/* screen_marketing_campanhas.jsx
   Marketing · Campanhas — Geração de conceito, copy e prompts visuais a partir de briefings aprovados.
   Fluxo: conceito_pendente → conceito_gerado → copy_pendente → copy_gerado
          → prompts_pendente → prompts_gerado → em_producao
   Expõe window.MktCampanhasScreen.
*/

// ── Cores de marca ─────────────────────────────────────────────────────────────
const _BC = {
  mimaki: '#e60012', biond: '#00a86b', decal: '#f59e0b',
  alldecor: '#ec4899', sensek: '#8B2DE8', netscreen: '#F97316', digidelta: '#3859D0',
};
const _brandColor = (slug) => _BC[slug] || '#3859D0';

// ── API ────────────────────────────────────────────────────────────────────────
const CampAPI = {
  list:             ()           => fetch('/api/marketing/campanhas').then(r => r.json()),
  get:              (id)         => fetch(`/api/marketing/campanhas/${id}`).then(r => r.json()),
  update:           (id, body)   => fetch(`/api/marketing/campanhas/${id}`, { method: 'PUT',    headers: { 'Content-Type': 'application/json' }, body: JSON.stringify(body) }).then(r => r.json()),
  remove:           (id)         => fetch(`/api/marketing/campanhas/${id}`, { method: 'DELETE' }).then(r => r.json()),
  generateConceito: (id)         => fetch(`/api/marketing/campanhas/${id}/generate-conceito`, { method: 'POST', headers: { 'Content-Type': 'application/json' } }).then(r => r.json()),
  aprovarConceito:  (id)         => fetch(`/api/marketing/campanhas/${id}/conceito`, { method: 'PATCH', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ action: 'aprovar' }) }).then(r => r.json()),
  generateCopy:     (id)         => fetch(`/api/marketing/campanhas/${id}/generate-copy`, { method: 'POST', headers: { 'Content-Type': 'application/json' } }).then(r => r.json()),
  patchCopy:        (copyId, b)  => fetch(`/api/marketing/copy/${copyId}`,    { method: 'PATCH', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify(b) }).then(r => r.json()),
  generatePrompts:  (id)         => fetch(`/api/marketing/campanhas/${id}/generate-prompts`, { method: 'POST', headers: { 'Content-Type': 'application/json' } }).then(r => r.json()),
  patchPrompt:      (pId, b)     => fetch(`/api/marketing/prompts/${pId}`,    { method: 'PATCH', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify(b) }).then(r => r.json()),
  enviarProducao:   (id)         => fetch(`/api/marketing/campanhas/${id}/enviar-producao`, { method: 'POST', headers: { 'Content-Type': 'application/json' } }).then(r => r.json()),
  getBriefing:           (bid)        => fetch(`/api/marketing/briefings/${bid}`).then(r => r.json()),
  getBrands:             ()           => fetch('/api/marketing/brands').then(r => r.json()),
  availableForCampaign:  ()           => fetch('/api/marketing/briefings/available-for-campaign').then(r => r.json()),
  create:                (body)       => fetch('/api/marketing/campanhas', { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify(body) }).then(r => r.json()),
};
window.MktCampanhasAPI = { list: CampAPI.list };

// ── Kanban ─────────────────────────────────────────────────────────────────────
const KANBAN_COLS = [
  { id: 'briefing',      label: 'Briefing',      color: '#3859D0',
    statuses: ['conceito_pendente'] },
  { id: 'conceito',      label: 'Conceito',      color: '#94a3b8',
    statuses: ['conceito_gerado', 'conceito'] },
  { id: 'copy',          label: 'Copy',          color: '#f59e0b',
    statuses: ['copy_pendente', 'copy_gerado', 'copy_aprovado'] },
  { id: 'para_producao', label: 'Para Produção', color: '#22c55e',
    statuses: ['prompts_pendente', 'prompts_gerado', 'geracao', 'aprovacao', 'em_producao', 'publicado'] },
];

const STATUS_COL = {};
KANBAN_COLS.forEach(col => col.statuses.forEach(s => { STATUS_COL[s] = col; }));

const CANAL_ICON = {
  instagram: '📸', linkedin: '💼', email: '✉️', whatsapp: '💬',
  ads: '📢', site: '🌐', tiktok: '🎵', led: '💡',
};
const CANAL_LABEL = {
  instagram: 'Instagram', linkedin: 'LinkedIn', email: 'Email', whatsapp: 'WhatsApp',
  ads: 'Ads', site: 'Site', tiktok: 'TikTok', led: 'LED/Muppi',
};

// ── Helpers ────────────────────────────────────────────────────────────────────
const CampDropdown = ({ label, value, options, onChange, disabled }) => {
  const [open, setOpen] = React.useState(false);
  const ref = React.useRef(null);
  React.useEffect(() => {
    if (!open) return;
    const onClick = (e) => { if (ref.current && !ref.current.contains(e.target)) setOpen(false); };
    document.addEventListener('mousedown', onClick);
    return () => document.removeEventListener('mousedown', onClick);
  }, [open]);
  const current = options.find(o => o.value === value) || options[0];
  return (
    <div ref={ref} style={{ position: 'relative' }}>
      <button onClick={() => !disabled && setOpen(v => !v)} disabled={disabled} style={{
        background: 'var(--bg-elev, #162032)', color: disabled ? 'var(--text-dim, #475569)' : 'var(--text, #f1f5f9)',
        border: '1px solid var(--border, #1e293b)', borderRadius: 6,
        padding: '6px 10px', fontSize: 11.5,
        display: 'inline-flex', alignItems: 'center', gap: 8,
        cursor: disabled ? 'not-allowed' : 'pointer', opacity: disabled ? 0.55 : 1,
        fontFamily: 'inherit', transition: 'border-color .15s',
      }}>
        <span style={{ color: 'var(--text-dim, #475569)', fontSize: 10, textTransform: 'uppercase', letterSpacing: '.06em', fontFamily: 'var(--font-mono, monospace)' }}>{label}</span>
        <span style={{ fontWeight: 500, color: disabled ? 'var(--text-dim, #475569)' : 'var(--text, #f1f5f9)' }}>{current?.label || '—'}</span>
        <span style={{ color: 'var(--text-muted, #64748b)', fontSize: 9 }}>▾</span>
      </button>
      {open && (
        <div className="animate-in" style={{
          position: 'absolute', top: 'calc(100% + 4px)', left: 0, zIndex: 50,
          background: 'var(--bg-elev, #162032)', border: '1px solid var(--border, #1e293b)', borderRadius: 6,
          boxShadow: '0 8px 24px rgba(0,0,0,0.12)', minWidth: 180, padding: 4, maxHeight: 280, overflowY: 'auto',
        }}>
          {options.map(o => (
            <button key={o.value} onClick={() => { onChange(o.value); setOpen(false); }} style={{
              display: 'block', width: '100%', textAlign: 'left',
              background: o.value === value ? 'color-mix(in oklch, var(--ai-500, #3859D0) 12%, transparent)' : 'transparent',
              color: o.value === value ? 'var(--ai-500, #3859D0)' : 'var(--text, #f1f5f9)',
              border: 'none', padding: '7px 10px', borderRadius: 4,
              fontSize: 12, fontWeight: o.value === value ? 600 : 500,
              cursor: 'pointer', fontFamily: 'inherit',
            }}>{o.label}</button>
          ))}
        </div>
      )}
    </div>
  );
};

