// Tidal — Dashboard (Início) — conectado à API real

const Dashboard = ({state, setState, setPage}) => {
  const toast = useToast();
  const isMobile = useMobile();
  const token = () => localStorage.getItem('genesis_token');

  // ─── Dados reais ───
  const [manifesto, setManifesto] = useState({abordo:[], pendente:[], total_bordo:0});
  const [events, setEvents]       = useState([]);
  const [avisos, setAvisos]       = useState([]);
  const [weekLog, setWeekLog]     = useState([]);
  const [cabins, setCabins]       = useState([]);
  const [loading, setLoading]     = useState(true);

  const fetchAll = async () => {
    try {
      // Guard: o log da gangway exige permissão — sem ela, nem tenta (evita 403 no console)
      const u = state?.currentUser || {};
      const perms = u.permissoes || [];
      const canLog = u.role === 'admin' || u.is_staff === true || perms.some(p => ['gangway.operar','manifesto.gerir'].includes(p));
      const [mRes, eRes, aRes, lRes, cRes] = await Promise.all([
        fetch('/api/boarding/manifesto',  { headers:{'Authorization':`Bearer ${token()}`} }),
        fetch('/api/events',              { headers:{'Authorization':`Bearer ${token()}`} }),
        fetch('/api/announcements',       { headers:{'Authorization':`Bearer ${token()}`} }),
        canLog ? fetch('/api/boarding/log', { headers:{'Authorization':`Bearer ${token()}`} }) : Promise.resolve(null),
        fetch('/api/cabins',              { headers:{'Authorization':`Bearer ${token()}`} }),
      ]);
      if (mRes.ok) setManifesto(await mRes.json());
      if (eRes.ok) setEvents(await eRes.json());
      if (aRes.ok) setAvisos(await aRes.json());
      if (lRes && lRes.ok) setWeekLog(await lRes.json());
      if (cRes.ok) setCabins(await cRes.json());
    } catch(e) { console.error(e); }
    finally { setLoading(false); }
  };

  useEffect(() => { fetchAll(); }, [state?.currentUser?.permissoes]);

  const abordo = manifesto.abordo || [];
  // Admin, crew e is_staff = tripulação; ops sem is_staff = operações; guest = visitantes
  const crew  = abordo.filter(u => u.role === 'crew' || u.role === 'admin' || (u.role === 'ops' && u.is_staff)).length;
  const ops   = abordo.filter(u => u.role === 'ops' && !u.is_staff).length;
  const catering = abordo.filter(u => u.role === 'catering').length;
  const terceirizada = abordo.filter(u => u.role === 'terceirizada').length;
  const guest = abordo.filter(u => u.role === 'guest').length;
  const pob   = abordo.length;
  const capacidade = manifesto.capacidade || pob || 0; // usa capacidade real se disponível

  const today = new Date().toISOString().split('T')[0];
  const upcoming = events.filter(e => (e.data||'').slice(0,10) >= today).slice(0, isMobile ? 2 : 4);
  const avisosRecentes = avisos.slice(0, 3);

  // ─── Movimentação dos últimos 7 dias ───
  const weekMovement = (() => {
    const days = [];
    for (let i = 6; i >= 0; i--) {
      const d = new Date();
      d.setDate(d.getDate() - i);
      const dayStr = d.toDateString();
      const count = weekLog.filter(l => l.created_at && new Date(l.created_at).toDateString() === dayStr).length;
      days.push({ label: d.toLocaleDateString('pt-BR',{weekday:'short'}).slice(0,3), count });
    }
    return days;
  })();
  const maxMov = Math.max(...weekMovement.map(d=>d.count), 1);

  // ─── Ocupação por deck ───
  const deckOccupancy = (() => {
    const decks = {};
    cabins.forEach(c => {
      const deck = String(c.deck || (c.number ? String(c.number).charAt(0) : '?'));
      if (!decks[deck]) decks[deck] = { total: 0, occupied: 0 };
      const total = (c.berths_detail && c.berths_detail.length) || (c.berths && c.berths.length) || 1;
      let occ = (c.occupied != null) ? Number(c.occupied)
        : (c.berths_detail ? c.berths_detail.filter(b => b && b.user_id).length : 0);
      if (!Number.isFinite(occ)) occ = 0;
      decks[deck].total += total;
      decks[deck].occupied += Math.min(occ, total);
    });
    return Object.entries(decks)
      .map(([deck, d]) => ({ deck, ...d }))
      .sort((a, b) => Number(b.deck) - Number(a.deck));
  })();

  // ─── Aniversariantes a bordo (próximos 30 dias) ───
  const birthdays = (() => {
    const now = new Date();
    return abordo
      .filter(u => u.data_nascimento)
      .map(u => {
        const bd = new Date(u.data_nascimento);
        const next = new Date(now.getFullYear(), bd.getMonth(), bd.getDate());
        if (next < now) next.setFullYear(now.getFullYear()+1);
        const days = Math.ceil((next - now) / 86400000);
        return { ...u, daysUntil: days, bdDate: bd };
      })
      .filter(u => u.daysUntil <= 30)
      .sort((a,b) => a.daysUntil - b.daysUntil)
      .slice(0, 4);
  })();

  // Saudação personalizada por hora do dia
  const tt = useT();
  const lang = tt.lang;
  const me = state.currentUser || {};
  const primeiroNome = (me.nome || '').split(' ')[0];
  const hora = new Date().getHours();
  const saudacao = lang==='pt' ? (hora < 12 ? 'Bom dia' : hora < 18 ? 'Boa tarde' : 'Boa noite') : (hora < 12 ? 'Good morning' : hora < 18 ? 'Good afternoon' : 'Good evening');

  return (
    <main style={{padding: isMobile ? '16px 16px 80px' : '30px 36px 56px', flex:1}}>
      {loading ? (
        // Skeleton loaders
        <div style={{display:'grid', gridTemplateColumns: isMobile ? '1fr' : '1.4fr 1fr', gap: isMobile ? 16 : 22}}>
          <div>
            <div style={{height:isMobile?220:300,borderRadius:28,marginBottom:18,background:'linear-gradient(90deg,var(--cream-2) 25%,var(--cream-3) 50%,var(--cream-2) 75%)',backgroundSize:'200% 100%',animation:'shimmer 1.5s infinite'}}/>
            <div style={{height:160,borderRadius:22,background:'linear-gradient(90deg,var(--cream-2) 25%,var(--cream-3) 50%,var(--cream-2) 75%)',backgroundSize:'200% 100%',animation:'shimmer 1.5s infinite'}}/>
          </div>
          <div style={{display:'flex',flexDirection:'column',gap:12}}>
            {[1,2,3].map(i=>(
              <div key={i} style={{height:90,borderRadius:20,background:'linear-gradient(90deg,var(--cream-2) 25%,var(--cream-3) 50%,var(--cream-2) 75%)',backgroundSize:'200% 100%',animation:'shimmer 1.5s infinite'}}/>
            ))}
          </div>
        </div>
      ) : (
      <>
      {/* Saudação */}
      {primeiroNome && (
        <div style={{marginBottom:isMobile?16:22}}>
          <div className="t-eyebrow">{new Date().toLocaleDateString(lang==='pt'?'pt-BR':'en-GB',{weekday:'long',day:'numeric',month:'long'})}</div>
          <h1 style={{fontFamily:'var(--fs)',fontSize:isMobile?28:34,letterSpacing:'-0.7px',lineHeight:1.05,marginTop:6}}>
            {saudacao}, <em style={{fontStyle:'italic',color:'var(--accent)'}}>{primeiroNome}.</em>
          </h1>
        </div>
      )}

      <div style={{display:'grid', gridTemplateColumns: isMobile ? '1fr' : '1.4fr 1fr', gap: isMobile ? 16 : 22}}>
        <div>
          {/* POB hero */}
          <section style={{
            background:'var(--surface)',
            border:'1px solid var(--line-soft)', borderTop:'3px solid var(--accent)', borderRadius:28, padding: isMobile ? '20px 20px' : '30px 32px',
            position:'relative', overflow:'hidden', boxShadow:'var(--shadow-sm)'
          }}>
            <div style={{position:'absolute',top:-40,right:-30,width:180,height:180,borderRadius:'50%',background:'radial-gradient(circle, rgba(217,105,75,0.12) 0%, transparent 70%)'}}/>
            <div className="t-eyebrow" style={{marginBottom:isMobile?10:18}}>{lang==='pt'?'A bordo agora · em tempo real':'Aboard now · real time'}</div>
            <div style={{fontFamily:'var(--fs)',fontSize:isMobile?72:128,fontWeight:400,lineHeight:0.9,letterSpacing:'-4px',position:'relative',color:'var(--accent)'}}>
              <TickNumber value={pob}/>
              {capacidade > 0 && <span style={{fontStyle:'italic',color:'var(--teal)',fontSize:isMobile?24:38,letterSpacing:'-1px',marginLeft:4,fontWeight:400}}>/{capacidade}</span>}
            </div>
            <div style={{fontFamily:'var(--fs)',fontStyle:'italic',fontSize:isMobile?14:18,color:'var(--muted)',marginTop:6}}>
              {pob === 0
                ? (lang==='pt' ? 'nenhuma pessoa a bordo no momento.' : 'nobody aboard right now.')
                : lang==='pt'
                  ? <>são <span style={{color:'var(--ink)',fontStyle:'normal',fontFamily:'var(--f)',fontWeight:500}}>{pob} {pob===1?'pessoa':'pessoas'}</span> dividindo este pedaço de mar com você.</>
                  : <><span style={{color:'var(--ink)',fontStyle:'normal',fontFamily:'var(--f)',fontWeight:500}}>{pob} {pob===1?'person':'people'}</span> sharing this stretch of sea with you.</>
              }
            </div>
            <div style={{display:'flex',gap:isMobile?8:16,marginTop:isMobile?16:24,flexWrap:'wrap'}}>
              {[
                {label:'Tripulação', value:crew,  cls:'crew',  l:'T'},
                {label:'Operações',  value:ops,   cls:'ops',   l:'O'},
                ...(catering>0 ? [{label:'Catering', value:catering, cls:'catering', l:'C'}] : []),
                ...(terceirizada>0 ? [{label:'Terceirizada', value:terceirizada, cls:'terceirizada', l:'Tz'}] : []),
                {label:'Visitantes', value:guest, cls:'guest', l:'V'},
              ].map(r => (
                <div key={r.label} style={{flex:`1 1 ${isMobile?'88px':'104px'}`,minWidth:isMobile?88:104,background:'var(--cream)',borderRadius:16,padding:isMobile?'9px 10px':'12px 13px',border:'1px solid var(--line-soft)',display:'flex',alignItems:'center',gap:isMobile?7:10,overflow:'hidden'}}>
                  <div className={`av av-${isMobile?'sm':'md'} ${r.cls}`} style={{flexShrink:0}}>{r.l}</div>
                  <div style={{minWidth:0}}>
                    <div style={{fontFamily:'var(--fs)',fontSize:isMobile?18:23,lineHeight:1,fontWeight:500}}><TickNumber value={r.value}/></div>
                    <div style={{fontSize:isMobile?9:11,color:'var(--muted)',fontFamily:'var(--fm)',letterSpacing:0.2,marginTop:2,whiteSpace:'nowrap',overflow:'hidden',textOverflow:'ellipsis'}}>{r.label}</div>
                  </div>
                </div>
              ))}
            </div>
          </section>

          {/* Movimentação da semana — dados reais */}
          <div style={{marginTop:isMobile?12:18}}>
            <WeekMovementWidget data={weekMovement} max={maxMov} total={weekMovement.reduce((s,d)=>s+d.count,0)} lang={lang}/>
          </div>

          {/* Avisos recentes */}
          <div style={{marginTop:isMobile?12:22}}>
            <AvisosWidget avisos={avisosRecentes} onMore={()=>setPage('avisos')} lang={lang}/>
          </div>
        </div>

        {/* RIGHT — eventos */}
        <aside style={{display:'flex',flexDirection:'column',gap:10}}>
          <SectionH title="Esta semana" em="juntos." meta={`${upcoming.length} atividade${upcoming.length!==1?'s':''}`}/>
          {upcoming.length === 0 && (
            <div className="empty" style={{padding:'28px 16px',fontSize:14}}>
              nenhum evento agendado para esta semana.
              <div style={{marginTop:10}}>
                <button className="btn btn-primary btn-sm" onClick={()=>setPage('agenda')}>
                  <Icon n="plus" size={12}/>Criar evento
                </button>
              </div>
            </div>
          )}
          {upcoming.map(ev => <EventRow lang={lang} key={ev.id} ev={ev} onClick={()=>setPage('agenda')}/>)}

          {/* Ocupação por deck */}
          {deckOccupancy.length > 0 && <DeckWidget decks={deckOccupancy} onClick={()=>setPage('cabines')}/>}

          {/* Aniversariantes */}
          {birthdays.length > 0 && <BirthdayWidget birthdays={birthdays} lang={lang}/>}

          {abordo.length > 0 && !isMobile && <TurnoWidget abordo={abordo}/>}
        </aside>
      </div>
      </>
      )}
    </main>
  );
};