const CampDateRangePicker = ({ value, onChange }) => {
  const ref = React.useRef(null);
  const [open, setOpen] = React.useState(false);
  const [draftStart, setDraftStart] = React.useState(value.start);
  const [draftEnd, setDraftEnd] = React.useState(value.end);
  const [draftPreset, setDraftPreset] = React.useState(value.preset);
  const [anchor, setAnchor] = React.useState(() => {
    const d = new Date(value.end); d.setDate(1); d.setMonth(d.getMonth() - 1); return d;
  });
  const [pickStart, setPickStart] = React.useState(true);
  React.useEffect(() => {
    if (!open) return;
    const onClick = (e) => { if (ref.current && !ref.current.contains(e.target)) setOpen(false); };
    document.addEventListener('mousedown', onClick);
    return () => document.removeEventListener('mousedown', onClick);
  }, [open]);
  const stripTime = (d) => new Date(d.getFullYear(), d.getMonth(), d.getDate());
  const addDays = (d, n) => { const x = new Date(d); x.setDate(x.getDate() + n); return x; };
  const fmt = (d) => d ? d.toLocaleDateString('pt-PT', { day: 'numeric', month: 'short', year: 'numeric' }).replace('.', '') : '—';
  const fmtShort = (d) => d ? d.toLocaleDateString('pt-PT', { day: 'numeric', month: 'short' }).replace('.', '') : '—';
  const presets = [
    { id: 'all', label: 'Todo o período' }, { id: 'custom', label: 'Personalizado' },
    { id: 'today', label: 'Hoje' }, { id: 'yesterday', label: 'Ontem' },
    { id: 'last_7d', label: 'Últimos 7 dias' }, { id: 'last_30d', label: 'Últimos 30 dias' },
    { id: 'this_month', label: 'Este mês' }, { id: 'last_month', label: 'Mês passado' },
    { id: 'last_90d', label: 'Últimos 90 dias' }, { id: 'this_year', label: 'Este ano' },
  ];
  const presetLabels = Object.fromEntries(presets.map(p => [p.id, p.label]));
  const applyPreset = (id) => {
    if (id === 'all') { setDraftPreset('all'); return; }
    const today = stripTime(new Date()); let s = today, e = today;
    switch (id) {
      case 'today': break; case 'yesterday': s = e = addDays(today, -1); break;
      case 'last_7d': s = addDays(today, -6); break; case 'last_30d': s = addDays(today, -29); break;
      case 'last_90d': s = addDays(today, -89); break;
      case 'this_month': s = new Date(today.getFullYear(), today.getMonth(), 1); break;
      case 'last_month': s = new Date(today.getFullYear(), today.getMonth() - 1, 1); e = new Date(today.getFullYear(), today.getMonth(), 0); break;
      case 'this_year': s = new Date(today.getFullYear(), 0, 1); break;
      case 'custom': return; default: return;
    }
    setDraftPreset(id); setDraftStart(s); setDraftEnd(e);
    setAnchor(new Date(e.getFullYear(), e.getMonth() - 1, 1)); setPickStart(true);
  };
  const handleDayClick = (d) => {
    if (pickStart || !draftStart || (draftStart && draftEnd && d < draftStart)) {
      setDraftStart(d); setDraftEnd(d); setPickStart(false); setDraftPreset('custom');
    } else {
      if (d < draftStart) setDraftStart(d);
      else { setDraftEnd(d); setPickStart(true); }
      setDraftPreset('custom');
    }
  };
  const apply = () => { onChange({ preset: draftPreset, start: draftStart, end: draftEnd }); setOpen(false); };
  const cancel = () => { setDraftStart(value.start); setDraftEnd(value.end); setDraftPreset(value.preset); setOpen(false); };
  const triggerLabel = presetLabels[value.preset] || 'Personalizado';
  const triggerRange = value.preset === 'all' ? '' : `${fmtShort(value.start)} – ${fmt(value.end)}`;
  const nextAnchor = new Date(anchor.getFullYear(), anchor.getMonth() + 1, 1);
  const Month = ({ date }) => {
    const y = date.getFullYear(), m = date.getMonth();
    const firstDay = new Date(y, m, 1).getDay(), daysInMonth = new Date(y, m + 1, 0).getDate();
    const monthLabel = date.toLocaleDateString('pt-PT', { month: 'long', year: 'numeric' }).toUpperCase();
    const cells = [];
    for (let i = 0; i < firstDay; i++) cells.push(null);
    for (let d = 1; d <= daysInMonth; d++) cells.push(new Date(y, m, d));
    const inRange = (d) => draftStart && draftEnd && d >= draftStart && d <= draftEnd;
    const isStart = (d) => draftStart && d.getTime() === stripTime(draftStart).getTime();
    const isEnd = (d) => draftEnd && d.getTime() === stripTime(draftEnd).getTime();
    return (
      <div style={{ marginBottom: 10 }}>
        <div style={{ fontSize: 10.5, fontFamily: 'var(--font-mono, monospace)', color: 'var(--text-dim, #475569)', letterSpacing: '.08em', padding: '4px 6px' }}>{monthLabel}</div>
        <div style={{ display: 'grid', gridTemplateColumns: 'repeat(7, 1fr)', gap: 1, fontSize: 11 }}>
          {cells.map((d, i) => {
            if (!d) return <div key={i} />;
            const r = inRange(d), s = isStart(d), e = isEnd(d), isEdge = s || e;
            return (
              <button key={i} onClick={() => handleDayClick(d)} style={{
                width: 30, height: 30, lineHeight: '30px', textAlign: 'center', padding: 0,
                border: 'none', cursor: 'pointer', fontFamily: 'inherit',
                background: isEdge ? 'var(--ai-500, #3859D0)' : (r ? 'color-mix(in oklch, var(--ai-500, #3859D0) 18%, transparent)' : 'transparent'),
                color: isEdge ? '#fff' : (r ? 'var(--ai-500, #3859D0)' : 'var(--text, #f1f5f9)'),
                borderRadius: isEdge ? '50%' : (r ? 0 : 4), fontWeight: isEdge ? 600 : 500, fontSize: 11.5,
              }}>{d.getDate()}</button>
            );
          })}
        </div>
      </div>
    );
  };
  return (
    <div ref={ref} style={{ position: 'relative' }}>
      <button onClick={() => setOpen(v => !v)} style={{
        background: 'var(--bg-elev, #162032)', color: 'var(--text, #f1f5f9)',
        border: '1px solid var(--border, #1e293b)', borderRadius: 6, padding: '6px 10px', fontSize: 11.5,
        display: 'inline-flex', alignItems: 'center', gap: 8, cursor: 'pointer', fontFamily: 'inherit',
      }}>
        <span style={{ color: 'var(--text-dim, #475569)', fontSize: 10, textTransform: 'uppercase', letterSpacing: '.06em', fontFamily: 'var(--font-mono, monospace)' }}>Período</span>
        <span style={{ fontWeight: 600, color: 'var(--ai-500, #3859D0)', background: 'color-mix(in oklch, var(--ai-500, #3859D0) 12%, transparent)', padding: '1px 6px', borderRadius: 3 }}>{triggerLabel}</span>
        {triggerRange && <span style={{ color: 'var(--text-muted, #64748b)', fontFamily: 'var(--font-mono, monospace)', fontSize: 11 }}>{triggerRange}</span>}
        <span style={{ color: 'var(--text-muted, #64748b)', fontSize: 9 }}>▾</span>
      </button>
      {open && (
        <div style={{
          position: 'absolute', top: 'calc(100% + 6px)', right: 0, zIndex: 60,
          background: 'var(--bg-elev, #162032)', border: '1px solid var(--border, #1e293b)', borderRadius: 8,
          boxShadow: '0 12px 32px rgba(0,0,0,0.18)', display: 'flex', minWidth: 560,
        }}>
          <div style={{ width: 190, borderRight: '1px solid var(--border, #1e293b)', padding: '6px 0', maxHeight: 460, overflowY: 'auto' }}>
            {presets.map(p => (
              <button key={p.id} onClick={() => applyPreset(p.id)} style={{
                display: 'block', width: '100%', textAlign: 'left',
                background: draftPreset === p.id ? 'color-mix(in oklch, var(--ai-500, #3859D0) 12%, transparent)' : 'transparent',
                color: draftPreset === p.id ? 'var(--ai-500, #3859D0)' : 'var(--text, #f1f5f9)',
                border: 'none', padding: '8px 14px', fontSize: 12.5, fontWeight: draftPreset === p.id ? 600 : 500,
                cursor: 'pointer', fontFamily: 'inherit',
              }}>{p.label}</button>
            ))}
          </div>
          <div style={{ flex: 1, padding: 14, display: 'flex', flexDirection: 'column' }}>
            <div style={{ display: 'flex', gap: 8, marginBottom: 10 }}>
              <div style={{ flex: 1 }}>
                <div style={{ fontSize: 9.5, color: 'var(--text-dim, #475569)', textTransform: 'uppercase', letterSpacing: '.08em', fontFamily: 'var(--font-mono, monospace)', marginBottom: 3 }}>Data início</div>
                <div style={{ border: `1px solid ${pickStart ? 'var(--ai-500, #3859D0)' : 'var(--border, #1e293b)'}`, borderRadius: 4, padding: '5px 8px', fontSize: 12, background: 'var(--bg, #0f172a)' }}>{fmt(draftStart)}</div>
              </div>
              <div style={{ alignSelf: 'flex-end', padding: '6px 0', color: 'var(--text-muted, #64748b)' }}>—</div>
              <div style={{ flex: 1 }}>
                <div style={{ fontSize: 9.5, color: 'var(--text-dim, #475569)', textTransform: 'uppercase', letterSpacing: '.08em', fontFamily: 'var(--font-mono, monospace)', marginBottom: 3 }}>Data fim</div>
                <div style={{ border: `1px solid ${!pickStart ? 'var(--ai-500, #3859D0)' : 'var(--border, #1e293b)'}`, borderRadius: 4, padding: '5px 8px', fontSize: 12, background: 'var(--bg, #0f172a)' }}>{fmt(draftEnd)}</div>
              </div>
            </div>
            <div style={{ display: 'flex', justifyContent: 'space-between', alignItems: 'center', marginBottom: 4 }}>
              <button onClick={() => setAnchor(new Date(anchor.getFullYear(), anchor.getMonth() - 1, 1))} style={{ background: 'none', border: '1px solid var(--border, #1e293b)', borderRadius: 4, width: 24, height: 24, color: 'var(--text-muted, #64748b)', cursor: 'pointer' }}>‹</button>
              <div style={{ display: 'grid', gridTemplateColumns: 'repeat(7, 1fr)', gap: 1, flex: 1, padding: '0 8px' }}>
                {['D','S','T','Q','Q','S','S'].map((d, i) => (
                  <div key={i} style={{ textAlign: 'center', fontSize: 10, color: 'var(--text-dim, #475569)', fontFamily: 'var(--font-mono, monospace)', textTransform: 'uppercase' }}>{d}</div>
                ))}
              </div>
              <button onClick={() => setAnchor(new Date(anchor.getFullYear(), anchor.getMonth() + 1, 1))} style={{ background: 'none', border: '1px solid var(--border, #1e293b)', borderRadius: 4, width: 24, height: 24, color: 'var(--text-muted, #64748b)', cursor: 'pointer' }}>›</button>
            </div>
            <div style={{ flex: 1, overflowY: 'auto', maxHeight: 360, padding: '0 30px' }}>
              <Month date={anchor} />
              <Month date={nextAnchor} />
            </div>
            <div style={{ display: 'flex', justifyContent: 'flex-end', gap: 8, marginTop: 10, paddingTop: 10, borderTop: '1px solid var(--border, #1e293b)' }}>
              <button onClick={cancel} className="btn btn-xs">Cancelar</button>
              <button onClick={apply} className="btn btn-xs btn-ai">Aplicar</button>
            </div>
          </div>
        </div>
      )}
    </div>
  );
};

const StatusBadge = ({ status }) => {
  const MAP = {
    conceito_pendente:  ['Briefing',    '#3859D0', 'rgba(56,89,208,.12)'],
    conceito_gerado:    ['Gerado',      '#94a3b8', 'rgba(148,163,184,.18)'],
    conceito:           ['Gerado',      '#94a3b8', 'rgba(148,163,184,.18)'],
    copy_pendente:      ['Pendente',    '#f59e0b', 'rgba(245,158,11,.12)'],
    copy_gerado:        ['Gerado',      '#f59e0b', 'rgba(245,158,11,.2)'],
    copy_aprovado:      ['Aprovado',    '#f59e0b', 'rgba(245,158,11,.25)'],
    prompts_pendente:   ['Pendente',    '#22c55e', 'rgba(34,197,94,.12)'],
    prompts_gerado:     ['Gerado',      '#22c55e', 'rgba(34,197,94,.18)'],
    geracao:            ['Gerado',      '#22c55e', 'rgba(34,197,94,.18)'],
    aprovacao:          ['Aprovado',    '#22c55e', 'rgba(34,197,94,.22)'],
    em_producao:        ['Produção',    '#22c55e', 'rgba(34,197,94,.18)'],
    publicado:          ['Publicado',   '#22c55e', 'rgba(34,197,94,.28)'],
  };
  const [label, color, bg] = MAP[status] || [status, '#94a3b8', 'rgba(148,163,184,.12)'];
  return (
    <span style={{
      fontSize: 10, fontWeight: 600, padding: '2px 8px', borderRadius: 99,
      color, background: bg, fontFamily: 'var(--font-mono, monospace)',
    }}>{label}</span>
  );
};

// ── Banner contextual ──────────────────────────────────────────────────────────
const CampBanner = ({ kpi, onFilter }) => {
  const hour    = new Date().getHours();
  const [seed]  = React.useState(Math.random);
  const rawName = window.currentUser?.nome_apresentar || window.currentUser?.nome || '';
  const first   = rawName.split(' ')[0] || '';
  const { heading, segments } = React.useMemo(() => {
    const saudacao = hour < 12 ? 'Bom dia' : hour < 19 ? 'Boa tarde' : 'Boa noite';
    const heading  = first ? `${saudacao}, ${first}.` : `${saudacao}.`;
    const pl = (n, s, p) => n === 1 ? s : p;
    let pool;
    if (kpi.para_producao > 0) {
      const n = kpi.para_producao;
      pool = [[
        { text: `${n} ${pl(n,'campanha','campanhas')} em produção`, filter: 'para_producao', color: 'success' },
        { text: '. A equipa de produção já pode começar a trabalhar.' },
      ]];
    } else if (kpi.copy > 0) {
      const n = kpi.copy;
      pool = [[
        { text: `${n} ${pl(n,'campanha','campanhas')} na fase de copy`, filter: 'copy', color: 'warning' },
        { text: `. Aprova o copy para a Digi AI avançar.` },
      ]];
    } else if (kpi.conceito > 0) {
      const n = kpi.conceito;
      pool = [[
        { text: `${n} ${pl(n,'campanha aguarda','campanhas aguardam')} aprovação de conceito`, filter: 'conceito', color: 'warning' },
        { text: `. Revê e aprova para avançar para copy.` },
      ]];
    } else if (kpi.briefing > 0) {
      const n = kpi.briefing;
      pool = [[
        { text: `${n} ${pl(n,'campanha','campanhas')} com briefing aprovado`, filter: 'briefing', color: 'ai' },
        { text: `. Abre o card e gera o conceito com a Digi AI.` },
      ]];
    } else if (kpi.total === 0) {
      pool = [[{ text: `Ainda não há campanhas. Aprova um briefing e cria a primeira campanha para a Digi AI começar a gerar conteúdo.` }]];
    } else {
      pool = [[{ text: `${kpi.total} ${pl(kpi.total,'campanha activa','campanhas activas')} no pipeline. Tudo a correr bem.` }]];
    }
    return { heading, segments: pool[Math.floor(seed * pool.length)] };
  }, [kpi, hour, first, seed]);

  const segColor = c => ({ danger: 'var(--danger)', ai: 'var(--ai-500, #3859D0)', success: 'var(--success)', warning: 'var(--warning)' }[c] || 'var(--warning)');
  return (
    <div style={{ flexShrink: 0, padding: '10px 0 18px' }}>
      <div style={{ fontSize: 22, fontWeight: 700, color: 'var(--text, #f1f5f9)', fontFamily: 'var(--font-display, Montserrat, sans-serif)', marginBottom: 6, letterSpacing: '-0.02em' }}>
        {heading}
      </div>
      <div style={{ fontSize: 13, color: 'var(--text-muted, #64748b)', lineHeight: 1.65 }}>
        {segments.map((seg, i) => seg.color ? (
          <span key={i} onClick={seg.filter ? () => onFilter(seg.filter) : undefined}
            style={{ color: segColor(seg.color), cursor: seg.filter ? 'pointer' : 'default', fontWeight: 500 }}>
            {seg.text}
          </span>
        ) : <span key={i}>{seg.text}</span>)}
      </div>
    </div>
  );
};

// ── CampanhaCard ───────────────────────────────────────────────────────────────
const CampanhaCard = ({ c, onClick, onEdit, onDelete, cardIndex, onDragStart: onDragStartProp }) => {
  const [hover,      setHover]      = React.useState(false);
  const [menuOpen,   setMenuOpen]   = React.useState(false);
  const [confirming, setConfirming] = React.useState(false);
  const menuRef    = React.useRef(null);
  const isDragging = React.useRef(false);
  const bCol       = _brandColor(c.brand_slug);
  const produto  = c.product_name && c.product_name !== c.titulo ? c.product_name : null;
  const channels = Array.isArray(c.channels) ? c.channels : [];
  const CHAN_ABBR = { instagram: 'IG', linkedin: 'LIN', email: 'EML', whatsapp: 'WA', ads: 'ADS', site: 'WEB', tiktok: 'TIK', led: 'LED', facebook: 'FB', youtube: 'YT', google_ads: 'GGL', social: 'SOC' };
  const autor    = c.created_by_name || null;

  const relTime = (dt) => {
    if (!dt) return null;
    const diff = Math.floor((Date.now() - new Date(dt)) / 1000);
    if (diff < 60)     return 'agora';
    if (diff < 3600)   return `há ${Math.floor(diff / 60)}min`;
    if (diff < 86400)  return `há ${Math.floor(diff / 3600)}h`;
    if (diff < 604800) return `há ${Math.floor(diff / 86400)} ${Math.floor(diff / 86400) === 1 ? 'dia' : 'dias'}`;
    return new Date(dt).toLocaleDateString('pt-PT', { day: '2-digit', month: 'short' });
  };
  const tempo = relTime(c.updated_at);

  React.useEffect(() => {
    if (!menuOpen) return;
    const h = (e) => { if (menuRef.current && !menuRef.current.contains(e.target)) { setMenuOpen(false); setConfirming(false); } };
    document.addEventListener('mousedown', h);
    return () => document.removeEventListener('mousedown', h);
  }, [menuOpen]);

  return (
    <div
      draggable
      onMouseEnter={() => setHover(true)}
      onMouseLeave={() => setHover(false)}
      onDragStart={(e) => {
        isDragging.current = true;
        e.dataTransfer.setData('text/plain', c.id);
        e.dataTransfer.effectAllowed = 'move';
        onDragStartProp && onDragStartProp(c);
      }}
      onDragEnd={() => { setTimeout(() => { isDragging.current = false; }, 50); }}
      style={{
        background: hover ? 'var(--bg-hover, #1e293b)' : 'var(--bg-elev, #162032)',
        border: `1px solid ${hover ? 'var(--border-active, #334155)' : 'var(--border, #1e293b)'}`,
        borderLeft: `3px solid ${bCol}`, borderRadius: 8, padding: '12px 14px',
        transition: 'background 150ms ease, border-color 150ms ease', cursor: 'grab', position: 'relative',
        animation: 'slide-up 0.2s ease-out both',
        animationDelay: `${Math.min(cardIndex || 0, 9) * 25}ms`,
      }}
    >
      {/* Header row */}
      <div style={{ display: 'flex', justifyContent: 'space-between', alignItems: 'center', marginBottom: 6 }}>
        <span style={{ fontSize: 9, fontWeight: 700, textTransform: 'uppercase', letterSpacing: '0.1em', color: bCol, fontFamily: 'var(--font-mono, monospace)' }}>
          {c.brand_name}
        </span>
        <div style={{ display: 'flex', alignItems: 'center', gap: 6 }} onClick={e => e.stopPropagation()}>
          <StatusBadge status={c.status} />
          {/* Kebab menu */}
          <div ref={menuRef} style={{ position: 'relative' }}>
            <button
              onClick={() => { setMenuOpen(o => !o); setConfirming(false); }}
              style={{
                display: 'flex', alignItems: 'center', justifyContent: 'center',
                width: 22, height: 22, borderRadius: 4, cursor: 'pointer',
                background: menuOpen ? 'var(--bg-sunken, #0f172a)' : 'transparent',
                border: `1px solid ${menuOpen ? 'var(--border, #334155)' : 'transparent'}`,
                color: 'var(--text-muted, #64748b)', fontSize: 14, lineHeight: 1,
                transition: 'all 150ms ease',
              }}
              onMouseEnter={e => { if (!menuOpen) { e.currentTarget.style.background = 'var(--bg-sunken, #0f172a)'; e.currentTarget.style.borderColor = 'var(--border, #334155)'; } }}
              onMouseLeave={e => { if (!menuOpen) { e.currentTarget.style.background = 'transparent'; e.currentTarget.style.borderColor = 'transparent'; } }}
            >⋮</button>
            {menuOpen && (
              <div className="animate-in" style={{
                position: 'absolute', top: 'calc(100% + 4px)', right: 0, zIndex: 80,
                background: 'var(--bg-elev, #1e293b)', border: '1px solid var(--border, #334155)',
                borderRadius: 7, minWidth: 140, overflow: 'hidden',
                boxShadow: '0 6px 20px rgba(0,0,0,.4)',
              }}>
                <div onClick={() => { setMenuOpen(false); onEdit(c); }}
                  style={{ padding: '9px 14px', fontSize: 12.5, cursor: 'pointer', color: 'var(--text, #f1f5f9)', display: 'flex', alignItems: 'center', gap: 8 }}
                  onMouseEnter={e => e.currentTarget.style.background = 'var(--bg-hover, #334155)'}
                  onMouseLeave={e => e.currentTarget.style.background = 'transparent'}
                >
                  <span style={{ fontSize: 13 }}>✏️</span> Editar título
                </div>
                {!confirming ? (
                  <div onClick={() => setConfirming(true)}
                    style={{ padding: '9px 14px', fontSize: 12.5, cursor: 'pointer', color: '#f87171', display: 'flex', alignItems: 'center', gap: 8, borderTop: '1px solid var(--border, #334155)' }}
                    onMouseEnter={e => e.currentTarget.style.background = 'rgba(248,113,113,.08)'}
                    onMouseLeave={e => e.currentTarget.style.background = 'transparent'}
                  >
                    <span style={{ fontSize: 13 }}>🗑️</span> Apagar
                  </div>
                ) : (
                  <div style={{ padding: '9px 14px', borderTop: '1px solid var(--border, #334155)' }}>
                    <div style={{ fontSize: 11, color: 'var(--text-muted, #94a3b8)', marginBottom: 7 }}>Tens a certeza?</div>
                    <div style={{ display: 'flex', gap: 6 }}>
                      <button onClick={() => { setMenuOpen(false); setConfirming(false); onDelete(c.id); }}
                        style={{ flex: 1, padding: '4px 0', fontSize: 11, fontWeight: 600, borderRadius: 4, cursor: 'pointer', background: 'rgba(248,113,113,.15)', border: '1px solid rgba(248,113,113,.3)', color: '#f87171' }}>
                        Apagar
                      </button>
                      <button onClick={() => setConfirming(false)}
                        style={{ flex: 1, padding: '4px 0', fontSize: 11, borderRadius: 4, cursor: 'pointer', background: 'transparent', border: '1px solid var(--border, #334155)', color: 'var(--text-muted, #94a3b8)' }}>
                        Cancelar
                      </button>
                    </div>
                  </div>
                )}
              </div>
            )}
          </div>
        </div>
      </div>

      {/* Content — click area */}
      <div onClick={() => { if (!isDragging.current) onClick(); }}>
        {/* Título */}
        <div style={{ fontSize: 12.5, fontWeight: 600, color: 'var(--text, #f1f5f9)', fontFamily: 'var(--font-display, Montserrat, sans-serif)', lineHeight: 1.35, marginBottom: 3 }}>
          {c.titulo}
        </div>

        {/* Produto */}
        {produto && (
          <div style={{ fontSize: 11, color: 'var(--text-muted, #64748b)', marginBottom: 6, whiteSpace: 'nowrap', overflow: 'hidden', textOverflow: 'ellipsis' }}>
            {produto}
          </div>
        )}

        {/* Canais */}
        {channels.length > 0 && (
          <div style={{ fontSize: 10, color: 'var(--text-dim, #475569)', fontFamily: 'var(--font-mono, monospace)', letterSpacing: '0.04em', marginBottom: 10 }}>
            {channels.map(ch => CHAN_ABBR[ch] || ch.toUpperCase()).join(' · ')}
          </div>
        )}

        {/* Rodapé: autor · tempo + pills copy/prompts */}
        <div style={{ display: 'flex', alignItems: 'center', justifyContent: 'space-between', marginTop: channels.length > 0 ? 0 : 8, gap: 6 }}>
          <span style={{ fontSize: 10, color: 'var(--text-dim, #475569)', fontFamily: 'var(--font-mono, monospace)', overflow: 'hidden', textOverflow: 'ellipsis', whiteSpace: 'nowrap' }}>
            {autor ? `${autor} · ` : ''}{tempo}
          </span>
          <div style={{ display: 'flex', gap: 4, flexShrink: 0 }}>
            {c.num_copy > 0 && (
              <span style={{
                fontSize: 9, fontFamily: 'var(--font-mono, monospace)', letterSpacing: '0.04em',
                padding: '2px 6px', borderRadius: 10,
                background: c.num_copy_aprovado >= c.num_copy ? 'rgba(34,197,94,.12)' : 'rgba(245,158,11,.10)',
                color: c.num_copy_aprovado >= c.num_copy ? 'var(--success, #22c55e)' : 'var(--warning, #f59e0b)',
              }}>
                {c.num_copy_aprovado}/{c.num_copy} copy
              </span>
            )}
            {c.num_prompts > 0 && (
              <span style={{
                fontSize: 9, fontFamily: 'var(--font-mono, monospace)', letterSpacing: '0.04em',
                padding: '2px 6px', borderRadius: 10,
                background: c.num_prompts_aprovado >= c.num_prompts ? 'rgba(34,197,94,.12)' : 'rgba(56,89,208,.12)',
                color: c.num_prompts_aprovado >= c.num_prompts ? 'var(--success, #22c55e)' : 'var(--ai-500, #3859D0)',
              }}>
                {c.num_prompts_aprovado}/{c.num_prompts} visual
              </span>
            )}
          </div>
        </div>
      </div>
    </div>
  );
};

// ── KanbanColumn ───────────────────────────────────────────────────────────────
const KanbanColumn = ({ col, cards, onCardClick, onEdit, onDelete, onDragStart, onDrop, dragCard }) => {
  const [isDragOver, setIsDragOver] = React.useState(false);
  const colIdx  = KANBAN_COLS.findIndex(c => c.id === col.id);
  const srcIdx  = dragCard ? KANBAN_COLS.findIndex(c => c.statuses.includes(dragCard.status)) : -1;
  const canDrop = dragCard && srcIdx !== -1 && colIdx > srcIdx;

  return (
    <div
      style={{
        flex: '1 1 0', display: 'flex', flexDirection: 'column', gap: 8,
        borderRadius: 10, padding: 4,
        border: isDragOver && canDrop ? '1px dashed var(--ai-500, #3859D0)' : '1px solid transparent',
        background: isDragOver && canDrop ? 'rgba(56,89,208,.06)' : 'transparent',
        transition: 'background 150ms ease, border-color 150ms ease',
      }}
      onDragOver={(e) => { e.preventDefault(); e.dataTransfer.dropEffect = canDrop ? 'move' : 'none'; if (canDrop) setIsDragOver(true); }}
      onDragEnter={(e) => { e.preventDefault(); if (canDrop) setIsDragOver(true); }}
      onDragLeave={(e) => { if (!e.currentTarget.contains(e.relatedTarget)) setIsDragOver(false); }}
      onDrop={(e) => { e.preventDefault(); setIsDragOver(false); if (dragCard && canDrop) onDrop(dragCard, col.id); }}
    >
      {cards.map((c, i) => (
        <CampanhaCard key={c.id} c={c} onClick={() => onCardClick(c)} onEdit={onEdit} onDelete={onDelete} cardIndex={i} onDragStart={onDragStart} />
      ))}
      {isDragOver && canDrop && cards.length === 0 && (
        <div style={{ height: 56, borderRadius: 8, border: '1px dashed rgba(56,89,208,.4)', display: 'flex', alignItems: 'center', justifyContent: 'center' }}>
          <span style={{ fontSize: 11, color: 'var(--ai-500, #3859D0)', fontFamily: 'var(--font-mono, monospace)' }}>soltar aqui</span>
        </div>
      )}
    </div>
  );
};

// ── Tabs do drawer antigo (não usadas — mantidas para referência) ──────────────
const TabConceito = ({ campanha, onAction, generating }) => {
  const hasConceito = !!(campanha.big_idea);
  const isApproved  = ['copy_pendente','copy_gerado','copy_aprovado','prompts_pendente','prompts_gerado','em_producao'].includes(campanha.status);

  return (
    <div style={{ display: 'flex', flexDirection: 'column', gap: 16 }}>
      {!hasConceito ? (
        <div style={{ textAlign: 'center', padding: '32px 0' }}>
          <div style={{ fontSize: 13, color: 'var(--text-muted, #64748b)', marginBottom: 20 }}>
            Nenhum conceito gerado ainda. A Digi AI vai analisar os 5 blocos do briefing e criar o conceito estratégico da campanha.
          </div>
          <button onClick={() => onAction('generateConceito')} disabled={generating.conceito}
            className="btn btn-primary" style={{ gap: 6 }}>
            {generating.conceito ? '⟳ A gerar…' : '✦ Gerar Conceito com Digi AI'}
          </button>
        </div>
      ) : (
        <>
          {[
            { key: 'big_idea',       label: 'Big Idea',       icon: '💡' },
            { key: 'posicionamento', label: 'Posicionamento', icon: '🎯' },
            { key: 'narrativa',      label: 'Narrativa',      icon: '📖' },
            { key: 'tom_campanha',   label: 'Tom da Campanha',icon: '🗣️' },
          ].map(f => campanha[f.key] ? (
            <div key={f.key} style={{ background: 'var(--bg-sunken, #0f172a)', borderRadius: 8, padding: '14px 16px' }}>
              <div style={{ fontSize: 10, fontWeight: 700, textTransform: 'uppercase', letterSpacing: '0.08em', color: 'var(--text-dim, #475569)', fontFamily: 'var(--font-mono, monospace)', marginBottom: 8 }}>
                {f.icon} {f.label}
              </div>
              <div style={{ fontSize: 13, color: 'var(--text, #f1f5f9)', lineHeight: 1.6 }}>{campanha[f.key]}</div>
            </div>
          ) : null)}
          {!isApproved && (
            <div style={{ display: 'flex', gap: 8, flexWrap: 'wrap' }}>
              <button onClick={() => onAction('aprovarConceito')} disabled={generating.approve}
                className="btn btn-primary" style={{ gap: 6 }}>
                ✓ Aprovar Conceito
              </button>
              <button onClick={() => onAction('generateConceito')} disabled={generating.conceito}
                className="btn" style={{ color: 'var(--text-muted, #64748b)' }}>
                {generating.conceito ? '⟳ A gerar…' : '↻ Regenerar'}
              </button>
            </div>
          )}
          {isApproved && (
            <div style={{ fontSize: 11, color: 'var(--success, #22c55e)', fontWeight: 500 }}>✓ Conceito aprovado — a avançar para copy</div>
          )}
        </>
      )}
    </div>
  );
};