// ─── WeekMovementWidget — movimentação real dos 7 dias ───
const WeekMovementWidget = ({data, max, total, lang}) => (
  <div style={{background:'var(--surface)',border:'1px solid var(--line-soft)',borderTop:'3px solid var(--accent)',borderRadius:22,padding:'22px 24px',boxShadow:'var(--shadow-sm)'}}>
    <div style={{display:'flex',alignItems:'baseline',justifyContent:'space-between',marginBottom:18}}>
      <div>
        <div className="t-eyebrow">{lang==='pt'?'Movimentação · 7 dias':'Movements · 7 days'}</div>
        <div style={{fontFamily:'var(--fs)',fontSize:28,fontWeight:500,letterSpacing:'-0.6px',marginTop:4}}>
          {total} <em style={{fontStyle:'italic',color:'var(--teal)',fontSize:15,fontWeight:400}}>{lang==='pt'?'passagens':'passages'}</em>
        </div>
      </div>
    </div>
    <div style={{display:'flex',alignItems:'flex-end',gap:8,height:80}}>
      {data.map((d,i)=>(
        <div key={i} style={{flex:1,display:'flex',flexDirection:'column',alignItems:'center',gap:6}}>
          <div style={{
            width:'100%',
            height:`${Math.max((d.count/max)*60, 3)}px`,
            background: d.count > 0 ? 'linear-gradient(180deg, var(--teal), var(--leaf))' : 'var(--cream-3)',
            borderRadius:6,
            transition:'height .4s ease',
            position:'relative'
          }}>
            {d.count > 0 && (
              <div style={{position:'absolute',top:-18,left:0,right:0,textAlign:'center',fontSize:10,fontFamily:'var(--fm)',color:'var(--muted)'}}>
                {d.count}
              </div>
            )}
          </div>
          <div style={{fontSize:10,color:'var(--muted)',fontFamily:'var(--fm)',textTransform:'capitalize'}}>{d.label}</div>
        </div>
      ))}
    </div>
  </div>
);