// ── Drawer: tab Copy ───────────────────────────────────────────────────────────
const TabCopy = ({ campanha, copy, onAction, generating }) => {
  const channels  = Array.isArray(campanha.briefing?.channels) ? campanha.briefing.channels : [];
  const hasCopy   = copy.length > 0;
  const canGenerate = ['copy_pendente', 'copy_gerado', 'copy_aprovado', 'prompts_pendente'].includes(campanha.status)
    || ['conceito_gerado'].includes(campanha.status)
    || campanha.big_idea;

  return (
    <div style={{ display: 'flex', flexDirection: 'column', gap: 16 }}>
      {!canGenerate && (
        <div style={{ padding: '12px 16px', background: 'rgba(245,158,11,.08)', borderRadius: 8, fontSize: 12, color: '#f59e0b', border: '1px solid rgba(245,158,11,.2)' }}>
          Aprova o Conceito antes de gerar copy.
        </div>
      )}
      {channels.length === 0 && (
        <div style={{ padding: '12px 16px', background: 'rgba(148,163,184,.06)', borderRadius: 8, fontSize: 12, color: 'var(--text-muted, #64748b)' }}>
          Canais não definidos no Bloco 4 do briefing.
        </div>
      )}
      {!hasCopy && channels.length > 0 && canGenerate && (
        <div style={{ textAlign: 'center', padding: '24px 0' }}>
          <div style={{ fontSize: 13, color: 'var(--text-muted, #64748b)', marginBottom: 16 }}>
            A Digi AI vai gerar copy específico para cada canal: {channels.map(c => CANAL_LABEL[c] || c).join(', ')}.
          </div>
          <button onClick={() => onAction('generateCopy')} disabled={generating.copy}
            className="btn btn-primary">
            {generating.copy ? '⟳ A gerar…' : '✦ Gerar Copy para todos os canais'}
          </button>
        </div>
      )}
      {hasCopy && (
        <>
          {copy.map(cp => (
            <CopyCard key={cp.id} cp={cp} onApprove={() => onAction('approveCopy', cp.id, 'aprovado')} onFlag={() => onAction('approveCopy', cp.id, 'correcao')} />
          ))}
          <button onClick={() => onAction('generateCopy')} disabled={generating.copy}
            className="btn" style={{ alignSelf: 'flex-start', color: 'var(--text-muted, #64748b)', fontSize: 12 }}>
            {generating.copy ? '⟳ A gerar…' : '↻ Regenerar todo o copy'}
          </button>
        </>
      )}
    </div>
  );
};

const CopyCard = ({ cp, onApprove, onFlag }) => {
  const [exp, setExp] = React.useState(false);
  const canalLabel = CANAL_LABEL[cp.canal] || cp.canal || '—';
  const canalIcon  = CANAL_ICON[cp.canal] || '📄';
  const isApproved = cp.status === 'aprovado';
  const isFlagged  = cp.status === 'correcao';

  return (
    <div style={{
      background: 'var(--bg-sunken, #0f172a)', borderRadius: 8,
      border: `1px solid ${isApproved ? 'rgba(34,197,94,.25)' : isFlagged ? 'rgba(251,146,60,.25)' : 'var(--border, #1e293b)'}`,
    }}>
      <div onClick={() => setExp(e => !e)} style={{ display: 'flex', alignItems: 'center', gap: 10, padding: '12px 16px', cursor: 'pointer', userSelect: 'none' }}>
        <span style={{ fontSize: 16 }}>{canalIcon}</span>
        <span style={{ fontSize: 13, fontWeight: 600, color: 'var(--text, #f1f5f9)', flex: 1, fontFamily: 'var(--font-display, Montserrat, sans-serif)' }}>{canalLabel}</span>
        {cp.formato && <span style={{ fontSize: 10, color: 'var(--text-dim, #475569)', fontFamily: 'var(--font-mono, monospace)' }}>{cp.formato}</span>}
        <StatusBadge status={cp.status} />
        <span style={{ fontSize: 10, color: 'var(--text-dim, #475569)', marginLeft: 4 }}>{exp ? '▴' : '▾'}</span>
      </div>
      {exp && (
        <div style={{ padding: '0 16px 14px', display: 'flex', flexDirection: 'column', gap: 10, borderTop: '1px solid var(--border, #1e293b)' }}>
          {cp.headline && <CopyField label="Headline" value={cp.headline} />}
          {cp.body     && <CopyField label="Body"     value={cp.body} multiline />}
          {cp.cta      && <CopyField label="CTA"      value={cp.cta} />}
          {cp.hashtags && <CopyField label="Hashtags" value={cp.hashtags} mono />}
          {!isApproved && (
            <div style={{ display: 'flex', gap: 8, marginTop: 4 }}>
              <button onClick={onApprove} className="btn btn-sm btn-primary" style={{ fontSize: 11 }}>✓ Aprovar</button>
              <button onClick={onFlag}    className="btn btn-sm" style={{ fontSize: 11, color: '#fb923c', borderColor: 'rgba(251,146,60,.3)' }}>⚑ Corrigir</button>
            </div>
          )}
          {isApproved && <div style={{ fontSize: 11, color: 'var(--success, #22c55e)', fontWeight: 500 }}>✓ Copy aprovado</div>}
        </div>
      )}
    </div>
  );
};

const CopyField = ({ label, value, multiline, mono }) => (
  <div>
    <div style={{ fontSize: 10, fontWeight: 700, textTransform: 'uppercase', letterSpacing: '0.08em', color: 'var(--text-dim, #475569)', fontFamily: 'var(--font-mono, monospace)', marginBottom: 4 }}>{label}</div>
    <div style={{ fontSize: 12.5, color: 'var(--text, #f1f5f9)', lineHeight: multiline ? 1.6 : 1.3, fontFamily: mono ? 'var(--font-mono, monospace)' : 'inherit', whiteSpace: multiline ? 'pre-wrap' : 'normal', wordBreak: 'break-word' }}>{value}</div>
  </div>
);

// ── Drawer: tab Prompts ────────────────────────────────────────────────────────
const TabPrompts = ({ campanha, prompts, onAction, generating }) => {
  const canGenerate = campanha.big_idea && (campanha.status !== 'conceito_pendente' && campanha.status !== 'conceito_gerado');
  const hasPrompts  = prompts.length > 0;

  return (
    <div style={{ display: 'flex', flexDirection: 'column', gap: 16 }}>
      {!canGenerate && (
        <div style={{ padding: '12px 16px', background: 'rgba(168,85,247,.06)', borderRadius: 8, fontSize: 12, color: '#a855f7', border: '1px solid rgba(168,85,247,.2)' }}>
          Aprova o Conceito e o Copy antes de gerar prompts visuais.
        </div>
      )}
      {!hasPrompts && canGenerate && (
        <div style={{ textAlign: 'center', padding: '24px 0' }}>
          <div style={{ fontSize: 13, color: 'var(--text-muted, #64748b)', marginBottom: 16 }}>
            A Digi AI vai criar prompts de imagem e vídeo para todos os canais visuais da campanha (Instagram, Ads, LinkedIn, Site…).
          </div>
          <button onClick={() => onAction('generatePrompts')} disabled={generating.prompts}
            className="btn btn-primary">
            {generating.prompts ? '⟳ A gerar…' : '✦ Gerar Prompts Visuais'}
          </button>
        </div>
      )}
      {hasPrompts && (
        <>
          {prompts.map(pr => (
            <PromptCard key={pr.id} pr={pr} onApprove={() => onAction('approvePrompt', pr.id, 'aprovado')} onFlag={() => onAction('approvePrompt', pr.id, 'correcao')} />
          ))}
          <button onClick={() => onAction('generatePrompts')} disabled={generating.prompts}
            className="btn" style={{ alignSelf: 'flex-start', color: 'var(--text-muted, #64748b)', fontSize: 12 }}>
            {generating.prompts ? '⟳ A gerar…' : '↻ Regenerar prompts'}
          </button>
        </>
      )}
    </div>
  );
};

const PromptCard = ({ pr, onApprove, onFlag }) => {
  const [exp, setExp] = React.useState(false);
  const canalLabel = CANAL_LABEL[pr.canal] || pr.canal || '—';
  const canalIcon  = CANAL_ICON[pr.canal] || '🖼️';
  const tipoLabel  = pr.tipo === 'imagem' ? '📷 Imagem' : '🎬 Vídeo';
  const isApproved = pr.status === 'aprovado';
  const isFlagged  = pr.status === 'correcao';

  return (
    <div style={{
      background: 'var(--bg-sunken, #0f172a)', borderRadius: 8,
      border: `1px solid ${isApproved ? 'rgba(34,197,94,.25)' : isFlagged ? 'rgba(251,146,60,.25)' : 'var(--border, #1e293b)'}`,
    }}>
      <div onClick={() => setExp(e => !e)} style={{ display: 'flex', alignItems: 'center', gap: 10, padding: '12px 16px', cursor: 'pointer', userSelect: 'none' }}>
        <span style={{ fontSize: 16 }}>{canalIcon}</span>
        <span style={{ fontSize: 13, fontWeight: 600, color: 'var(--text, #f1f5f9)', flex: 1, fontFamily: 'var(--font-display, Montserrat, sans-serif)' }}>{canalLabel}</span>
        <span style={{ fontSize: 10, color: 'var(--text-dim, #475569)', fontFamily: 'var(--font-mono, monospace)' }}>{tipoLabel}</span>
        {pr.ratio && <span style={{ fontSize: 10, color: 'var(--text-dim, #475569)', fontFamily: 'var(--font-mono, monospace)' }}>{pr.ratio}</span>}
        <StatusBadge status={pr.status} />
        <span style={{ fontSize: 10, color: 'var(--text-dim, #475569)', marginLeft: 4 }}>{exp ? '▴' : '▾'}</span>
      </div>
      {exp && (
        <div style={{ padding: '0 16px 14px', display: 'flex', flexDirection: 'column', gap: 10, borderTop: '1px solid var(--border, #1e293b)' }}>
          {pr.prompt_texto && <CopyField label="Prompt" value={pr.prompt_texto} multiline />}
          {pr.estilo       && <CopyField label="Estilo"  value={pr.estilo} />}
          {pr.referencia   && <CopyField label="Referência" value={pr.referencia} />}
          {!isApproved && (
            <div style={{ display: 'flex', gap: 8, marginTop: 4 }}>
              <button onClick={onApprove} className="btn btn-sm btn-primary" style={{ fontSize: 11 }}>✓ Aprovar</button>
              <button onClick={onFlag}    className="btn btn-sm" style={{ fontSize: 11, color: '#fb923c', borderColor: 'rgba(251,146,60,.3)' }}>⚑ Corrigir</button>
            </div>
          )}
          {isApproved && <div style={{ fontSize: 11, color: 'var(--success, #22c55e)', fontWeight: 500 }}>✓ Prompt aprovado</div>}
        </div>
      )}
    </div>
  );
};

// ── CampanhaDetail (vista full-width) ─────────────────────────────────────────
const CampanhaDetail = ({ campanhaSummary, onBack, onRefresh, initialTab }) => {
  const [tab,        setTab]        = React.useState(initialTab || 'conceito');
  const [detail,     setDetail]     = React.useState(null);
  const [loading,    setLoading]    = React.useState(true);
  const [generating, setGenerating] = React.useState({});
  const [error,      setError]      = React.useState('');

  const loadDetail = React.useCallback(async () => {
    setLoading(true);
    try {
      const d = await CampAPI.get(campanhaSummary.id);
      setDetail(d);
    } catch {
      setError('Erro ao carregar campanha.');
    } finally {
      setLoading(false);
    }
  }, [campanhaSummary.id]);

  React.useEffect(() => { loadDetail(); }, [loadDetail]);

  const setGen = (key, val) => setGenerating(g => ({ ...g, [key]: val }));

  const handleAction = async (action, arg1, arg2) => {
    setError('');
    try {
      if      (action === 'generateConceito') { setGen('conceito', true);  await CampAPI.generateConceito(detail.id); }
      else if (action === 'aprovarConceito')  { setGen('approve',  true);  await CampAPI.aprovarConceito(detail.id); }
      else if (action === 'generateCopy')     { setGen('copy',     true);  await CampAPI.generateCopy(detail.id); }
      else if (action === 'approveCopy')      { await CampAPI.patchCopy(arg1, { status: arg2 }); }
      else if (action === 'generatePrompts')  { setGen('prompts',  true);  await CampAPI.generatePrompts(detail.id); }
      else if (action === 'approvePrompt')    { await CampAPI.patchPrompt(arg1, { status: arg2 }); }
      else if (action === 'enviarProducao')   { setGen('producao', true);  await CampAPI.enviarProducao(detail.id); }
      await loadDetail(); onRefresh();
    } catch (e) {
      setError(e.message || 'Erro inesperado');
    } finally {
      setGenerating({});
    }
  };

  const bCol = _brandColor(campanhaSummary.brand_slug);
  const canEnviar = detail && detail.big_idea
    && (detail.copy || []).length > 0
    && (detail.copy || []).every(c => c.status === 'aprovado')
    && detail.status !== 'em_producao';

  const TABS = [
    { id: 'conceito', label: 'Conceito' },
    { id: 'copy',     label: `Copy${detail?.copy?.length ? ` · ${detail.copy.length}` : ''}` },
    { id: 'prompts',  label: `Prompts${detail?.prompts?.length ? ` · ${detail.prompts.length}` : ''}` },
  ];

  return (
    <div className="scrollbar" style={{ height: '100%', overflowY: 'auto' }}>

      {/* ── Header ── */}
      <div style={{ padding: '22px 32px 0' }}>

        {/* Breadcrumb */}
        <div style={{ display: 'flex', alignItems: 'center', gap: 6, marginBottom: 16 }}>
          <button onClick={onBack} style={{
            display: 'flex', alignItems: 'center', gap: 5, background: 'none', border: 'none',
            color: 'var(--text-muted, #64748b)', fontSize: 12, cursor: 'pointer', padding: '3px 0',
            fontFamily: 'var(--font-body, Inter, sans-serif)', transition: 'color .1s',
          }}
            onMouseEnter={e => e.currentTarget.style.color = 'var(--text, #f1f5f9)'}
            onMouseLeave={e => e.currentTarget.style.color = 'var(--text-muted, #64748b)'}
          >
            ← Campanhas
          </button>
          <span style={{ color: 'var(--text-dim, #475569)', fontSize: 12 }}>/</span>
          <span style={{ fontSize: 12, color: 'var(--text-dim, #475569)', maxWidth: 280, overflow: 'hidden', textOverflow: 'ellipsis', whiteSpace: 'nowrap' }}>
            {campanhaSummary.titulo}
          </span>
        </div>

        {/* Title row */}
        <div style={{ display: 'flex', alignItems: 'flex-start', justifyContent: 'space-between', gap: 16, marginBottom: 16 }}>
          <div>
            <div style={{ display: 'flex', alignItems: 'center', gap: 8, marginBottom: 6 }}>
              <span style={{ fontSize: 10, fontWeight: 700, textTransform: 'uppercase', letterSpacing: '0.1em', color: bCol, fontFamily: 'var(--font-mono, monospace)' }}>
                {campanhaSummary.brand_name}
              </span>
              <StatusBadge status={detail?.status || campanhaSummary.status} />
            </div>
            <h1 style={{ margin: 0, fontSize: 24, fontWeight: 700, color: 'var(--text, #f1f5f9)', fontFamily: 'var(--font-display, Montserrat, sans-serif)', letterSpacing: '-0.02em', lineHeight: 1.2 }}>
              {campanhaSummary.titulo}
            </h1>
            {(campanhaSummary.commercial_name || campanhaSummary.product_name) && (
              <div style={{ fontSize: 13, color: 'var(--text-muted, #64748b)', marginTop: 4 }}>{campanhaSummary.commercial_name || campanhaSummary.product_name}</div>
            )}
          </div>

          {/* Enviar para Produção */}
          {!loading && (
            detail?.status === 'em_producao'
              ? <div style={{ fontSize: 12, color: 'var(--success, #22c55e)', fontWeight: 500, padding: '8px 0' }}>✓ Em Produção</div>
              : <button onClick={() => handleAction('enviarProducao')} disabled={!canEnviar || generating.producao}
                  className="btn btn-primary" style={{ opacity: canEnviar ? 1 : 0.4, whiteSpace: 'nowrap', flexShrink: 0 }}>
                  {generating.producao ? '⟳ A enviar…' : '→ Enviar para Produção'}
                </button>
          )}
        </div>

        {/* Tabs */}
        <div style={{ display: 'flex', gap: 2, borderBottom: '1px solid var(--border, #1e293b)' }}>
          {TABS.map(t => (
            <button key={t.id} onClick={() => setTab(t.id)} style={{
              background: 'none', border: 'none',
              borderBottom: `2px solid ${tab === t.id ? 'var(--ai-500, #3859D0)' : 'transparent'}`,
              marginBottom: '-1px',
              color: tab === t.id ? 'var(--text, #f1f5f9)' : 'var(--text-muted, #64748b)',
              fontSize: 13, fontWeight: tab === t.id ? 600 : 500,
              fontFamily: 'var(--font-display, Montserrat, sans-serif)',
              padding: '6px 16px 10px', cursor: 'pointer', whiteSpace: 'nowrap', transition: 'all .15s',
            }}>{t.label}</button>
          ))}
        </div>
      </div>

      {/* ── Tab content ── */}
      <div style={{ padding: '24px 32px 40px' }}>
        {error && (
          <div style={{ marginBottom: 16, padding: '12px 16px', background: 'rgba(239,68,68,.08)', borderRadius: 8, fontSize: 12, color: '#f87171' }}>{error}</div>
        )}
        {loading ? (
          <div style={{ display: 'grid', gridTemplateColumns: '1fr 1fr', gap: 12 }}>
            {[1,2,3,4].map(i => <div key={i} style={{ height: 120, borderRadius: 8, background: 'var(--bg-elev, #162032)', opacity: 1 - i * 0.2 }} />)}
          </div>
        ) : (
          <>
            {tab === 'conceito' && <TabConceitoFull campanha={detail} onAction={handleAction} generating={generating} />}
            {tab === 'copy'     && <TabCopyFull     campanha={detail} copy={detail?.copy || []}       onAction={handleAction} generating={generating} />}
            {tab === 'prompts'  && <TabPromptsFull  campanha={detail} prompts={detail?.prompts || []} onAction={handleAction} generating={generating} />}
          </>
        )}
      </div>
    </div>
  );
};

// ── TabConceitoFull (layout 2 colunas) ────────────────────────────────────────
const TabConceitoFull = ({ campanha, onAction, generating }) => {
  const hasConceito = !!(campanha?.big_idea);
  const isApproved  = ['copy_pendente','copy_gerado','copy_aprovado','prompts_pendente','prompts_gerado','em_producao'].includes(campanha?.status);

  if (!hasConceito) return (
    <div style={{ display: 'flex', flexDirection: 'column', alignItems: 'center', padding: '48px 0', gap: 16 }}>
      <div style={{ fontSize: 14, color: 'var(--text-muted, #64748b)', textAlign: 'center', maxWidth: 440, lineHeight: 1.6 }}>
        Nenhum conceito gerado ainda. A Digi AI vai analisar os 5 blocos do briefing e criar o conceito estratégico da campanha.
      </div>
      <button onClick={() => onAction('generateConceito')} disabled={generating.conceito} className="btn btn-primary">
        {generating.conceito ? '⟳ A gerar conceito…' : '✦ Gerar Conceito com Digi AI'}
      </button>
    </div>
  );

  const fields = [
    { key: 'big_idea',       label: 'Big Idea',        icon: '💡', desc: 'A ideia criativa central' },
    { key: 'posicionamento', label: 'Posicionamento',  icon: '🎯', desc: 'Percepção vs concorrência' },
    { key: 'narrativa',      label: 'Narrativa',       icon: '📖', desc: 'Arco emocional da campanha' },
    { key: 'tom_campanha',   label: 'Tom da Campanha', icon: '🗣️', desc: 'Voz e linguagem' },
  ];

  return (
    <div>
      <div style={{ display: 'grid', gridTemplateColumns: '1fr 1fr', gap: 16, marginBottom: 20 }}>
        {fields.map(f => campanha[f.key] ? (
          <div key={f.key} style={{ background: 'var(--bg-elev, #162032)', border: '1px solid var(--border, #1e293b)', borderRadius: 10, padding: '18px 20px' }}>
            <div style={{ display: 'flex', alignItems: 'center', gap: 7, marginBottom: 10 }}>
              <span style={{ fontSize: 16 }}>{f.icon}</span>
              <div>
                <div style={{ fontSize: 11, fontWeight: 700, textTransform: 'uppercase', letterSpacing: '0.08em', color: 'var(--text-muted, #64748b)', fontFamily: 'var(--font-mono, monospace)' }}>{f.label}</div>
                <div style={{ fontSize: 10, color: 'var(--text-dim, #475569)', fontFamily: 'var(--font-mono, monospace)' }}>{f.desc}</div>
              </div>
            </div>
            <div style={{ fontSize: 13.5, color: 'var(--text, #f1f5f9)', lineHeight: 1.65 }}>{campanha[f.key]}</div>
          </div>
        ) : null)}
      </div>
      {!isApproved && (
        <div style={{ display: 'flex', gap: 8 }}>
          <button onClick={() => onAction('aprovarConceito')} disabled={generating.approve} className="btn btn-primary">
            ✓ Aprovar Conceito
          </button>
          <button onClick={() => onAction('generateConceito')} disabled={generating.conceito} className="btn" style={{ color: 'var(--text-muted, #64748b)' }}>
            {generating.conceito ? '⟳ A gerar…' : '↻ Regenerar'}
          </button>
        </div>
      )}
      {isApproved && <div style={{ fontSize: 12, color: 'var(--success, #22c55e)', fontWeight: 500 }}>✓ Conceito aprovado</div>}
    </div>
  );
};

// ── TabCopyFull (grid de canais) ───────────────────────────────────────────────
const TabCopyFull = ({ campanha, copy, onAction, generating }) => {
  const channels    = Array.isArray(campanha?.briefing?.channels) ? campanha.briefing.channels : [];
  const hasCopy     = copy.length > 0;
  const conceptDone = campanha?.big_idea;

  if (!conceptDone) return (
    <div style={{ padding: '32px 0', textAlign: 'center', color: 'var(--text-muted, #64748b)', fontSize: 13 }}>
      Aprova o Conceito antes de gerar copy.
    </div>
  );

  return (
    <div>
      {!hasCopy ? (
        <div style={{ display: 'flex', flexDirection: 'column', alignItems: 'center', padding: '40px 0', gap: 14 }}>
          <div style={{ fontSize: 13, color: 'var(--text-muted, #64748b)', textAlign: 'center', maxWidth: 440, lineHeight: 1.6 }}>
            Canais do briefing: <strong style={{ color: 'var(--text, #f1f5f9)' }}>{channels.map(c => CANAL_LABEL[c] || c).join(', ') || '—'}</strong>
          </div>
          <button onClick={() => onAction('generateCopy')} disabled={generating.copy} className="btn btn-primary">
            {generating.copy ? '⟳ A gerar copy…' : '✦ Gerar Copy para todos os canais'}
          </button>
        </div>
      ) : (
        <>
          <div style={{ display: 'grid', gridTemplateColumns: 'repeat(auto-fill, minmax(320px, 1fr))', gap: 14, marginBottom: 20 }}>
            {copy.map(cp => <CopyCardFull key={cp.id} cp={cp} onApprove={() => onAction('approveCopy', cp.id, 'aprovado')} onFlag={() => onAction('approveCopy', cp.id, 'correcao')} />)}
          </div>
          <button onClick={() => onAction('generateCopy')} disabled={generating.copy} className="btn" style={{ color: 'var(--text-muted, #64748b)', fontSize: 12 }}>
            {generating.copy ? '⟳ A gerar…' : '↻ Regenerar todo o copy'}
          </button>
        </>
      )}
    </div>
  );
};