// ─── DeckWidget — ocupação por deck ───
const DeckWidget = ({decks, onClick}) => (
  <div onClick={onClick} style={{background:'var(--surface)',border:'1px solid var(--line-soft)',borderTop:'3px solid var(--accent)',borderRadius:22,padding:'20px 22px',cursor:'pointer',boxShadow:'var(--shadow-sm)'}}>
    <div className="t-eyebrow" style={{marginBottom:14}}>{useT().lang==='pt'?'Ocupação por deck':'Deck occupancy'}</div>
    <div style={{display:'grid',gap:10}}>
      {decks.map(d=>{
        const pct = d.total > 0 ? Math.round((d.occupied/d.total)*100) : 0;
        return (
          <div key={d.deck}>
            <div style={{display:'flex',justifyContent:'space-between',fontSize:12,marginBottom:4}}>
              <span style={{fontWeight:500}}>Deck {d.deck}</span>
              <span style={{fontFamily:'var(--fm)',color:'var(--muted)',fontSize:11}}>{d.occupied}/{d.total} · {pct}%</span>
            </div>
            <div style={{height:6,background:'var(--cream-3)',borderRadius:4,overflow:'hidden'}}>
              <div style={{
                height:'100%',width:`${Math.min(pct,100)}%`,borderRadius:4,
                background: pct > 85 ? 'var(--coral)' : pct > 60 ? 'var(--sun, #D9A04B)' : 'var(--leaf)',
                transition:'width .5s ease'
              }}/>
            </div>
          </div>
        );
      })}
    </div>
  </div>
);