const CopyCardFull = ({ cp, onApprove, onFlag }) => {
  const canalLabel = CANAL_LABEL[cp.canal] || cp.canal || '—';
  const canalIcon  = CANAL_ICON[cp.canal] || '📄';
  const isApproved = cp.status === 'aprovado';
  const isFlagged  = cp.status === 'correcao';
  return (
    <div style={{
      background: 'var(--bg-elev, #162032)', borderRadius: 10,
      border: `1px solid ${isApproved ? 'rgba(34,197,94,.3)' : isFlagged ? 'rgba(251,146,60,.3)' : 'var(--border, #1e293b)'}`,
      display: 'flex', flexDirection: 'column',
    }}>
      <div style={{ padding: '14px 18px 10px', borderBottom: '1px solid var(--border, #1e293b)', display: 'flex', alignItems: 'center', gap: 8 }}>
        <span style={{ fontSize: 18 }}>{canalIcon}</span>
        <span style={{ fontSize: 14, fontWeight: 600, color: 'var(--text, #f1f5f9)', flex: 1, fontFamily: 'var(--font-display, Montserrat, sans-serif)' }}>{canalLabel}</span>
        {cp.formato && <span style={{ fontSize: 10, color: 'var(--text-dim, #475569)', fontFamily: 'var(--font-mono, monospace)' }}>{cp.formato}</span>}
        <StatusBadge status={cp.status} />
      </div>
      <div style={{ padding: '14px 18px', display: 'flex', flexDirection: 'column', gap: 12, flex: 1 }}>
        {cp.headline && <CopyField label="Headline" value={cp.headline} />}
        {cp.body     && <CopyField label="Body"     value={cp.body}     multiline />}
        {cp.cta      && <CopyField label="CTA"      value={cp.cta} />}
        {cp.hashtags && <CopyField label="Hashtags" value={cp.hashtags} mono />}
        {!isApproved && (
          <div style={{ display: 'flex', gap: 8, marginTop: 4, paddingTop: 10, borderTop: '1px solid var(--border, #1e293b)' }}>
            <button onClick={onApprove} className="btn btn-sm btn-primary" style={{ fontSize: 11 }}>✓ Aprovar</button>
            <button onClick={onFlag}    className="btn btn-sm" style={{ fontSize: 11, color: '#fb923c', borderColor: 'rgba(251,146,60,.3)' }}>⚑ Corrigir</button>
          </div>
        )}
        {isApproved && <div style={{ fontSize: 11, color: 'var(--success, #22c55e)', fontWeight: 500, paddingTop: 8, borderTop: '1px solid var(--border, #1e293b)' }}>✓ Copy aprovado</div>}
      </div>
    </div>
  );
};

// ── TabPromptsFull (grid visual) ──────────────────────────────────────────────
const TabPromptsFull = ({ campanha, prompts, onAction, generating }) => {
  const copyDone = (campanha?.copy || []).some(c => c.status === 'aprovado') || campanha?.big_idea;

  if (!copyDone) return (
    <div style={{ padding: '32px 0', textAlign: 'center', color: 'var(--text-muted, #64748b)', fontSize: 13 }}>
      Aprova pelo menos um canal de copy antes de gerar prompts visuais.
    </div>
  );

  return (
    <div>
      {prompts.length === 0 ? (
        <div style={{ display: 'flex', flexDirection: 'column', alignItems: 'center', padding: '40px 0', gap: 14 }}>
          <div style={{ fontSize: 13, color: 'var(--text-muted, #64748b)', textAlign: 'center', maxWidth: 440, lineHeight: 1.6 }}>
            A Digi AI vai criar prompts de imagem e vídeo para todos os canais visuais da campanha.
          </div>
          <button onClick={() => onAction('generatePrompts')} disabled={generating.prompts} className="btn btn-primary">
            {generating.prompts ? '⟳ A gerar prompts…' : '✦ Gerar Prompts Visuais'}
          </button>
        </div>
      ) : (
        <>
          <div style={{ display: 'grid', gridTemplateColumns: 'repeat(auto-fill, minmax(320px, 1fr))', gap: 14, marginBottom: 20 }}>
            {prompts.map(pr => <PromptCardFull key={pr.id} pr={pr} onApprove={() => onAction('approvePrompt', pr.id, 'aprovado')} onFlag={() => onAction('approvePrompt', pr.id, 'correcao')} />)}
          </div>
          <button onClick={() => onAction('generatePrompts')} disabled={generating.prompts} className="btn" style={{ color: 'var(--text-muted, #64748b)', fontSize: 12 }}>
            {generating.prompts ? '⟳ A gerar…' : '↻ Regenerar prompts'}
          </button>
        </>
      )}
    </div>
  );
};

const PromptCardFull = ({ pr, onApprove, onFlag }) => {
  const canalLabel = CANAL_LABEL[pr.canal] || pr.canal || '—';
  const canalIcon  = CANAL_ICON[pr.canal] || '🖼️';
  const tipoLabel  = pr.tipo === 'imagem' ? '📷 Imagem' : '🎬 Vídeo';
  const isApproved = pr.status === 'aprovado';
  const isFlagged  = pr.status === 'correcao';
  return (
    <div style={{
      background: 'var(--bg-elev, #162032)', borderRadius: 10,
      border: `1px solid ${isApproved ? 'rgba(34,197,94,.3)' : isFlagged ? 'rgba(251,146,60,.3)' : 'var(--border, #1e293b)'}`,
      display: 'flex', flexDirection: 'column',
    }}>
      <div style={{ padding: '14px 18px 10px', borderBottom: '1px solid var(--border, #1e293b)', display: 'flex', alignItems: 'center', gap: 8 }}>
        <span style={{ fontSize: 18 }}>{canalIcon}</span>
        <span style={{ fontSize: 14, fontWeight: 600, color: 'var(--text, #f1f5f9)', flex: 1, fontFamily: 'var(--font-display, Montserrat, sans-serif)' }}>{canalLabel}</span>
        <span style={{ fontSize: 10, color: 'var(--text-dim, #475569)', fontFamily: 'var(--font-mono, monospace)' }}>{tipoLabel}</span>
        {pr.ratio && <span style={{ fontSize: 10, color: 'var(--text-dim, #475569)', fontFamily: 'var(--font-mono, monospace)', marginLeft: 4 }}>{pr.ratio}</span>}
        <StatusBadge status={pr.status} />
      </div>
      <div style={{ padding: '14px 18px', display: 'flex', flexDirection: 'column', gap: 12, flex: 1 }}>
        {pr.prompt_texto && <CopyField label="Prompt" value={pr.prompt_texto} multiline />}
        {pr.estilo       && <CopyField label="Estilo"  value={pr.estilo} />}
        {pr.referencia   && <CopyField label="Referência" value={pr.referencia} />}
        {!isApproved && (
          <div style={{ display: 'flex', gap: 8, marginTop: 4, paddingTop: 10, borderTop: '1px solid var(--border, #1e293b)' }}>
            <button onClick={onApprove} className="btn btn-sm btn-primary" style={{ fontSize: 11 }}>✓ Aprovar</button>
            <button onClick={onFlag}    className="btn btn-sm" style={{ fontSize: 11, color: '#fb923c', borderColor: 'rgba(251,146,60,.3)' }}>⚑ Corrigir</button>
          </div>
        )}
        {isApproved && <div style={{ fontSize: 11, color: 'var(--success, #22c55e)', fontWeight: 500, paddingTop: 8, borderTop: '1px solid var(--border, #1e293b)' }}>✓ Prompt aprovado</div>}
      </div>
    </div>
  );
};

// ── EditTituloModal ────────────────────────────────────────────────────────────
const EditTituloModal = ({ campanha, onSave, onClose }) => {
  const [titulo, setTitulo] = React.useState(campanha.titulo);
  const [saving, setSaving] = React.useState(false);
  const inputRef = React.useRef(null);
  React.useEffect(() => { inputRef.current?.focus(); inputRef.current?.select(); }, []);
  const save = async () => {
    if (!titulo.trim() || titulo.trim() === campanha.titulo) { onClose(); return; }
    setSaving(true);
    await CampAPI.update(campanha.id, { titulo: titulo.trim() });
    onSave();
    onClose();
  };
  return (
    <>
      <div onClick={onClose} style={{ position: 'fixed', inset: 0, background: 'rgba(0,0,0,.5)', zIndex: 300 }} />
      <div style={{
        position: 'fixed', top: '50%', left: '50%', transform: 'translate(-50%,-50%)', zIndex: 301,
        background: 'var(--bg-elev, #1e293b)', border: '1px solid var(--border, #334155)',
        borderRadius: 10, padding: '22px 24px', width: 400,
        boxShadow: '0 16px 48px rgba(0,0,0,.5)',
      }}>
        <div style={{ fontSize: 14, fontWeight: 600, color: 'var(--text, #f1f5f9)', marginBottom: 14, fontFamily: 'var(--font-display, Montserrat, sans-serif)' }}>
          Editar título
        </div>
        <input ref={inputRef} value={titulo} onChange={e => setTitulo(e.target.value)}
          onKeyDown={e => { if (e.key === 'Enter') save(); if (e.key === 'Escape') onClose(); }}
          style={{
            width: '100%', boxSizing: 'border-box', padding: '9px 12px', borderRadius: 6, fontSize: 13,
            background: 'var(--bg-sunken, #0f172a)', border: '1px solid var(--border, #334155)',
            color: 'var(--text, #f1f5f9)', outline: 'none', fontFamily: 'var(--font-body, Inter, sans-serif)',
            marginBottom: 14,
          }}
        />
        <div style={{ display: 'flex', justifyContent: 'flex-end', gap: 8 }}>
          <button onClick={onClose} className="btn" style={{ fontSize: 12 }}>Cancelar</button>
          <button onClick={save} disabled={saving || !titulo.trim()} className="btn btn-primary" style={{ fontSize: 12 }}>
            {saving ? '⟳ A guardar…' : 'Guardar'}
          </button>
        </div>
      </div>
    </>
  );
};