// ─── BirthdayWidget — aniversariantes a bordo ───
const BirthdayWidget = ({birthdays, lang}) => (
  <div style={{background:'var(--surface)',border:'1px solid var(--line-soft)',borderTop:'3px solid var(--accent)',borderRadius:22,padding:'20px 22px',boxShadow:'var(--shadow-sm)'}}>
    <div className="t-eyebrow" style={{marginBottom:14}}>🎂 {lang==='pt'?'Aniversários a bordo':'Birthdays aboard'}</div>
    <div style={{display:'grid',gap:10}}>
      {birthdays.map(b=>(
        <div key={b.id} style={{display:'flex',alignItems:'center',gap:10}}>
          <Avatar user={b} size="sm"/>
          <div style={{flex:1,minWidth:0}}>
            <div style={{fontSize:13,fontWeight:500,whiteSpace:'nowrap',overflow:'hidden',textOverflow:'ellipsis'}}>{b.nome}</div>
            <div style={{fontSize:11,color:'var(--muted)',fontFamily:'var(--fm)'}}>
              {b.bdDate.toLocaleDateString(lang==='pt'?'pt-BR':'en-GB',{day:'2-digit',month:'long'})}
            </div>
          </div>
          <div style={{
            fontFamily:'var(--fm)',fontSize:11,padding:'3px 10px',borderRadius:20,
            background: b.daysUntil === 0 ? 'var(--accent)' : 'var(--cream)',
            color: b.daysUntil === 0 ? 'white' : 'var(--muted)',
            whiteSpace:'nowrap'
          }}>
            {b.daysUntil === 0 ? (lang==='pt'?'hoje! 🎉':'today! 🎉') : b.daysUntil === 1 ? (lang==='pt'?'amanhã':'tomorrow') : `${b.daysUntil} ${lang==='pt'?'dias':'days'}`}
          </div>
        </div>
      ))}
    </div>
  </div>
);