// ── BriefingResumo ─────────────────────────────────────────────────────────────
const BriefingResumo = ({ campanha, onBack, onRefresh }) => {
  const [briefing,   setBriefing]   = React.useState(null);
  const [loading,    setLoading]    = React.useState(true);
  const [generating, setGenerating] = React.useState(false);
  const bCol = _brandColor(campanha.brand_slug);

  React.useEffect(() => {
    if (!campanha.briefing_id) { setLoading(false); return; }
    CampAPI.getBriefing(campanha.briefing_id)
      .then(d => setBriefing(d))
      .catch(() => {})
      .finally(() => setLoading(false));
  }, [campanha.briefing_id]);

  const handleGerar = async () => {
    setGenerating(true);
    try { await CampAPI.generateConceito(campanha.id); } catch (e) {}
    setGenerating(false);
    onRefresh();
    onBack();
  };

  const Field = ({ label, value }) => value ? (
    <div style={{ display: 'flex', flexDirection: 'column', gap: 6 }}>
      <div style={{ fontSize: 9.5, fontWeight: 700, textTransform: 'uppercase', letterSpacing: '0.1em', color: 'var(--text-dim, #475569)', fontFamily: 'var(--font-mono, monospace)' }}>{label}</div>
      <div style={{ fontSize: 13, color: 'var(--text, #f1f5f9)', lineHeight: 1.65 }}>{value}</div>
    </div>
  ) : null;

  const TagList = ({ label, items }) => (items && items.length > 0) ? (
    <div style={{ display: 'flex', flexDirection: 'column', gap: 6 }}>
      <div style={{ fontSize: 9.5, fontWeight: 700, textTransform: 'uppercase', letterSpacing: '0.1em', color: 'var(--text-dim, #475569)', fontFamily: 'var(--font-mono, monospace)' }}>{label}</div>
      <div style={{ display: 'flex', flexWrap: 'wrap', gap: 6 }}>
        {items.map((t, i) => (
          <span key={i} style={{ fontSize: 11, padding: '2px 8px', borderRadius: 99, background: 'var(--bg-sunken, #0f172a)', color: 'var(--text-muted, #94a3b8)', border: '1px solid var(--border, #1e293b)' }}>
            {typeof t === 'object' ? (t.name || t.label || JSON.stringify(t)) : t}
          </span>
        ))}
      </div>
    </div>
  ) : null;

  const Section = ({ title, children }) => (
    <div style={{ background: 'var(--bg-elev, #162032)', border: '1px solid var(--border, #1e293b)', borderRadius: 10, padding: '18px 20px', display: 'flex', flexDirection: 'column', gap: 14 }}>
      <div style={{ fontSize: 9.5, fontWeight: 700, textTransform: 'uppercase', letterSpacing: '0.12em', color: bCol, fontFamily: 'var(--font-mono, monospace)' }}>{title}</div>
      {children}
    </div>
  );

  return (
    <div className="scrollbar" style={{ height: '100%', overflowY: 'auto' }}>
      {/* Breadcrumb + Header */}
      <div style={{ padding: '20px 32px 24px' }}>
        <div style={{ display: 'flex', alignItems: 'center', gap: 10, marginBottom: 16 }}>
          <button onClick={onBack} style={{ background: 'none', border: 'none', cursor: 'pointer', color: 'var(--text-muted, #64748b)', fontSize: 13, padding: 0, display: 'flex', alignItems: 'center', gap: 6, fontFamily: 'var(--font-body, Inter, sans-serif)' }}>
            ← Campanhas
          </button>
          <span style={{ fontSize: 13, color: 'var(--text-dim, #475569)' }}>/</span>
          <span style={{ fontSize: 13, color: 'var(--text-muted, #64748b)' }}>Briefing</span>
        </div>
        <div style={{ fontSize: 9, fontWeight: 700, textTransform: 'uppercase', letterSpacing: '0.1em', color: bCol, fontFamily: 'var(--font-mono, monospace)', marginBottom: 6 }}>{campanha.brand_name}</div>
        <h1 className="font-display" style={{ margin: '0 0 4px', fontSize: 24, fontWeight: 600, letterSpacing: '-0.015em', color: 'var(--text, #f1f5f9)' }}>{campanha.titulo}</h1>
        {(campanha.commercial_name || campanha.product_name) && <div style={{ fontSize: 13, color: 'var(--text-muted, #64748b)' }}>{campanha.commercial_name || campanha.product_name}</div>}
      </div>

      {/* Conteúdo */}
      <div style={{ padding: '0 32px 40px', display: 'flex', flexDirection: 'column', gap: 12 }}>
        {loading ? (
          <div style={{ color: 'var(--text-muted, #64748b)', fontSize: 13 }}>A carregar briefing…</div>
        ) : briefing ? (
          <>
            {briefing.block1 && (
              <Section title="Produto">
                <Field label="Nome Comercial"  value={briefing.block1.commercial_name} />
                <Field label="Elevator Pitch"  value={briefing.block1.elevator_pitch} />
                <TagList label="USPs"          items={briefing.block1.usps} />
                <TagList label="Aplicações"    items={briefing.block1.applications} />
                <TagList label="Mercados"      items={briefing.block1.geo_markets} />
              </Section>
            )}
            {briefing.block2 && (
              <Section title="Público-Alvo">
                <Field label="Decision Maker"   value={briefing.block2.decision_maker} />
                <Field label="Utilizador Final" value={briefing.block2.end_user} />
                <TagList label="Pain Points"    items={briefing.block2.pain_points} />
                <TagList label="Motivadores"    items={briefing.block2.motivators} />
              </Section>
            )}
            {briefing.block4 && (
              <Section title="Campanha">
                <Field label="Objectivo"      value={briefing.block4.objective} />
                <Field label="Mensagem-Chave" value={briefing.block4.key_message} />
                <Field label="Tom"            value={briefing.block4.tone} />
                <TagList label="Canais"       items={briefing.block4.channels} />
              </Section>
            )}
            <div style={{ display: 'flex', gap: 10, paddingTop: 8 }}>
              <button onClick={handleGerar} disabled={generating} className="btn btn-primary" style={{ gap: 6 }}>
                {generating ? '⟳ A gerar conceito…' : '✦ Gerar Conceito com Digi AI'}
              </button>
              <button onClick={onBack} className="btn" style={{ color: 'var(--text-muted, #64748b)' }}>Voltar</button>
            </div>
          </>
        ) : (
          <div style={{ fontSize: 13, color: 'var(--text-muted, #64748b)' }}>Briefing não encontrado.</div>
        )}
      </div>
    </div>
  );
};

// ── NovaCampanhaModal ──────────────────────────────────────────────────────────
const NovaCampanhaModal = ({ onClose, onCreated }) => {
  const [briefings, setBriefings] = React.useState(null);
  const [selected,  setSelected]  = React.useState(null);
  const [saving,    setSaving]    = React.useState(false);
  const [error,     setError]     = React.useState('');

  React.useEffect(() => {
    CampAPI.availableForCampaign()
      .then(d => setBriefings(Array.isArray(d) ? d : []))
      .catch(() => setBriefings([]));
  }, []);

  const handleCreate = async () => {
    if (!selected) return;
    setSaving(true); setError('');
    try {
      const titulo = selected.commercial_name || selected.product_name || `Campanha #${selected.id}`;
      const camp = await CampAPI.create({ briefing_id: selected.id, titulo });
      if (camp?.error) throw new Error(camp.error);
      onCreated(camp);
    } catch (e) {
      setError(e.message || 'Erro ao criar campanha.');
      setSaving(false);
    }
  };

  const goToBriefings = () => {
    onClose();
    if (window.mktNavToSub) window.mktNavToSub('briefings');
  };

  return (
    <div style={{
      position: 'fixed', inset: 0, zIndex: 200,
      background: 'rgba(0,0,0,0.55)', display: 'flex', alignItems: 'center', justifyContent: 'center',
    }} onClick={e => { if (e.target === e.currentTarget) onClose(); }}>
      <div style={{
        background: 'var(--bg-elev, #162032)', border: '1px solid var(--border, #1e293b)',
        borderRadius: 12, width: 520, maxHeight: '80vh', display: 'flex', flexDirection: 'column',
        boxShadow: '0 24px 64px rgba(0,0,0,0.4)',
      }}>
        {/* Header */}
        <div style={{ padding: '20px 24px 16px', borderBottom: '1px solid var(--border, #1e293b)', display: 'flex', alignItems: 'center', justifyContent: 'space-between', flexShrink: 0 }}>
          <div>
            <div style={{ fontSize: 10, fontFamily: 'var(--font-mono, monospace)', color: 'var(--text-dim, #475569)', letterSpacing: '0.08em', marginBottom: 4 }}>NOVA CAMPANHA</div>
            <div style={{ fontSize: 15, fontWeight: 600, fontFamily: 'var(--font-display, Montserrat, sans-serif)', color: 'var(--text, #f1f5f9)' }}>Selecciona um briefing aprovado</div>
          </div>
          <button onClick={onClose} style={{ background: 'none', border: 'none', color: 'var(--text-muted, #64748b)', fontSize: 18, cursor: 'pointer', lineHeight: 1, padding: 4 }}>✕</button>
        </div>

        {/* Body */}
        <div className="scrollbar" style={{ flex: 1, overflowY: 'auto', padding: '12px 24px' }}>
          {briefings === null ? (
            <div style={{ padding: '32px 0', textAlign: 'center', color: 'var(--text-muted, #64748b)', fontSize: 13 }}>A carregar…</div>
          ) : briefings.length === 0 ? (
            <div style={{ padding: '32px 0', textAlign: 'center', display: 'flex', flexDirection: 'column', alignItems: 'center', gap: 14 }}>
              <div style={{ fontSize: 13, color: 'var(--text-muted, #64748b)' }}>Não há briefings aprovados disponíveis.</div>
              <button onClick={goToBriefings} className="btn btn-sm btn-primary">
                Ir para Briefings
              </button>
            </div>
          ) : (
            <div style={{ display: 'flex', flexDirection: 'column', gap: 6 }}>
              {briefings.map(b => {
                const isActive = selected?.id === b.id;
                const bColor = b.brand_color || '#3859D0';
                return (
                  <div key={b.id} onClick={() => setSelected(b)} style={{
                    padding: '12px 14px', borderRadius: 8, cursor: 'pointer',
                    border: `1px solid ${isActive ? 'var(--ai-500, #3859D0)' : 'var(--border, #1e293b)'}`,
                    background: isActive ? 'color-mix(in oklch, var(--ai-500, #3859D0) 8%, transparent)' : 'var(--bg, #0f172a)',
                    transition: 'border-color .15s, background .15s',
                    display: 'flex', alignItems: 'center', gap: 12,
                  }}>
                    <div style={{ width: 4, borderRadius: 2, alignSelf: 'stretch', background: bColor, flexShrink: 0 }} />
                    <div style={{ flex: 1, minWidth: 0 }}>
                      <div style={{ display: 'flex', alignItems: 'center', gap: 8, marginBottom: 2 }}>
                        <span style={{ fontSize: 11, fontWeight: 700, color: bColor, fontFamily: 'var(--font-display, Montserrat, sans-serif)', letterSpacing: '0.04em' }}>{b.brand_name}</span>
                        {(b.commercial_name || b.product_name) && (
                          <span style={{ fontSize: 12, color: 'var(--text, #f1f5f9)', fontWeight: 500 }}>{b.commercial_name || b.product_name}</span>
                        )}
                      </div>
                      {b.objective && (
                        <div style={{ fontSize: 11.5, color: 'var(--text-muted, #64748b)', whiteSpace: 'nowrap', overflow: 'hidden', textOverflow: 'ellipsis' }}>{b.objective}</div>
                      )}
                    </div>
                    {isActive && <div style={{ color: 'var(--ai-500, #3859D0)', fontSize: 16, flexShrink: 0 }}>✓</div>}
                  </div>
                );
              })}
            </div>
          )}
          {error && <div style={{ marginTop: 8, fontSize: 12, color: 'var(--danger, #ef4444)' }}>{error}</div>}
        </div>

        {/* Footer */}
        {briefings && briefings.length > 0 && (
          <div style={{ padding: '14px 24px', borderTop: '1px solid var(--border, #1e293b)', display: 'flex', justifyContent: 'flex-end', gap: 8, flexShrink: 0 }}>
            <button onClick={onClose} className="btn btn-sm">Cancelar</button>
            <button onClick={handleCreate} disabled={!selected || saving} className="btn btn-sm btn-primary"
              style={{ opacity: (!selected || saving) ? 0.5 : 1 }}>
              {saving ? 'A criar…' : 'Criar Campanha'}
            </button>
          </div>
        )}
      </div>
    </div>
  );
};