// ─── Spark — mini gráfico (legado) ───
const Spark = ({label, value, delta, tone, pts, bars}) => {
  const colors = {teal:'var(--teal)', coral:'var(--coral)', leaf:'var(--leaf)'};
  return (
    <div style={{background:'var(--cream)',border:'1px solid var(--line-soft)',borderRadius:18,padding:'16px 18px'}}>
      <div className="t-eyebrow">{label}</div>
      <div style={{fontFamily:'var(--fs)',fontSize:30,fontWeight:500,lineHeight:1,letterSpacing:'-0.6px',marginTop:6}}>
        {value}<em style={{fontStyle:'italic',color:colors[tone],fontSize:14,marginLeft:6,letterSpacing:0,fontWeight:400}}>{delta}</em>
      </div>
      <svg viewBox="0 0 200 32" preserveAspectRatio="none" style={{width:'100%',height:32,marginTop:8}}>
        {bars ? (
          <g fill={colors[tone]}>
            {[20,14,22,8,16,6,12].map((h,i)=>(<rect key={i} x={4+i*30} y={32-h} width={14} height={h} rx={2}/>))}
          </g>
        ) : <polyline fill="none" stroke={colors[tone]} strokeWidth={2} points={pts||'0,16 200,16'}/>}
      </svg>
    </div>
  );
};

// ─── AvisosWidget — avisos reais ───
const AvisosWidget = ({avisos, onMore, lang}) => (
  <div style={{background:'var(--surface)',border:'1px solid var(--line-soft)',borderTop:'3px solid var(--accent)',borderRadius:22,padding:'20px 22px',boxShadow:'var(--shadow-sm)'}}>
    <div style={{display:'flex',alignItems:'center',justifyContent:'space-between',marginBottom:12}}>
      <div className="t-eyebrow">{lang==='pt'?'Avisos':'Announcements'}</div>
      <button className="btn ghost sm" onClick={onMore} style={{fontSize:11,color:'var(--accent)'}}>{lang==='pt'?'ver todos':'view all'}</button>
    </div>
    {avisos.length === 0 && (
      <div style={{fontSize:13,color:'var(--muted)',fontStyle:'italic',fontFamily:'var(--fs)'}}>{lang==='pt'?'nenhum aviso ativo.':'no active announcements.'}</div>
    )}
    {avisos.map((a,i) => (
      <div key={a.id} style={{padding:'10px 0',borderTop:i===0?'none':'1px solid rgba(31,42,46,0.08)',paddingTop:i===0?0:10}}>
        <div style={{fontFamily:'var(--fm)',fontSize:10,letterSpacing:0.8,color:'var(--accent)',textTransform:'uppercase',marginBottom:3}}>
          {a.from_name||'Genesis'} · {new Date(a.created_at).toLocaleDateString('pt-BR')}
        </div>
        <div style={{fontSize:13.5,lineHeight:1.5,color:'var(--ink-2)',fontWeight:500}}>{a.titulo}</div>
        {a.conteudo && <div style={{fontSize:12,color:'var(--muted)',marginTop:2,lineHeight:1.4}}>{a.conteudo.slice(0,80)}{a.conteudo.length>80?'…':''}</div>}
      </div>
    ))}
  </div>
);

// ─── TurnoWidget — distribuição por turno ───
const TurnoWidget = ({abordo}) => {
  const lang = useT().lang;
  const turnos = {};
  abordo.forEach(u => {
    const t = u.turno || 'Não definido';
    turnos[t] = (turnos[t]||0) + 1;
  });
  const entries = Object.entries(turnos).sort((a,b)=>b[1]-a[1]);
  const colors = ['var(--teal)','var(--coral)','var(--leaf)','var(--sun)','var(--sky)','var(--rose)'];
  return (
    <div style={{background:'var(--surface)',border:'1px solid var(--line-soft)',borderTop:'3px solid var(--accent)',borderRadius:22,padding:'20px 22px',marginTop:8,boxShadow:'var(--shadow-sm)'}}>
      <div className="t-eyebrow" style={{marginBottom:14}}>{lang==='pt'?'Distribuição por turno':'Shift distribution'}</div>
      {entries.map(([t,n],i) => (
        <div key={t} style={{display:'flex',alignItems:'center',gap:10,marginBottom:8}}>
          <div style={{width:8,height:8,borderRadius:'50%',background:colors[i%colors.length],flexShrink:0}}/>
          <div style={{flex:1,fontSize:12,fontFamily:'var(--fm)'}}>{t}</div>
          <div style={{width:80,height:6,background:'var(--cream-2)',borderRadius:3,overflow:'hidden'}}>
            <div style={{width:`${n/abordo.length*100}%`,height:'100%',background:colors[i%colors.length],borderRadius:3}}/>
          </div>
          <div style={{fontSize:11,fontFamily:'var(--fm)',color:'var(--muted)',minWidth:20,textAlign:'right'}}>{n}</div>
        </div>
      ))}
    </div>
  );
};

// ─── EventRow — linha de evento real ───
const EventRow = ({ev, onClick, lang}) => {
  const iconMap = {aula:'EN', cinema:'▷', treino:'↗', musica:'♪', outro:'·'};
  const today = new Date().toISOString().split('T')[0];
  const isToday = (ev.data||'').slice(0,10) === today;
  return (
    <div onClick={onClick} style={{
      background:'var(--surface)',border:'1px solid var(--line-soft)',borderTop:'3px solid var(--accent)',borderRadius:18,
      padding:'15px 17px',display:'flex',gap:14,alignItems:'center',
      cursor:'pointer',transition:'all .2s',boxShadow:'var(--shadow-sm)'
    }}
      onMouseEnter={e=>{e.currentTarget.style.transform='translateY(-2px)';e.currentTarget.style.boxShadow='0 12px 32px -16px rgba(31,42,46,0.18)'}}
      onMouseLeave={e=>{e.currentTarget.style.transform='';e.currentTarget.style.boxShadow='var(--shadow-sm)'}}
    >
      <div style={{
        width:46,height:46,borderRadius:13,flexShrink:0,
        background: ev.tipo==='aula'?'var(--sky-soft)':ev.tipo==='cinema'?'rgba(217,105,75,0.14)':ev.tipo==='treino'?'var(--leaf-soft)':'var(--cream-2)',
        color: ev.tipo==='aula'?'var(--teal)':ev.tipo==='cinema'?'var(--accent)':ev.tipo==='treino'?'var(--leaf)':'var(--muted)',
        display:'grid',placeItems:'center',fontFamily:'var(--fs)',fontSize:20,fontStyle:'italic'
      }}>{iconMap[ev.tipo]||'·'}</div>
      <div style={{flex:1,minWidth:0}}>
        <div style={{fontFamily:'var(--fs)',fontSize:16,fontWeight:500,letterSpacing:'-0.3px',lineHeight:1.15}}>{ev.nome}</div>
        <div style={{fontSize:12,color:'var(--muted)',marginTop:3,fontFamily:'var(--fm)',display:'flex',alignItems:'center',gap:8}}>
          <span>{isToday ? (lang==='pt'?'🟢 hoje':'🟢 today') : new Date((ev.data||'').slice(0,10)+'T12:00:00').toLocaleDateString(lang==='pt'?'pt-BR':'en-GB',{weekday:'short',day:'numeric',month:'short'})}</span>
          <span>·</span>
          <span>{ev.horario}</span>
          <span>·</span>
          <span>{(ev.participantes||[]).length} inscritos</span>
        </div>
      </div>
    </div>
  );
};

Object.assign(window, {Dashboard});