// ── MktCampanhasScreen (main) ──────────────────────────────────────────────────
const MktCampanhasScreen = () => {
  const [campanhas,     setCampanhas]     = React.useState(null);
  const [allBrands,     setAllBrands]     = React.useState([]);
  const [filterBrand,   setFilterBrand]   = React.useState('all');
  const [filterCol,     setFilterCol]     = React.useState('all');
  const [filterProduto, setFilterProduto] = React.useState('all');
  const [filterCriador, setFilterCriador] = React.useState('all');
  const today = new Date();
  const [dateRange,     setDateRange]     = React.useState({ preset: 'all', start: new Date(today.getFullYear(), 0, 1), end: today });
  const [search,        setSearch]        = React.useState('');
  const [selected,      setSelected]      = React.useState(null);
  const [editing,       setEditing]       = React.useState(null);
  const [showModal,     setShowModal]     = React.useState(false);
  const [toast,         setToast]         = React.useState('');
  const [dragCard,      setDragCard]      = React.useState(null);
  const [initialTab,    setInitialTab]    = React.useState('conceito');

  const BRAND_ORDER = ['mimaki', 'biond', 'decal', 'alldecor', 'sensek', 'netscreen', 'digidelta'];

  const load = React.useCallback(async () => {
    try {
      const live = await CampAPI.list();
      setCampanhas(Array.isArray(live) ? live : []);
    } catch {
      setCampanhas([]);
    }
  }, []);

  React.useEffect(() => { load(); }, [load]);

  React.useEffect(() => {
    CampAPI.getBrands().then(d => {
      if (!Array.isArray(d)) return;
      const sorted = d.filter(b => b.active !== false && b.slug !== 'todas').sort((a, b) => {
        const ia = BRAND_ORDER.indexOf(a.slug), ib = BRAND_ORDER.indexOf(b.slug);
        return (ia === -1 ? 99 : ia) - (ib === -1 ? 99 : ib);
      });
      setAllBrands(sorted);
    }).catch(() => {});
  }, []);

  const toast_ = (msg) => { setToast(msg); setTimeout(() => setToast(''), 3200); };

  const handleDelete = async (id) => {
    try {
      await CampAPI.remove(id);
      await load();
      toast_('Campanha apagada.');
    } catch { toast_('Erro ao apagar campanha.'); }
  };

  const COL_TAB_MAP = { conceito: 'conceito', copy: 'copy', para_producao: 'prompts' };
  const handleDrop = (card, targetColId) => {
    const srcCol = STATUS_COL[card.status];
    const srcIdx = KANBAN_COLS.findIndex(c => c.id === srcCol?.id);
    const tgtIdx = KANBAN_COLS.findIndex(c => c.id === targetColId);
    if (tgtIdx <= srcIdx) { toast_('Não é possível recuar na pipeline.'); return; }
    setInitialTab(COL_TAB_MAP[targetColId] || 'conceito');
    setSelected(card);
  };

  React.useEffect(() => {
    const clear = () => setDragCard(null);
    document.addEventListener('dragend', clear);
    return () => document.removeEventListener('dragend', clear);
  }, []);


  const produtos = React.useMemo(() => {
    const s = new Set((campanhas || []).map(c => c.commercial_name || c.product_name).filter(Boolean));
    return [...s].sort().map(v => ({ value: v, label: v }));
  }, [campanhas]);

  const criadores = React.useMemo(() => {
    const s = new Set((campanhas || []).map(c => c.created_by_name).filter(Boolean));
    return [...s].sort().map(v => ({ value: v, label: v }));
  }, [campanhas]);

  const filtered = React.useMemo(() => {
    if (!campanhas) return [];
    return campanhas.filter(c => {
      if (filterBrand !== 'all' && c.brand_slug !== filterBrand) return false;
      if (filterCol !== 'all') {
        const col = KANBAN_COLS.find(k => k.id === filterCol);
        if (col && !col.statuses.includes(c.status)) return false;
      }
      if (filterProduto !== 'all' && (c.commercial_name || c.product_name) !== filterProduto) return false;
      if (filterCriador !== 'all' && c.created_by_name !== filterCriador) return false;
      if (dateRange.preset !== 'all' && dateRange.start && dateRange.end) {
        const d = new Date(c.created_at);
        if (d < dateRange.start || d > dateRange.end) return false;
      }
      if (search.trim()) {
        const q = search.toLowerCase();
        if (!(c.titulo || '').toLowerCase().includes(q) && !(c.commercial_name || c.product_name || '').toLowerCase().includes(q)) return false;
      }
      return true;
    });
  }, [campanhas, filterBrand, filterCol, filterProduto, filterCriador, dateRange, search]);

  const kpi = React.useMemo(() => {
    const all = campanhas || [];
    const count = (id) => { const col = KANBAN_COLS.find(k => k.id === id); return col ? all.filter(c => col.statuses.includes(c.status)).length : 0; };
    return { total: all.length, briefing: count('briefing'), conceito: count('conceito'), copy: count('copy'), para_producao: count('para_producao') };
  }, [campanhas]);

  const kpiCards = [
    { id: 'briefing',      label: 'Briefing',      value: kpi.briefing,      accent: 'var(--ai-500, #3859D0)',  fill: kpi.total ? kpi.briefing      / kpi.total : 0 },
    { id: 'conceito',      label: 'Conceito',      value: kpi.conceito,      accent: '#94a3b8',                 fill: kpi.total ? kpi.conceito      / kpi.total : 0 },
    { id: 'copy',          label: 'Copy',           value: kpi.copy,          accent: 'var(--warning, #f59e0b)', fill: kpi.total ? kpi.copy          / kpi.total : 0 },
    { id: 'para_producao', label: 'Para Produção',  value: kpi.para_producao, accent: 'var(--success, #22c55e)', fill: kpi.total ? kpi.para_producao / kpi.total : 0 },
  ];

  const colCards = KANBAN_COLS.map(col => ({
    ...col,
    cards: filtered.filter(c => col.statuses.includes(c.status)),
  }));

  const hasFilter = filterBrand !== 'all' || filterCol !== 'all' || filterProduto !== 'all' || filterCriador !== 'all' || dateRange.preset !== 'all' || search.trim();

  // ── Vistas de detalhe (full-width) ────────────────────────────────────────
  if (selected) {
    const isBriefingCard = selected.status === 'conceito_pendente';
    return (
      <>
        {isBriefingCard
          ? <BriefingResumo campanha={selected} onBack={() => setSelected(null)} onRefresh={load} />
          : <CampanhaDetail campanhaSummary={selected} onBack={() => setSelected(null)} onRefresh={load} initialTab={initialTab} />
        }
        {editing && (
          <EditTituloModal campanha={editing} onSave={load} onClose={() => setEditing(null)} />
        )}
      </>
    );
  }

  // ── Vista Kanban ────────────────────────────────────────────────────────────
  return (
    <>
      {showModal && (
        <NovaCampanhaModal
          onClose={() => setShowModal(false)}
          onCreated={(camp) => { setShowModal(false); load(); toast_(`Campanha "${camp.titulo}" criada.`); }}
        />
      )}
      <div className="scrollbar" style={{ height: '100%', overflowY: 'auto' }}>

        {/* Header */}
        <div style={{ padding: '28px 32px 0', display: 'flex', flexDirection: 'column', gap: 18 }}>
          <div style={{ display: 'flex', alignItems: 'flex-end', justifyContent: 'space-between', gap: 16, flexWrap: 'wrap' }}>
            <div>
              <div style={{ fontSize: 10, color: 'var(--text-dim, #475569)', fontFamily: 'var(--font-mono, monospace)', letterSpacing: '0.08em' }}>
                MARKETING · CAMPANHAS
              </div>
              <h1 className="font-display" style={{ margin: '6px 0 4px', fontSize: 26, fontWeight: 600, letterSpacing: '-0.015em', color: 'var(--text, #f1f5f9)' }}>
                Campanhas de Conteúdo
              </h1>
              <div style={{ fontSize: 12, color: 'var(--text-muted, #64748b)' }}>
                Geração de conceito, copy e prompts visuais · {kpi.total} campanha{kpi.total !== 1 ? 's' : ''} · {kpi.para_producao} em produção
              </div>
            </div>
            <button onClick={() => setShowModal(true)} className="btn btn-sm btn-primary"
              style={{ display: 'flex', alignItems: 'center', gap: 6, flexShrink: 0 }}>
              <span style={{ fontSize: 16, lineHeight: 1 }}>+</span> Nova Campanha
            </button>
          </div>

          <CampBanner kpi={kpi} onFilter={setFilterCol} />

          {/* Brand tabs */}
          <div style={{ display: 'flex', gap: 4, borderBottom: '1px solid var(--border, #1e293b)' }}>
            {[{ slug: 'all', name: 'Todas' }, ...allBrands].map(b => {
              const active = b.slug === filterBrand;
              return (
                <button key={b.slug} onClick={() => setFilterBrand(b.slug)} style={{
                  background: 'none', border: 'none', outline: 'none',
                  borderBottom: `2px solid ${active ? 'var(--ai-500, #3859D0)' : 'transparent'}`,
                  marginBottom: '-1px',
                  color: active ? 'var(--text, #f1f5f9)' : 'var(--text-muted, #64748b)',
                  fontSize: 13, fontWeight: active ? 600 : 500,
                  fontFamily: 'var(--font-display, Montserrat, sans-serif)', letterSpacing: '.01em',
                  padding: '6px 14px 10px', cursor: 'pointer', whiteSpace: 'nowrap', transition: 'all .15s',
                }}>
                  {b.name}
                </button>
              );
            })}
          </div>

          {/* Filter row */}
          <div style={{ display: 'flex', justifyContent: 'space-between', alignItems: 'center', flexWrap: 'wrap', gap: 8 }}>
            <div style={{ display: 'flex', gap: 6, flexWrap: 'wrap', alignItems: 'center' }}>
              {filterBrand === 'all' && (
                <CampDropdown label="Marca" value={filterBrand} onChange={setFilterBrand}
                  options={[{ value: 'all', label: 'Todas' }, ...allBrands.map(b => ({ value: b.slug, label: b.name }))]}
                />
              )}
              <CampDropdown label="Produto" value={filterProduto} onChange={setFilterProduto}
                options={[{ value: 'all', label: 'Todos' }, ...produtos]}
              />
              {criadores.length > 0 && (
                <CampDropdown label="Criado por" value={filterCriador} onChange={setFilterCriador}
                  options={[{ value: 'all', label: 'Todos' }, ...criadores]}
                />
              )}
              <CampDropdown label="Estado" value={filterCol} onChange={setFilterCol}
                options={[
                  { value: 'all',           label: 'Todos' },
                  { value: 'briefing',      label: 'Briefing' },
                  { value: 'conceito',      label: 'Conceito' },
                  { value: 'copy',          label: 'Copy' },
                  { value: 'para_producao', label: 'Para Produção' },
                ]}
              />
              {hasFilter && (
                <button onClick={() => { setFilterBrand('all'); setFilterCol('all'); setFilterProduto('all'); setFilterCriador('all'); setDateRange({ preset: 'all', start: new Date(new Date().getFullYear(), 0, 1), end: new Date() }); setSearch(''); }}
                  style={{ background: 'none', border: 'none', color: 'var(--text-muted, #64748b)', fontSize: 11, cursor: 'pointer', padding: '4px 6px', fontFamily: 'var(--font-mono, monospace)' }}>
                  ✕ limpar
                </button>
              )}
              <span style={{ fontSize: 12, color: 'var(--text-muted, #64748b)', paddingLeft: 4 }}>
                {filtered.length} resultado{filtered.length !== 1 ? 's' : ''}
              </span>
            </div>
            <CampDateRangePicker value={dateRange} onChange={setDateRange} />
          </div>

        </div>

        {/* KPI strip + Kanban — mesmo grid horizontal */}
        <div style={{ overflowX: 'auto', overflowY: 'visible' }}>
          <div style={{ padding: '18px 32px 32px', minWidth: 640 }}>
            {/* KPI — 4 células alinhadas com as 4 colunas */}
            <div style={{ display: 'flex', gap: 12, marginBottom: 16 }}>
              {kpiCards.map((k, i) => (
                <div key={i} style={{
                  flex: '1 1 0', background: 'var(--bg-elev, #162032)',
                  border: '1px solid var(--border, #1e293b)', borderRadius: 8,
                  padding: '12px 16px 0', display: 'flex', flexDirection: 'column', gap: 4, overflow: 'hidden',
                  animation: 'slide-up 0.25s ease-out both',
                  animationDelay: `${i * 60}ms`,
                  transition: 'border-color 150ms ease, background 150ms ease',
                }}>
                  <div style={{ fontSize: 9.5, fontWeight: 600, letterSpacing: '0.10em', textTransform: 'uppercase', color: 'var(--text-muted, #64748b)', fontFamily: 'var(--font-mono, monospace)', whiteSpace: 'nowrap' }}>{k.label}</div>
                  <div style={{ fontSize: 22, fontWeight: 700, fontFamily: 'var(--font-display, Montserrat, sans-serif)', color: k.accent, lineHeight: 1, paddingBottom: 10 }}>{k.value}</div>
                  <div style={{ height: 3, background: 'var(--bg-sunken, #0f172a)', overflow: 'hidden' }}>
                    <div style={{ height: '100%', width: `${(k.fill || 0) * 100}%`, background: k.accent, transition: 'width .4s' }} />
                  </div>
                </div>
              ))}
            </div>

            {/* Kanban */}
            {campanhas === null ? (
              <div style={{ display: 'flex', gap: 12 }}>
                {KANBAN_COLS.map(col => (
                  <div key={col.id} style={{ flex: '1 1 0' }}>
                    {[1, 2].map(i => <div key={i} style={{ height: 88, borderRadius: 8, background: 'var(--bg-elev, #162032)', marginBottom: 8, opacity: 1 - i * 0.3 }} />)}
                  </div>
                ))}
              </div>
            ) : filtered.length === 0 ? (
              <div style={{ padding: '48px 0', display: 'flex', flexDirection: 'column', alignItems: 'center', gap: 12 }}>
                <div style={{ fontSize: 13, color: 'var(--text-muted, #64748b)', textAlign: 'center' }}>
                  {campanhas.length === 0
                    ? 'Ainda não há campanhas. Aprova um briefing e clica em "+ Criar Campanha" para começar.'
                    : 'Sem resultados para os filtros actuais.'}
                </div>
                {campanhas.length > 0 && (
                  <button onClick={() => { setFilterBrand('all'); setFilterCol('all'); setSearch(''); }}
                    className="btn" style={{ fontSize: 12 }}>
                    Limpar filtros
                  </button>
                )}
              </div>
            ) : (
              <div style={{ display: 'flex', gap: 12 }}>
                {colCards.map(col => (
                  <KanbanColumn
                    key={col.id} col={col} cards={col.cards}
                    onCardClick={setSelected}
                    onEdit={setEditing}
                    onDelete={handleDelete}
                    onDragStart={setDragCard}
                    onDrop={handleDrop}
                    dragCard={dragCard}
                  />
                ))}
              </div>
            )}
          </div>
        </div>

        {toast && (
          <div style={{
            position: 'fixed', bottom: 20, right: 20, zIndex: 9999,
            background: 'var(--bg-elev, #162032)', color: 'var(--text-dim, #475569)',
            border: '1px solid var(--border, #1e293b)',
            padding: '10px 16px', borderRadius: 8, fontSize: 13,
            boxShadow: '0 8px 24px rgba(0,0,0,.3)',
          }}>{toast}</div>
        )}
      </div>

      {editing && (
        <EditTituloModal campanha={editing} onSave={load} onClose={() => setEditing(null)} />
      )}
    </>
  );
};

window.MktCampanhasScreen = MktCampanhasScreen;
// ─── (fim) ───────────────────────────────────────────────────────────────────
