// desktop.jsx — Pastor (desktop) experience: app shell + onboarding workspace.
const { useState, useMemo, useEffect, useRef } = React;

// ── Pilot backend client ─────────────────────────────────────
const PASTOR_TKEY = 'believer_pastor_token';
const api = {
  token: () => localStorage.getItem(PASTOR_TKEY) || '',
  setToken: (t) => t ? localStorage.setItem(PASTOR_TKEY, t) : localStorage.removeItem(PASTOR_TKEY),
  getProfile: () => { try { return JSON.parse(localStorage.getItem('believer_pastor_profile') || 'null'); } catch { return null; } },
  setProfile: (p) => { p ? localStorage.setItem('believer_pastor_profile', JSON.stringify(p)) : localStorage.removeItem('believer_pastor_profile'); window.dispatchEvent(new Event('believer-auth')); },
  headers() { const t = this.token(); return { 'Content-Type': 'application/json', ...(t ? { Authorization: 'Bearer ' + t } : {}) }; },
  _check(r) { if (r.status === 401 && this.token()) { this.setToken(''); this.setProfile(null); } },
  async get(path) { const r = await fetch(path, { headers: this.headers() }); this._check(r); return { ok: r.ok, data: await r.json() }; },
  async post(path, body) { const r = await fetch(path, { method: 'POST', headers: this.headers(), body: JSON.stringify(body || {}) }); this._check(r); return { ok: r.ok, data: await r.json() }; },
  async del(path) { const r = await fetch(path, { method: 'DELETE', headers: this.headers() }); this._check(r); return { ok: r.ok, data: await r.json() }; },
};
// joinBase is resolved from the backend (/api/config) so the QR points at a
// phone-reachable host (LAN IP or PUBLIC_BASE_URL), not localhost.
api.joinBase = location.origin;
api.loadConfig = async () => { try { const r = await api.get('/api/config'); if (r.ok && r.data.joinBase) api.joinBase = r.data.joinBase; } catch {} };
const joinUrl = (code) => `${api.joinBase}/join.html?code=${code}`;

// Načte publikované onboardingy + jejich nováčky jedním paralelním průchodem
// (místo sekvenčních fetchů). Vrací { onboardings, rows } nebo null při chybě.
async function fetchPublishedNewcomers() {
  const { ok, data } = await api.get('/api/onboardings');
  if (!ok) return null;
  const pubs = data.onboardings.filter(o => o.published);
  const lists = await Promise.all(pubs.map(o =>
    api.get(`/api/onboardings/${o.id}/newcomers`)
      .then(r => r.ok ? r.data.newcomers.map(n => ({ ...n, onb: o.name, color: o.color, code: o.shareCode })) : [])
      .catch(() => [])
  ));
  return { onboardings: data.onboardings, rows: lists.flat() };
}

// Build a WhatsApp click-to-chat link from a phone number (+ optional prefilled text).
const waLink = (phone, text) => {
  const digits = String(phone || '').replace(/[^0-9]/g, '');
  return digits ? `https://wa.me/${digits}${text ? '?text=' + encodeURIComponent(text) : ''}` : null;
};
// Build a mailto: link with a friendly prefilled greeting.
const mailtoLink = (email, name) => {
  const first = String(name || '').split(' ')[0];
  const subject = t('Vítej u nás 🙂');
  const body = tf('Ahoj {0},\n\njak se ti daří na tvé cestě? Kdyby cokoliv, klidně se ozvi.\n\nS pozdravem,\ntvůj mentor', first);
  return `mailto:${email}?subject=${encodeURIComponent(subject)}&body=${encodeURIComponent(body)}`;
};

// Prepared messages (work for both WhatsApp and e-mail). {f} = newcomer's first name.
const MSG_TEMPLATES = [
  { key:'uvitani',   label:'Uvítání',              text:(f)=>tf('Ahoj {0}, vítej u nás! Jsme rádi, že ses připojil(a). Kdyby cokoliv, klidně se ozvi. 🙂', f) },
  { key:'povzbuzeni',label:'Povzbuzení',           text:(f)=>tf('Ahoj {0}, jen ti chci říct, že na tebe myslíme a fandíme ti. Drž se! 🙏', f) },
  { key:'skupinka',  label:'Pozvánka na skupinku', text:(f)=>tf('Ahoj {0}, v pátek se schází naše skupinka v 17:00. Budeme rádi, když dorazíš!', f) },
  { key:'pomoc',     label:'Nabídka pomoci',       text:(f)=>tf('Ahoj {0}, můžu ti s něčím pomoct na tvé cestě? Napiš mi, kdykoliv budeš chtít.', f) },
];
// E-mail providers — each opens its own web compose (or the default mail app).
const MAIL_PROVIDERS = [
  { key:'mailto', label:'Výchozí klient' },
  { key:'gmail',  label:'Gmail' },
  { key:'outlook',label:'Outlook' },
  { key:'seznam', label:'Seznam (email.cz)' },
];
const composeUrl = (provider, to, subject, body) => {
  const e = encodeURIComponent;
  if (provider==='gmail')   return `https://mail.google.com/mail/?view=cm&fs=1&to=${e(to)}&su=${e(subject)}&body=${e(body)}`;
  if (provider==='outlook') return `https://outlook.live.com/mail/0/deeplink/compose?to=${e(to)}&subject=${e(subject)}&body=${e(body)}`;
  if (provider==='seznam')  return `https://email.seznam.cz/`;   // Seznam nemá spolehlivý compose s parametry → otevřeme schránku + zkopírujeme text
  return `mailto:${to}?subject=${e(subject)}&body=${e(body)}`;
};

// Contact compose modal — pick a prepared message (+ e-mail provider) then send.
function ContactComposeModal({ newcomer, channel, onClose, toast }) {
  const first = (newcomer.name || '').split(' ')[0];
  const [tpl, setTpl] = useState('uvitani');
  const [msg, setMsg] = useState(MSG_TEMPLATES[0].text(first));
  const [subject, setSubject] = useState(tf('Ahoj {0} 🙂', first));
  const [provider, setProvider] = useState(localStorage.getItem('believer_mail_provider') || 'mailto');
  const isWa = channel === 'whatsapp';
  const pick = (t) => { setTpl(t.key); setMsg(t.text(first)); };
  const send = () => {
    if (isWa) {
      window.open(waLink(newcomer.phone, msg), '_blank');
      window.track && window.track('whatsapp_clicked', { from:'compose', template:tpl });
    } else {
      localStorage.setItem('believer_mail_provider', provider);
      if (provider==='seznam') { try { navigator.clipboard.writeText(subject+'\n\n'+msg); } catch {} toast && toast(t('Zpráva zkopírována — vlož ji v Seznam e-mailu.')); }
      window.open(composeUrl(provider, newcomer.email, subject, msg), '_blank');
      window.track && window.track('email_clicked', { from:'compose', provider, template:tpl });
    }
    onClose();
  };
  return (
    <div className="modal-overlay" onClick={onClose}>
      <div className="modal" onClick={e=>e.stopPropagation()} style={{maxWidth:480}}>
        <div className="modal-head">
          <span className="confirm-ico" style={isWa?{background:'#25D366',color:'#fff'}:{background:'var(--brand-soft)',color:'var(--brand-fg)'}}><Icon name={isWa?'whatsapp':'mail'} size={20} /></span>
          <div style={{flex:1}}><h3>{tf('{0} pro {1}', isWa?'WhatsApp':t('E-mail'), newcomer.name)}</h3><div style={{fontSize:13,color:'var(--text-2)',marginTop:2}}>{isWa? newcomer.phone : newcomer.email}</div></div>
          <button className="modal-x" onClick={onClose}><Icon name="x" size={20} /></button>
        </div>
        <div className="modal-body">
          <div style={{fontSize:12.5,fontWeight:700,color:'var(--text-2)',marginBottom:8}}>{t('Předpřipravená zpráva')}</div>
          <div style={{display:'flex',flexWrap:'wrap',gap:7,marginBottom:14}}>
            {MSG_TEMPLATES.map(tp => (
              <button key={tp.key} className={'chip-btn'+(tpl===tp.key?' on':'')} onClick={()=>pick(tp)}>{t(tp.label)}</button>
            ))}
          </div>
          {!isWa && (
            <>
              <label style={{fontSize:12.5,fontWeight:600,color:'var(--text-2)'}}>{t('Předmět')}</label>
              <input className="input" style={{marginTop:6,marginBottom:12}} value={subject} onChange={e=>setSubject(e.target.value)} />
            </>
          )}
          <label style={{fontSize:12.5,fontWeight:600,color:'var(--text-2)'}}>{t('Zpráva')}</label>
          <textarea className="input" rows={isWa?4:5} style={{marginTop:6}} value={msg} onChange={e=>{setMsg(e.target.value);setTpl('');}} />
          {!isWa && (
            <div style={{marginTop:14}}>
              <label style={{fontSize:12.5,fontWeight:600,color:'var(--text-2)'}}>{t('Odeslat přes')}</label>
              <div style={{display:'flex',flexWrap:'wrap',gap:7,marginTop:7}}>
                {MAIL_PROVIDERS.map(pv => (
                  <button key={pv.key} className={'chip-btn'+(provider===pv.key?' on':'')} onClick={()=>setProvider(pv.key)}>{t(pv.label)}</button>
                ))}
              </div>
            </div>
          )}
        </div>
        <div className="modal-foot">
          <button className="btn btn-ghost" onClick={()=>{ try{ navigator.clipboard.writeText(isWa?msg:(subject+'\n\n'+msg)); toast && toast(t('Zpráva zkopírována do schránky.')); }catch{} }} title={t('Zkopírovat zprávu, kdyby předvyplnění nefungovalo')}><Icon name="copy" />{t('Kopírovat')}</button>
          <div style={{flex:1}} />
          <button className="btn btn-ghost" onClick={onClose}>{t('Zrušit')}</button>
          <button className={'btn '+(isWa?'btn-wa':'btn-primary')} onClick={send}><Icon name={isWa?'whatsapp':'arrowUpRight'} />{isWa?t('Otevřít WhatsApp'):t('Otevřít e-mail')}</button>
        </div>
      </div>
    </div>
  );
}

// One block as seen in the pastor's read-only newcomer detail.
function NcBlock({ b, depth = 0 }) {
  const m = (typeof BLOCK_TYPES !== 'undefined' && BLOCK_TYPES.find(x => x.type === b.type)) || { label: b.type, icon: 'list', color: '#5A6270' };
  const pg = b._progress || {};
  if (b.type === 'task') {
    return (
      <div className={'tstep'+(pg.done?' done':'')} style={{marginLeft:depth?14:0}}>
        <span className="tdot">{pg.done && <Icon name="check" size={11} />}</span>
        <div className="tt">{b.title}</div>
        <div className="td">{pg.done ? t('hotovo') : t('čeká')}</div>
      </div>
    );
  }
  if (b.type === 'choice') {
    const br = (b.branches||[]).find(x => x.id === (pg.answer||''));
    return (
      <div style={{marginLeft:depth?14:0, margin:'10px 0'}}>
        <div style={{display:'flex',alignItems:'center',gap:8,fontSize:13,color:'#7A5CA8',fontWeight:700,marginBottom:6}}><Icon name="signpost" size={15} />{b.title}</div>
        {br
          ? <div style={{fontSize:13,color:'var(--text-2)',marginBottom:8}}>{t('Zvolená cesta:')} <strong style={{color:'var(--text)'}}>{br.label}</strong></div>
          : <div style={{fontSize:13,color:'var(--text-3)',marginBottom:8}}>{t('Zatím si nezvolil(a) cestu.')}</div>}
        {br && (br.blocks||[]).map(sb => <NcBlock key={sb.id} b={sb} depth={depth+1} />)}
      </div>
    );
  }
  if (b.type === 'quiz') {
    const ai = pg.answer!=null && pg.answer!=='' ? Number(pg.answer) : null;
    const ans = ai!=null ? (b.options||[])[ai] : null;
    return (
      <div className="nc-misc">
        <span className="nc-misc-ico" style={{background:m.color}}><Icon name={m.icon} size={13} /></span>
        <div><div className="nc-misc-t">{b.title}</div>
          <div className="nc-misc-s">{ans ? <>{t('Odpověděl(a):')} <strong style={{color:ans.correct?'var(--green)':'var(--red)'}}>{ans.label}</strong> {ans.correct?'✓':'✗'}</> : t('Zatím neodpověděl(a).')}</div>
        </div>
      </div>
    );
  }
  return (
    <div className="nc-misc">
      <span className="nc-misc-ico" style={{background:m.color}}><Icon name={m.icon} size={13} /></span>
      <div><div className="nc-misc-t">{b.title}</div><div className="nc-misc-s">{m.label}</div></div>
    </div>
  );
}

// Pastor's read-only detail of a newcomer (opens on row click).
function RealNewcomerDrawer({ id, onClose, onContact }) {
  const [d, setD] = useState(null);
  const [err, setErr] = useState('');
  useEffect(() => { let on=true; api.get('/api/newcomers/'+id).then(r => { if(!on) return; if(r.ok) setD(r.data); else setErr(r.data.error||t('Nepodařilo se načíst detail.')); }); return ()=>{on=false;}; }, [id]);
  return (
    <>
      <div className="drawer-overlay" onClick={onClose} />
      <div className="drawer">
        {!d && !err && <div style={{padding:40,color:'var(--text-3)'}}>{t('Načítám…')}</div>}
        {err && <div style={{padding:40,color:'var(--text-3)'}}>{err}</div>}
        {d && <>
          <div className="drawer-head">
            <Avatar name={d.name} size={52} />
            <div style={{flex:1,minWidth:0}}>
              <div style={{fontSize:19,fontWeight:700}}>{d.name}</div>
              <div style={{fontSize:13,color:'var(--text-2)',marginTop:2}}>{tf('{0} · připojen(a) {1}', d.onboarding.name, relTime(d.joinedAt))}</div>
              <div style={{fontSize:12.5,color:'var(--text-3)',marginTop:3}}>{[d.phone, d.email].filter(Boolean).join(' · ') || t('bez kontaktu')}</div>
            </div>
            <button className="modal-x" onClick={onClose}><Icon name="x" size={20} /></button>
          </div>
          <div className="drawer-body">
            <div className="card" style={{padding:'16px 18px',marginBottom:20}}>
              <div style={{fontSize:12.5,color:'var(--text-2)',fontWeight:600,marginBottom:8}}>{t('Pokrok onboardingu')}</div>
              <div style={{display:'flex',alignItems:'baseline',gap:6}}><span style={{fontSize:30,fontWeight:800}}>{d.pct}%</span><span style={{color:'var(--text-3)',fontSize:13}}>{tf('{0}/{1} úkolů · aktivní {2}', d.doneTasks, d.totalTasks, relTime(d.lastActive))}</span></div>
              <div className="pbar" style={{marginTop:10}}><i style={{width:d.pct+'%',background:d.pct===100?'var(--green)':'var(--brand)'}}/></div>
              {d.chosenPath && <div style={{display:'flex',alignItems:'center',gap:8,marginTop:12,paddingTop:12,borderTop:'1px solid var(--border)',fontSize:13,color:'var(--text-2)'}}>
                <span className="path-chip" style={{'--pc':d.chosenPath.color||'var(--brand)',marginTop:0}}><Icon name={d.chosenPath.icon||'signpost'} size={12} />{d.chosenPath.label}</span>
                <span>{t('Po uvítací cestě si zvolil(a) tento směr a pokračuje dál.')}</span>
              </div>}
            </div>
            <div className="sr-section-title">{t('Obsah a postup')}</div>
            <div className="tline">
              {d.blocks.map(b => <NcBlock key={b.id} b={b} />)}
            </div>
          </div>
          <div className="drawer-foot">
            {d.phone && <button className="btn btn-wa" style={{flex:1}} onClick={()=>onContact('whatsapp')}><Icon name="whatsapp" />WhatsApp</button>}
            {d.email && <button className="btn btn-primary" style={{flex:1}} onClick={()=>onContact('email')}><Icon name="mail" />{t('E-mail')}</button>}
            {!d.phone && !d.email && <div style={{color:'var(--text-3)',fontSize:13}}>{t('Nováček nezadal kontakt.')}</div>}
          </div>
        </>}
      </div>
    </>
  );
}

// ─────────────────────────────────────────────────────────────
// Sidebar
// ─────────────────────────────────────────────────────────────
const NAV_TOP = [
  { id:'home',     label:'Online nástěnka',     icon:'home' },
  { id:'events',   label:'Události společenství',icon:'calendar' },
  { id:'agenda',   label:'Moje agenda',         icon:'agenda' },
  { id:'planner',  label:'Plánovač událostí',   icon:'planner' },
  { id:'chat',     label:'Konverzace',          icon:'chat' },
  { id:'dary',     label:'Dary',                icon:'gift' },
  { id:'skupiny',  label:'Skupiny',             icon:'groups' },
];
const NAV_GROUPS = [
  { id:'mladez', label:'Mládež', av:'Mládež' },
  { id:'bible',  label:'Skupina na štúdium Biblie', av:'Biblie' },
];
const NAV_SUB = [
  { id:'prehled',     label:'Přehled',          icon:'list' },
  { id:'onboarding',  label:'Onboarding nováčků',icon:'rocket', badge:3 },
  { id:'kontakty',    label:'Kontakty',         icon:'contacts' },
  { id:'finance',     label:'Finanční přehled', icon:'bank' },
  { id:'uzivatele',   label:'Uživatelé',        icon:'users' },
];

function Sidebar({ active, setActive }) {
  const [open, setOpen] = useState(true);
  const Item = ({ id, label, icon, badge, sub }) => (
    <button className={'nav-item'+(active===id?' active':'')+(sub?' nav-sub':'')} onClick={()=>setActive(id)}>
      <Icon name={icon} />
      <span>{label}</span>
      {badge && <span className="nav-badge">{badge}</span>}
    </button>
  );
  return (
    <aside className="sidebar">
      <div className="sb-logo"><img src="assets/logo-combo.png" alt="Believer"/></div>
      <nav className="sb-nav">
        <Item id="onboarding" label={t('Onboarding nováčků')} icon="rocket" badge={3} />
      </nav>
      <div className="sb-foot">{t('Verze: 0.0.5957')}<br/>{t('© 2026 Believer s.r.o. Všechna práva vyhrazena.')}</div>
    </aside>
  );
}

// ─────────────────────────────────────────────────────────────
// Top bar
// ─────────────────────────────────────────────────────────────
// Branded confirmation pop-up (replaces the browser's native confirm()).
function ConfirmDialog({ title, body, confirmLabel = t('Potvrdit'), cancelLabel = t('Zrušit'), danger, icon = 'alert', onConfirm, onClose }) {
  return (
    <div className="modal-overlay" onClick={onClose}>
      <div className="modal" onClick={e=>e.stopPropagation()} style={{maxWidth:430}}>
        <div className="modal-head">
          <span className="confirm-ico" style={danger ? {background:'var(--red-soft)',color:'var(--red)'} : {background:'var(--brand-soft)',color:'var(--brand-fg)'}}><Icon name={icon} size={20} /></span>
          <div style={{flex:1}}><h3>{title}</h3></div>
          <button className="modal-x" onClick={onClose}><Icon name="x" size={20} /></button>
        </div>
        <div className="modal-body"><p style={{margin:0,fontSize:14,color:'var(--text-2)',lineHeight:1.55}}>{body}</p></div>
        <div className="modal-foot">
          <button className="btn btn-ghost" onClick={onClose}>{cancelLabel}</button>
          <button className={'btn '+(danger ? 'btn-danger' : 'btn-primary')} onClick={()=>{ onConfirm(); onClose && onClose(); }}>{confirmLabel}</button>
        </div>
      </div>
    </div>
  );
}

function TopBar({ theme, onTheme }) {
  const [me, setMe] = useState(api.getProfile());
  const [confirmLogout, setConfirmLogout] = useState(false);
  const [admins, setAdmins] = useState(false);
  const [tour, setTour] = useState(false);
  useEffect(() => {
    const h = () => setMe(api.getProfile());
    window.addEventListener('believer-auth', h);
    return () => window.removeEventListener('believer-auth', h);
  }, []);
  // První přihlášení → ukaž krátký průvodce (jen jednou).
  useEffect(() => {
    if (me && api.token() && !localStorage.getItem('believer_tour_done')) setTour(true);
  }, [me]);
  const closeTour = () => { try { localStorage.setItem('believer_tour_done', '1'); } catch (e) {} setTour(false); };
  const name = me?.pastor?.name || 'Matěj Plšek';
  const sub = me?.community ? t('Administrátor') + ' · ' + me.community.name : t('Administrátor') + ' · Cityhouse Brno';
  return (
    <header className="topbar">
      <img className="tb-logo" src="assets/logo-combo.png" alt="Believer" />
      <div className="tb-spacer" />
      <div className="lang-switch" role="group" aria-label={t('Jazyk')}>
        <button className={'lang-opt'+(window.LOCALE!=='en'?' on':'')} onClick={()=>window.setLocale('cs')} title="Čeština" aria-pressed={window.LOCALE!=='en'}>CZ</button>
        <button className={'lang-opt'+(window.LOCALE==='en'?' on':'')} onClick={()=>window.setLocale('en')} title="English" aria-pressed={window.LOCALE==='en'}>EN</button>
      </div>
      {me && <button className="tb-icon" onClick={()=>setTour(true)} title={t('Nápověda — průvodce')}><Icon name="help" /></button>}
      {me && <button className="tb-icon" onClick={()=>setAdmins(true)} title={t('Správci společenství')}><Icon name="users" /></button>}
      <button className="tb-icon" onClick={onTheme} title={t('Přepnout motiv')}><Icon name={theme==='dark'?'sun':'moon'} /></button>
      {me && (
        <div className="tb-user" onClick={()=>setConfirmLogout(true)} style={{cursor:'pointer'}} title={t('Odhlásit se')}>
          <Avatar name={name} size={38} className="av" />
          <div>
            <div className="nm">{name}</div>
            <div className="rl">{sub}<span style={{color:'var(--text-3)'}}> · {t('odhlásit')}</span></div>
          </div>
        </div>
      )}
      {admins && <AdminsModal me={me} onClose={()=>setAdmins(false)} />}
      {tour && <WelcomeTour name={me?.pastor?.name} onClose={closeTour} />}
      {confirmLogout && <ConfirmDialog title={t('Odhlásit se?')} body={tf('Opravdu se chceš odhlásit z účtu {0}?', me.community.name)} confirmLabel={t('Odhlásit se')} icon="user" onConfirm={()=>{ api.setToken(''); api.setProfile(null); location.reload(); }} onClose={()=>setConfirmLogout(false)} />}
    </header>
  );
}

// ── Jednoduchý uvítací průvodce (první přihlášení) ────────────
function WelcomeTour({ name, onClose }) {
  const [i, setI] = useState(0);
  const first = (name || '').split(' ')[0];
  const steps = [
    { icon: 'rocket', title: tf('Vítej v Believeru{0} 👋', first ? ', ' + first : ''),
      body: t('Tady provedeš nové lidi ve svém společenství krok za krokem — od přivítání po zapojení. Ukážeme ti to ve třech krocích.') },
    { icon: 'layers', title: t('1. Sestav cestu v Šablonách'),
      body: t('V záložce Šablony poskládáš uvítací cestu z bloků — text, video, kvíz, odkaz i rozcestník. Rozděl ji na části, ať má nováček přehled.') },
    { icon: 'arrowUpRight', title: t('2. Publikuj a sdílej QR'),
      body: t('Až bude cesta hotová, publikuj ji a sdílej QR kód nebo krátký kód. (Stačí mít ověřený e-mail — odkaz najdeš v poště.)') },
    { icon: 'users', title: t('3. Sleduj nováčky'),
      body: t('V Přehledu nováčků vidíš živě, kdo postupuje a kdo se zasekl. V Analytice máš report pro vedení, v Připomínkách koho povzbudit.') },
  ];
  const last = i === steps.length - 1;
  const s = steps[i];
  return (
    <div className="modal-overlay" onClick={onClose}>
      <div className="modal" onClick={e=>e.stopPropagation()} style={{maxWidth:440}}>
        <div className="modal-body" style={{textAlign:'center',padding:'30px 28px 24px'}}>
          <div style={{width:64,height:64,borderRadius:18,background:'var(--brand-soft)',color:'var(--brand-fg)',display:'flex',alignItems:'center',justifyContent:'center',margin:'0 auto 18px'}}><Icon name={s.icon} size={30} /></div>
          <h3 style={{fontSize:20,margin:'0 0 10px'}}>{s.title}</h3>
          <p style={{fontSize:14,color:'var(--text-2)',lineHeight:1.6,margin:0}}>{s.body}</p>
          <div style={{display:'flex',justifyContent:'center',gap:7,margin:'22px 0 4px'}}>
            {steps.map((_,k)=><span key={k} style={{width:k===i?22:8,height:8,borderRadius:99,background:k===i?'var(--brand)':'var(--border-2)',transition:'.2s'}}/>)}
          </div>
        </div>
        <div className="modal-foot" style={{justifyContent:'space-between'}}>
          <button className="btn btn-ghost" onClick={onClose}>{t('Přeskočit')}</button>
          <div style={{display:'flex',gap:8}}>
            {i>0 && <button className="btn btn-ghost" onClick={()=>setI(i-1)}>{t('Zpět')}</button>}
            <button className="btn btn-primary" onClick={()=>last?onClose():setI(i+1)}>{last?t('Jdeme na to'):t('Dál')}</button>
          </div>
        </div>
      </div>
    </div>
  );
}

// ── Správci společenství (více administrátorů) ────────────────
function AdminsModal({ me, onClose }) {
  const [data, setData] = useState(null);
  const [email, setEmail] = useState('');
  const [busy, setBusy] = useState(false);
  const [msg, setMsg] = useState('');
  const [err, setErr] = useState('');
  const [remove, setRemove] = useState(null);
  const myId = me?.pastor?.id;

  const load = async () => { const r = await api.get('/api/admins'); if (r.ok) setData(r.data); };
  useEffect(() => { load(); }, []);

  const invite = async () => {
    setErr(''); setMsg('');
    const e = email.trim();
    if (!/^[^@\s]+@[^@\s]+\.[^@\s]+$/.test(e)) { setErr(t('Zadej platný e-mail.')); return; }
    setBusy(true);
    const r = await api.post('/api/admins/invite', { email: e });
    setBusy(false);
    if (r.ok) { setEmail(''); setMsg(tf('Pozvánka odeslána na {0}.', e)); load(); window.track && window.track('admin_invited', {}); }
    else setErr(r.data.error || t('Pozvánku se nepodařilo odeslat.'));
  };
  const doRemove = async (a) => {
    const r = await api.del('/api/admins/' + a.id);
    if (r.ok) { if (r.data.removedSelf) { api.setToken(''); api.setProfile(null); location.reload(); return; } load(); }
    else setErr(r.data.error || t('Odebrání se nepovedlo.'));
  };
  const cancelInvite = async (em) => {
    setErr(''); setMsg('');
    const r = await api.del('/api/admins/invite/' + encodeURIComponent(em));
    if (r.ok) load(); else setErr(r.data.error || t('Zrušení se nepovedlo.'));
  };

  return (
    <div className="modal-overlay" onClick={onClose}>
      <div className="modal" onClick={e=>e.stopPropagation()} style={{maxWidth:460}}>
        <div className="modal-head">
          <span className="confirm-ico" style={{background:'var(--brand-soft)',color:'var(--brand-fg)'}}><Icon name="users" size={20} /></span>
          <div style={{flex:1}}><h3>{t('Správci společenství')}</h3><div style={{fontSize:13,color:'var(--text-2)',marginTop:2}}>{t('Spravujte onboarding ve více lidech.')}</div></div>
          <button className="modal-x" onClick={onClose}><Icon name="x" size={20} /></button>
        </div>
        <div className="modal-body">
          {!data ? <div style={{color:'var(--text-3)',padding:'10px 0'}}>{t('Načítám…')}</div> : <>
            {data.admins.map(a => (
              <div key={a.id} className="admin-row">
                <Avatar name={a.name} size={38} />
                <div style={{flex:1,minWidth:0}}>
                  <div style={{fontWeight:700,fontSize:14}}>{a.name}{a.isMe && <span style={{color:'var(--text-3)',fontWeight:400}}> · {t('to jsi ty')}</span>}</div>
                  <div style={{fontSize:12.5,color:'var(--text-3)'}}>{a.email}{!a.emailVerified && <span style={{color:'var(--amber)'}}> · {t('neověřeno')}</span>}</div>
                </div>
                {data.admins.length > 1 && <button className="btn btn-subtle btn-sm icon-btn" title={a.isMe ? t('Opustit společenství') : t('Odebrat správce')} onClick={()=>setRemove(a)}><Icon name="trash" /></button>}
              </div>
            ))}
            {data.pending.map(p => (
              <div key={p.email} className="admin-row">
                <span className="confirm-ico" style={{width:38,height:38,background:'var(--amber-soft)',color:'var(--amber)'}}><Icon name="mail" size={18} /></span>
                <div style={{flex:1,minWidth:0}}><div style={{fontWeight:700,fontSize:14}}>{p.email}</div><div style={{fontSize:12.5,color:'var(--text-3)'}}>{t('Pozvánka odeslána — čeká na přijetí')}</div></div>
                <button className="btn btn-subtle btn-sm icon-btn" title={t('Zrušit pozvánku')} onClick={()=>cancelInvite(p.email)}><Icon name="trash" /></button>
              </div>
            ))}
            <div style={{borderTop:'1px solid var(--border)',marginTop:14,paddingTop:16}}>
              <label style={{fontSize:12.5,fontWeight:600,color:'var(--text-2)'}}>{t('Pozvat dalšího správce')}</label>
              <div style={{display:'flex',gap:8,marginTop:7}}>
                <input className="input" style={{flex:1}} type="email" placeholder={t('vas@email.cz')} value={email} onChange={e=>setEmail(e.target.value)} onKeyDown={e=>e.key==='Enter'&&invite()} />
                <button className="btn btn-primary" disabled={busy} onClick={invite}><Icon name="mail" />{busy?'…':t('Pozvat')}</button>
              </div>
              <div style={{fontSize:12,color:'var(--text-3)',marginTop:7,lineHeight:1.45}}>{t('Pošleme mu e-mailem odkaz, kde si nastaví jméno a heslo. Pak má plný přístup ke správě.')}</div>
              {msg && <div style={{background:'var(--green-soft)',color:'var(--green)',borderRadius:8,padding:'9px 12px',fontSize:13,marginTop:10}}>{msg}</div>}
              {err && <div style={{background:'var(--red-soft)',color:'var(--red)',borderRadius:8,padding:'9px 12px',fontSize:13,marginTop:10}}>{err}</div>}
            </div>
          </>}
        </div>
      </div>
      {remove && <ConfirmDialog danger icon="trash"
        title={remove.id===myId ? t('Opustit společenství?') : t('Odebrat správce?')}
        body={remove.id===myId ? t('Přijdeš o přístup ke správě tohoto společenství. Pokračovat?') : tf('Opravdu odebrat správce „{0}"? Ztratí přístup ke správě.', remove.name)}
        confirmLabel={remove.id===myId ? t('Opustit') : t('Odebrat')}
        onConfirm={()=>doRemove(remove)} onClose={()=>setRemove(null)} />}
    </div>
  );
}

// ─────────────────────────────────────────────────────────────
// Banner: výzva k ověření e-mailu (dokud není potvrzený)
// ─────────────────────────────────────────────────────────────
function VerifyBanner({ toast }) {
  const [me, setMe] = useState(api.getProfile());
  const [sending, setSending] = useState(false);
  useEffect(() => {
    const h = () => setMe(api.getProfile());
    window.addEventListener('believer-auth', h);
    // Po návratu z ověřovacího e-mailu si stav obnovíme ze serveru.
    if (api.token()) api.get('/api/me').then(r => {
      if (r.ok) { const cur = api.getProfile() || {}; api.setProfile({ ...cur, pastor: { ...cur.pastor, ...r.data.pastor }, community: r.data.community }); }
    });
    return () => window.removeEventListener('believer-auth', h);
  }, []);
  if (!me?.pastor || me.pastor.emailVerified !== false) return null;
  const email = me.pastor.email;
  const resend = async () => {
    setSending(true);
    const r = await api.post('/api/resend-verification', {});
    setSending(false);
    if (r.ok) toast(r.data.alreadyVerified ? t('E-mail je už ověřený.') : t('Ověřovací e-mail jsme poslali znovu.'));
    else toast(t('E-mail se nepodařilo odeslat. Zkuste to za chvíli.'));
  };
  return (
    <div className="verify-banner">
      <span className="vb-badge"><Icon name="alert" size={15} /> {t('Neověřeno')}</span>
      <span className="vb-text">{t('Nejdřív prosím ověřte svůj e-mail')}{email ? ' ' : ''}<strong>{email}</strong> — {t('poslali jsme vám potvrzovací odkaz.')}</span>
      <button className="vb-btn" onClick={resend} disabled={sending}>{sending ? t('Odesílám…') : t('Poslat znovu')}</button>
    </div>
  );
}

// ─────────────────────────────────────────────────────────────
// Placeholder for non-onboarding nav items
// ─────────────────────────────────────────────────────────────
function Placeholder({ label }) {
  return (
    <div className="page-wrap" style={{display:'flex',flexDirection:'column',alignItems:'center',justifyContent:'center',textAlign:'center',padding:'90px 0',color:'var(--text-3)'}}>
      <div style={{width:74,height:74,borderRadius:18,background:'var(--surface-2)',display:'flex',alignItems:'center',justifyContent:'center',marginBottom:18,color:'var(--text-3)'}}>
        <Icon name="eye" size={34} />
      </div>
      <h2 style={{margin:'0 0 8px',color:'var(--text-2)',fontSize:20}}>{label}</h2>
      <p style={{margin:0,maxWidth:380,lineHeight:1.5}}>{t('Tato sekce není součástí prototypu onboardingu. Otevři')} <strong style={{color:'var(--brand-fg)'}}>{t('Onboarding nováčků')}</strong> {t('v levém menu.')}</p>
    </div>
  );
}

// ─────────────────────────────────────────────────────────────
// Onboarding workspace
// ─────────────────────────────────────────────────────────────
const OB_TABS = [
  { id:'dashboard',  label:'Přehled nováčků', icon:'users' },
  { id:'templates',  label:'Šablony',         icon:'layers' },
  { id:'analytics',  label:'Analytika',       icon:'chart' },
  { id:'reminders',  label:'Připomínky',      icon:'bell' },
];

// First-run welcome — new visitors register before they see the workspace.
function WelcomeGate({ onRegister, onLogin }) {
  const points = [
    { icon:'layers', title:t('Sestav onboarding'), text:t('Poskládej video, text, kvíz, úkol nebo rozcestník.') },
    { icon:'signpost', title:t('Sdílej přes QR'), text:t('Nováčci se připojí naskenováním kódu.') },
    { icon:'chart', title:t('Sleduj pokrok'), text:t('Vidíš živě, kdo postupuje a koho povzbudit.') },
  ];
  return (
    <div className="welcome">
      <div className="welcome-card">
        <img className="welcome-logo" src="assets/logo-mark.png" alt="" />
        <h1>{t('Vítej v onboardingu Believer')}</h1>
        <p className="welcome-lead">{t('Provázej nové lidi ve vašem společenství krok za krokem — od prvního přivítání až po zapojení. Začni založením svého společenství.')}</p>
        <div className="welcome-points">
          {points.map(p => (
            <div className="welcome-point" key={p.icon}>
              <span className="welcome-pico"><Icon name={p.icon} size={20} /></span>
              <div><div className="welcome-pt">{p.title}</div><div className="welcome-ptxt">{p.text}</div></div>
            </div>
          ))}
        </div>
        <button className="btn btn-primary welcome-cta" onClick={onRegister}><Icon name="community" />{t('Vytvořit společenství')}</button>
        <div className="welcome-login">{t('Už máš účet?')} <button onClick={onLogin}>{t('Přihlásit se')}</button></div>
      </div>
      <div className="welcome-note">{t('Po založení máš prostředí prázdné a připravíme ti jednu')} <strong>{t('ukázkovou šablonu')}</strong>{t(', ať vidíš, jak to funguje.')}</div>
    </div>
  );
}

function Onboarding({ toast }) {
  const [tab, setTab] = useState('dashboard');
  const [drawer, setDrawer] = useState(null);
  const [contact, setContact] = useState(null);
  const [login, setLogin] = useState(false);
  const [authTick, setAuthTick] = useState(0);
  const [idleCount, setIdleCount] = useState(0);
  const [authed, setAuthed] = useState(!!api.token());

  useEffect(() => { setAuthed(!!api.token()); }, [authTick]);
  useEffect(() => { const h = () => setAuthed(!!api.token()); window.addEventListener('believer-auth', h); return () => window.removeEventListener('believer-auth', h); }, []);

  // Live count of newcomers idle 7+ days — drives the Připomínky badge.
  useEffect(() => {
    let alive = true;
    const tick = async () => {
      if (document.hidden || !api.token()) { if (!api.token() && alive) setIdleCount(0); return; }
      const res = await fetchPublishedNewcomers();
      if (!res || !alive) return;
      const n = res.rows.filter(x => x.pct < 100 && (Date.now()-new Date(x.lastActive).getTime())/86400000 >= 7).length;
      if (alive) setIdleCount(c => c === n ? c : n);
    };
    tick(); const id = setInterval(tick, 15000);
    const h = () => tick();
    window.addEventListener('believer-auth', h);
    return () => { alive = false; clearInterval(id); window.removeEventListener('believer-auth', h); };
  }, [authTick]);
  if (!authed) {
    return (
      <div className="page-wrap">
        <WelcomeGate onRegister={()=>setLogin('register')} onLogin={()=>setLogin('login')} />
        {login && <LoginModal startMode={login} onClose={()=>setLogin(false)} onDone={()=>{ setLogin(false); setAuthTick(t=>t+1); }} toast={toast} />}
      </div>
    );
  }
  return (
    <div className="page-wrap">
      <div className="page-head">
        <div>
          <h1>{t('Onboarding nováčků')}</h1>
          <p>{t('Sledujte, jak se noví lidé v')} <strong>{(api.getProfile()?.community?.name) || t('vašem společenství')}</strong> {t('zabydlují — kdo postupuje, kdo se zasekl a koho je dobré povzbudit.')}</p>
        </div>
      </div>
      <div className="subtabs">
        {OB_TABS.map(tb => {
          const badge = tb.id==='reminders' ? idleCount : 0;
          return (
            <button key={tb.id} className={'subtab'+(tab===tb.id?' on':'')} onClick={()=>setTab(tb.id)}>
              <Icon name={tb.icon} />{t(tb.label)}
              {badge>0 && <span className="nav-badge" style={{marginLeft:2}}>{badge}</span>}
            </button>
          );
        })}
      </div>
      {tab==='dashboard' && <Dashboard onOpen={setDrawer} onContact={setContact} onLogin={()=>setLogin('login')} onRegister={()=>setLogin('register')} onGoTemplates={()=>setTab('templates')} toast={toast} authTick={authTick} />}
      {tab==='templates' && <Templates toast={toast} onLogin={()=>setLogin('login')} onRegister={()=>setLogin('register')} authTick={authTick} />}
      {tab==='analytics' && <Analytics toast={toast} authTick={authTick} />}
      {tab==='reminders' && <Reminders onContact={setContact} toast={toast} authTick={authTick} />}

      {drawer && <NewcomerDrawer person={drawer} onClose={()=>setDrawer(null)} onContact={setContact} />}
      {contact && <ContactModal person={contact} onClose={()=>setContact(null)} toast={toast} />}
      {login && <LoginModal startMode={login} onClose={()=>setLogin(false)} onDone={()=>{ setLogin(false); setAuthTick(t=>t+1); }} toast={toast} />}
    </div>
  );
}

// ── Live pilot newcomers (real data from backend, polled) ────
function relTime(iso) {
  if (!iso) return '';
  const diff = (Date.now() - new Date(iso).getTime()) / 1000;
  if (diff < 60) return t('právě teď');
  if (diff < 3600) return tf('před {0} min', Math.floor(diff/60));
  if (diff < 86400) return tf('před {0} h', Math.floor(diff/3600));
  return tf('před {0} dny', Math.floor(diff/86400));
}
function LiveNewcomers({ onLogin, onRegister, authTick }) {
  const [token, setTok] = useState(api.token());
  const [rows, setRows] = useState([]);
  const [loaded, setLoaded] = useState(false);

  useEffect(() => { setTok(api.token()); }, [authTick]);

  const sigRef = useRef('');
  useEffect(() => {
    if (!token) return;
    let alive = true;
    const tick = async () => {
      if (document.hidden) return;
      const res = await fetchPublishedNewcomers();
      if (!res || !alive) return;
      res.rows.sort((a,b)=> new Date(b.lastActive)-new Date(a.lastActive));
      const sig = JSON.stringify(res.rows);
      if (sig === sigRef.current) { if (!loaded) setLoaded(true); return; }
      sigRef.current = sig;
      setRows(res.rows); setLoaded(true);
    };
    tick();
    const id = setInterval(tick, 6000);
    const onVis = () => { if (!document.hidden) tick(); };
    document.addEventListener('visibilitychange', onVis);
    return () => { alive = false; clearInterval(id); document.removeEventListener('visibilitychange', onVis); };
  }, [token]);

  if (!token) {
    return (
      <div className="live-panel" style={{display:'flex',alignItems:'center',gap:14}}>
        <span className="live-ico"><Icon name="phone" size={20} /></span>
        <div style={{flex:1}}>
          <div style={{fontWeight:700,fontSize:14.5}}>{t('Živí nováčci z QR kódu')}</div>
          <div style={{fontSize:13,color:'var(--text-2)'}}>{t('Vytvoř si společenství a publikuj onboarding v záložce')} <strong>{t('Šablony')}</strong> {t('— kdo se připojí přes QR, objeví se tady živě.')}</div>
        </div>
        <button className="btn btn-ghost btn-sm" onClick={onLogin}><Icon name="user" />{t('Přihlásit')}</button>
        <button className="btn btn-primary btn-sm" onClick={onRegister}><Icon name="community" />{t('Vytvořit společenství')}</button>
      </div>
    );
  }
  return (
    <div className="live-panel">
      <div style={{display:'flex',alignItems:'center',gap:9,marginBottom: rows.length?12:0}}>
        <span className="live-dot" /><span style={{fontWeight:700,fontSize:14}}>{t('Živí nováčci z QR')}</span>
        <span style={{fontSize:12,color:'var(--text-3)'}}>· {t('aktualizuje se automaticky')}</span>
        <span style={{marginLeft:'auto',fontSize:12,color:'var(--text-3)'}}>{tf('{0} připojeno', rows.length)}</span>
      </div>
      {loaded && rows.length===0 && <div style={{fontSize:13,color:'var(--text-2)'}}>{t('Zatím se nikdo nepřipojil. Sdílej QR kód z onboardingu a sleduj, jak tu přibývají. 🙂')}</div>}
      <div className="live-grid">
        {rows.map(n => (
          <div className="live-card" key={n.id}>
            <Avatar name={n.name} size={38} />
            <div style={{flex:1,minWidth:0}}>
              <div style={{fontWeight:700,fontSize:14}}>{n.name}</div>
              <div style={{fontSize:11.5,color:'var(--text-3)'}}>{n.onb} · {relTime(n.joinedAt)}</div>
              <div className="pbar" style={{marginTop:6}}><i style={{width:n.pct+'%',background:n.pct===100?'var(--green)':'var(--brand)'}}/></div>
            </div>
            <div style={{textAlign:'right'}}>
              <div style={{fontWeight:800,fontSize:15}}>{n.pct}%</div>
              <div style={{fontSize:11,color:'var(--text-3)'}}>{n.doneTasks}/{n.totalTasks}</div>
            </div>
          </div>
        ))}
      </div>
    </div>
  );
}

// ── Dashboard switch: real data when logged in, demo otherwise ─
function Dashboard(props) {
  const [tok, setTok] = useState(api.token());
  useEffect(() => { setTok(api.token()); }, [props.authTick]);
  useEffect(() => { const h = () => setTok(api.token()); window.addEventListener('believer-auth', h); return () => window.removeEventListener('believer-auth', h); }, []);
  return tok ? <RealDashboard {...props} /> : <DemoDashboard {...props} />;
}

// Cache poslední načtené dashboardové sady — přežije přepnutí záložek, takže se
// při návratu nezobrazí prázdný stav, než dorazí čerstvá data (žádné problikávání).
let _dashCache = null;
// ── Real dashboard (live backend data for the logged-in account) ─
function RealDashboard({ onContact, onGoTemplates, toast, authTick }) {
  const [obs, setObs] = useState(_dashCache?.obs || []);
  const [rows, setRows] = useState(_dashCache?.rows || []);
  const [loaded, setLoaded] = useState(!!_dashCache);
  const [q, setQ] = useState('');
  const [del, setDel] = useState(null);
  const [compose, setCompose] = useState(null);
  const [detail, setDetail] = useState(null);
  const [tick0, setTick0] = useState(0);

  const sigRef = useRef('');
  useEffect(() => {
    let alive = true;
    const tick = async () => {
      if (document.hidden) return;                       // neběhej, když je záložka skrytá
      const res = await fetchPublishedNewcomers();
      if (!res || !alive) return;
      res.rows.sort((a,b)=> new Date(b.lastActive)-new Date(a.lastActive));
      const sig = JSON.stringify(res);
      if (sig === sigRef.current) { if (!loaded) setLoaded(true); return; }  // beze změny → nepřekresluj
      sigRef.current = sig;
      setObs(res.onboardings); setRows(res.rows); setLoaded(true);
      _dashCache = { obs: res.onboardings, rows: res.rows };
    };
    tick(); const id = setInterval(tick, 6000);
    const onVis = () => { if (!document.hidden) tick(); };
    document.addEventListener('visibilitychange', onVis);
    return () => { alive = false; clearInterval(id); document.removeEventListener('visibilitychange', onVis); };
  }, [authTick, tick0]);

  const deleteNewcomer = async (n) => {
    const { ok } = await api.del('/api/newcomers/' + n.id);
    if (ok) { setRows(r => r.filter(x => x.id !== n.id)); toast && toast(tf('Nováček „{0}" odebrán.', n.name)); window.track && window.track('newcomer_deleted', {}); }
    else toast && toast(t('Smazání se nepovedlo.'));
  };

  const idleOf = (n) => (Date.now()-new Date(n.lastActive).getTime())/86400000 >= 7;
  const filtered = rows.filter(n => n.name.toLowerCase().includes(q.toLowerCase()));
  const avg = rows.length ? Math.round(rows.reduce((a,n)=>a+n.pct,0)/rows.length) : 0;
  const chips = [
    { k:'avg',  label:t('Průměrné dokončení'), val:avg+' %', icon:'chart', c:'var(--brand-soft)', fg:'var(--brand-fg)' },
    { k:'act',  label:t('Aktivních nováčků'),  val:rows.length, icon:'users', c:'var(--sky-soft)', fg:'var(--brand-fg)' },
    { k:'done', label:t('Dokončili cestu'),    val:rows.filter(n=>n.pct===100).length, icon:'trophy', c:'var(--green-soft)', fg:'var(--green)' },
    { k:'idle', label:t('Bez aktivity'),       val:rows.filter(idleOf).length, icon:'alert', c:'var(--amber-soft)', fg:'var(--amber)' },
  ];

  if (loaded && rows.length === 0) {
    return (
      <div className="page-wrap" style={{display:'flex',flexDirection:'column',alignItems:'center',textAlign:'center',padding:'70px 0',color:'var(--text-3)'}}>
        <img src="assets/dove-standing.png" alt="" style={{height:96,marginBottom:18,opacity:.95}} />
        <h2 style={{margin:'0 0 8px',color:'var(--text-2)',fontSize:21}}>{t('Zatím tu nikdo není')}</h2>
        <p style={{margin:'0 0 20px',maxWidth:420,lineHeight:1.55}}>{t('Vytvoř si onboarding v záložce')} <strong style={{color:'var(--brand-fg)'}}>{t('Šablony')}</strong>{t(', publikuj ho a sdílej QR kód. Jakmile se někdo připojí, objeví se tady — naživo.')}</p>
        <button className="btn btn-primary" onClick={onGoTemplates}><Icon name="layers" />{t('Vytvořit onboarding')}</button>
      </div>
    );
  }

  return (
    <>
      <div className="stat-grid">
        {chips.map(s => (
          <div className="stat card" key={s.k}>
            <div style={{display:'flex',justifyContent:'space-between',alignItems:'flex-start'}}>
              <div><div className="s-label">{s.label}</div><div className="s-val">{s.val}</div></div>
              <div className="s-ico" style={{background:s.c,color:s.fg}}><Icon name={s.icon} size={19} /></div>
            </div>
          </div>
        ))}
      </div>
      <div className="filterbar">
        <div className="search-wrap"><Icon name="search" /><input className="search" placeholder={t('Hledat nováčka…')} value={q} onChange={e=>setQ(e.target.value)} /></div>
        <div style={{display:'flex',alignItems:'center',gap:7,color:'var(--text-3)',fontSize:13,fontWeight:600}}><span className="live-dot" />{t('živě')}</div>
        <div style={{marginLeft:'auto',alignSelf:'center',color:'var(--text-3)',fontSize:13,fontWeight:600}}>{tf('{0} nováčků', filtered.length)}</div>
      </div>
      <div className="card">
        <div className="nrow nrow-head"><div>{t('Nováček')}</div><div>{t('Postup checklistu')}</div><div>{t('Stav')}</div><div style={{textAlign:'right'}}>{t('Akce')}</div></div>
        {filtered.map(n => {
          const idle = idleOf(n), done = n.pct===100;
          return (
            <div className="nrow nrow-click" key={n.id} onClick={()=>setDetail(n)} title={t('Zobrazit detail nováčka')}>
              <div className="person">
                <Avatar name={n.name} size={42} />
                <div className="meta"><div className="nm">{n.name}</div><div className="sub">{tf('{0} · připojen(a) {1}', n.onb, relTime(n.joinedAt))}</div></div>
              </div>
              <div>
                <div style={{display:'flex',alignItems:'center',gap:10}}>
                  <div className="pbar" style={{flex:1}}><i style={{width:n.pct+'%',background:idle?'var(--amber)':done?'var(--green)':'var(--brand)'}}/></div>
                  <span className="pct" style={{minWidth:38,textAlign:'right'}}>{n.pct}%</span>
                </div>
                <div style={{fontSize:11.5,color:'var(--text-3)',marginTop:4}}>{tf('{0}/{1} úkolů', n.doneTasks, n.totalTasks)}</div>
              </div>
              <div>
                <span className={'chip '+(done?'done':idle?'idle':'prog')}><Icon name={done?'checkCircle':idle?'clock':'flame'} />{done?t('Dokončeno'):idle?t('Bez aktivity'):t('Probíhá')}</span>
                {n.chosenPath && <div className="path-chip" style={{'--pc':n.chosenPath.color||'var(--brand)'}} title={tf('Po dokončení uvítací cesty si zvolil(a) směr: {0}', n.chosenPath.label)}><Icon name={n.chosenPath.icon||'signpost'} size={12} />{tf('Směřuje: {0}', n.chosenPath.label)}</div>}
                <div style={{fontSize:11.5,color:'var(--text-3)',marginTop:5}}>{tf('aktivní {0}', relTime(n.lastActive))}</div>
              </div>
              <div style={{display:'flex',gap:8,justifyContent:'flex-end',alignItems:'center'}} onClick={e=>e.stopPropagation()}>
                {n.phone && <button className="btn btn-wa btn-sm" onClick={()=>setCompose({newcomer:n,channel:'whatsapp'})} title={tf('WhatsApp: {0}', n.phone)}><Icon name="whatsapp" />WhatsApp</button>}
                {n.email && <button className="btn btn-ghost btn-sm" onClick={()=>setCompose({newcomer:n,channel:'email'})} title={tf('E-mail: {0}', n.email)}><Icon name="mail" />{t('E-mail')}</button>}
                {!n.phone && !n.email && <span style={{fontSize:12,color:'var(--text-3)',alignSelf:'center'}}>{t('bez kontaktu')}</span>}
                <button className="btn btn-subtle btn-sm icon-btn" onClick={()=>setDel(n)} title={t('Odebrat nováčka')}><Icon name="trash" /></button>
              </div>
            </div>
          );
        })}
        {filtered.length===0 && <div style={{padding:'40px',textAlign:'center',color:'var(--text-3)'}}>{t('Žádný nováček neodpovídá hledání.')}</div>}
      </div>
      {compose && <ContactComposeModal newcomer={compose.newcomer} channel={compose.channel} onClose={()=>setCompose(null)} toast={toast} />}
      {detail && <RealNewcomerDrawer id={detail.id} onClose={()=>setDetail(null)} onContact={(ch)=>{ setCompose({newcomer:detail,channel:ch}); }} />}
      {del && <ConfirmDialog danger icon="trash" title={t('Odebrat nováčka?')} body={tf('Opravdu odebrat „{0}" z onboardingu? Jeho postup se trvale smaže. Pokud se znovu připojí přes QR, začne od začátku.', del.name)} confirmLabel={t('Odebrat')} onConfirm={()=>deleteNewcomer(del)} onClose={()=>setDel(null)} />}
    </>
  );
}

// ── Demo dashboard (sample data for the unauthenticated prototype) ─
function DemoDashboard({ onOpen, onContact, onLogin, onRegister, authTick }) {
  const [group, setGroup] = useState('Všechny skupiny'); // value je klíč filtru (GROUPS), nepřekládat
  const [status, setStatus] = useState('all');
  const [sort, setSort] = useState('progress');
  const [q, setQ] = useState('');

  const rows = useMemo(() => {
    let r = PEOPLE.filter(p =>
      (group==='Všechny skupiny' || p.group===group) &&
      (status==='all' || p.status===status) &&
      (p.name.toLowerCase().includes(q.toLowerCase()))
    );
    r = [...r].sort((a,b) =>
      sort==='progress' ? b.pct-a.pct :
      sort==='name'     ? a.name.localeCompare(b.name,'cs') :
      sort==='recent'   ? a.idleDays-b.idleDays : 0
    );
    return r;
  }, [group,status,sort,q]);

  const STATUS_LABEL = { done:t('Dokončeno'), prog:t('Probíhá'), idle:t('Bez aktivity'), new:t('Nový') };
  const statChips = [
    { k:'avg',  label:t('Průměrné dokončení'), val:ANALYTICS.avgCompletion+' %', icon:'chart', c:'var(--brand-soft)', fg:'var(--brand-fg)' },
    { k:'act',  label:t('Aktivních nováčků'),  val:PEOPLE.length, icon:'users', c:'var(--sky-soft)', fg:'var(--brand-fg)' },
    { k:'done', label:t('Dokončili cestu'),    val:PEOPLE.filter(p=>p.status==='done').length, icon:'trophy', c:'var(--green-soft)', fg:'var(--green)' },
    { k:'idle', label:t('Bez aktivity'),       val:PEOPLE.filter(p=>p.status==='idle').length, icon:'alert', c:'var(--amber-soft)', fg:'var(--amber)' },
  ];

  return (
    <>
      <LiveNewcomers onLogin={onLogin} onRegister={onRegister} authTick={authTick} />
      <div className="stat-grid">
        {statChips.map(s => (
          <div className="stat card" key={s.k}>
            <div style={{display:'flex',justifyContent:'space-between',alignItems:'flex-start'}}>
              <div>
                <div className="s-label">{s.label}</div>
                <div className="s-val">{s.val}</div>
              </div>
              <div className="s-ico" style={{background:s.c,color:s.fg}}><Icon name={s.icon} size={19} /></div>
            </div>
          </div>
        ))}
      </div>

      <div className="filterbar">
        <div className="search-wrap"><Icon name="search" /><input className="search" placeholder={t('Hledat nováčka…')} value={q} onChange={e=>setQ(e.target.value)} /></div>
        <div className="field"><label>{t('Skupina')}</label>
          <select className="select" value={group} onChange={e=>setGroup(e.target.value)}>{GROUPS.map(g=><option key={g}>{g}</option>)}</select>
        </div>
        <div className="field"><label>{t('Pokrok')}</label>
          <select className="select" value={status} onChange={e=>setStatus(e.target.value)}>
            <option value="all">{t('Vše')}</option><option value="prog">{t('Probíhá')}</option><option value="done">{t('Dokončeno')}</option><option value="idle">{t('Bez aktivity')}</option>
          </select>
        </div>
        <div className="field"><label>{t('Řadit podle')}</label>
          <select className="select" value={sort} onChange={e=>setSort(e.target.value)}>
            <option value="progress">{t('Pokroku')}</option><option value="recent">{t('Aktivity')}</option><option value="name">{t('Jména')}</option>
          </select>
        </div>
        <div style={{marginLeft:'auto',alignSelf:'flex-end',color:'var(--text-3)',fontSize:13,fontWeight:600}}>{tf('{0} nováčků', rows.length)}</div>
      </div>

      <div className="card">
        <div className="nrow nrow-head">
          <div>{t('Nováček')}</div><div>{t('Postup checklistu')}</div><div>{t('Stav')}</div><div style={{textAlign:'right'}}>{t('Akce')}</div>
        </div>
        {rows.map(p => (
          <div className="nrow" key={p.id} onClick={()=>onOpen(p)}>
            <div className="person">
              <Avatar name={p.name} size={42} />
              <div className="meta">
                <div className="nm">{p.name}{p.you && <span className="chip new" style={{marginLeft:8,fontSize:11,padding:'1px 8px'}}>{t('vy jako nováček')}</span>}</div>
                <div className="sub">{tf('{0} · registrace {1}', p.group, p.reg)}</div>
              </div>
            </div>
            <div>
              <div style={{display:'flex',alignItems:'center',gap:10}}>
                <div className="pbar" style={{flex:1}}><i style={{width:p.pct+'%', background:p.status==='idle'?'var(--amber)':p.status==='done'?'var(--green)':'var(--brand)'}}/></div>
                <span className="pct" style={{minWidth:38,textAlign:'right'}}>{p.pct}%</span>
              </div>
              <div style={{fontSize:11.5,color:'var(--text-3)',marginTop:4}}>{tf('{0}/{1} úkolů · {2}', p.done, TOTAL, PHASES.find(f=>f.key===p.phase).name)}</div>
            </div>
            <div>
              <span className={'chip '+p.status}>
                <Icon name={p.status==='done'?'checkCircle':p.status==='idle'?'clock':'flame'} />
                {STATUS_LABEL[p.status]}
              </span>
              <div style={{fontSize:11.5,color:'var(--text-3)',marginTop:5}}>{tf('aktivní {0}', p.last)}</div>
            </div>
            <div style={{display:'flex',gap:8,justifyContent:'flex-end'}} onClick={e=>e.stopPropagation()}>
              <button className="btn btn-ghost btn-sm" onClick={()=>onContact(p)}><Icon name="mail" />{t('Kontaktovat')}</button>
              <button className="btn btn-subtle btn-sm" onClick={()=>onOpen(p)}><Icon name="chevRight" /></button>
            </div>
          </div>
        ))}
        {rows.length===0 && <div style={{padding:'40px',textAlign:'center',color:'var(--text-3)'}}>{t('Žádný nováček neodpovídá filtrům.')}</div>}
      </div>
    </>
  );
}

// ── Newcomer detail drawer ───────────────────────────────────
function NewcomerDrawer({ person, onClose, onContact }) {
  const tasks = tasksFor(person.done);
  const phase = PHASES.find(f=>f.key===person.phase);
  return (
    <>
      <div className="drawer-overlay" onClick={onClose} />
      <div className="drawer">
        <div className="drawer-head">
          <Avatar name={person.name} size={52} />
          <div style={{flex:1}}>
            <div style={{fontSize:19,fontWeight:700}}>{person.name}</div>
            <div style={{fontSize:13,color:'var(--text-2)',marginTop:2}}>{tf('{0} · registrace {1}', person.group, person.reg)}</div>
          </div>
          <button className="modal-x" onClick={onClose}><Icon name="x" size={20} /></button>
        </div>
        <div className="drawer-body">
          <div style={{display:'flex',gap:14,marginBottom:24}}>
            <div className="card" style={{flex:1,padding:'16px 18px'}}>
              <div style={{fontSize:12.5,color:'var(--text-2)',fontWeight:600,marginBottom:8}}>{t('Dokončeno')}</div>
              <div style={{display:'flex',alignItems:'baseline',gap:6}}><span style={{fontSize:30,fontWeight:800}}>{person.pct}%</span><span style={{color:'var(--text-3)',fontSize:13}}>{tf('{0}/{1} úkolů', person.done, TOTAL)}</span></div>
              <div className="pbar" style={{marginTop:10}}><i style={{width:person.pct+'%',background:person.status==='idle'?'var(--amber)':person.status==='done'?'var(--green)':'var(--brand)'}}/></div>
            </div>
            <div className="card" style={{flex:1,padding:'16px 18px'}}>
              <div style={{fontSize:12.5,color:'var(--text-2)',fontWeight:600,marginBottom:8}}>{t('Aktuální fáze')}</div>
              <div style={{display:'flex',alignItems:'center',gap:9}}>
                <span style={{width:30,height:30,borderRadius:8,background:phase.color,color:'#fff',display:'flex',alignItems:'center',justifyContent:'center'}}><Icon name={phase.icon} size={17} /></span>
                <div><div style={{fontWeight:700,fontSize:15}}>{phase.name}</div><div style={{fontSize:11.5,color:'var(--text-3)'}}>{tf('aktivní {0}', person.last)}</div></div>
              </div>
            </div>
          </div>

          {person.status==='idle' && (
            <div style={{display:'flex',gap:12,alignItems:'center',background:'var(--amber-soft)',color:'var(--amber)',padding:'12px 16px',borderRadius:10,marginBottom:22,fontSize:13.5,fontWeight:600}}>
              <Icon name="alert" size={18} /> {tf('{0} dlouho nereagoval{1} ({2}). Zkuste {3} povzbudit.', person.name.split(' ')[0], person.name.endsWith('á')?'a':'', person.last, person.name.endsWith('á')?t('ji'):t('ho'))}
            </div>
          )}

          <div className="sr-section-title">{t('Postup v checklistu')}</div>
          <div className="tline">
            {tasks.map(tk => (
              <div key={tk.id} className={'tstep'+(tk.done?' done':'')}>
                <span className="tdot">{tk.done && <Icon name="check" size={11} />}</span>
                <div className="tt">{tk.title}</div>
                <div className="td">{PHASES.find(f=>f.key===tk.phase).name}{tk.done?' · '+t('hotovo'):' · '+t('čeká')}</div>
              </div>
            ))}
          </div>
        </div>
        <div className="drawer-foot">
          <button className="btn btn-primary" style={{flex:1}} onClick={()=>onContact(person)}><Icon name="mail" />{t('Kontaktovat')}</button>
          <button className="btn btn-ghost" onClick={()=>onContact(person)}><Icon name="bell" />{t('Poslat připomínku')}</button>
        </div>
      </div>
    </>
  );
}

// ── Contact modal ────────────────────────────────────────────
function ContactModal({ person, onClose, toast }) {
  const first = person.name.split(' ')[0];
  const [msg, setMsg] = useState(tf('Ahoj {0}, jak se ti daří na tvé cestě? Kdyby cokoliv, klidně se ozvi — rádi tě uvidíme na skupince. 🙂', first));
  return (
    <div className="modal-overlay" onClick={onClose}>
      <div className="modal" onClick={e=>e.stopPropagation()}>
        <div className="modal-head">
          <Avatar name={person.name} size={40} />
          <div><h3>{tf('Zpráva pro {0}', person.name)}</h3><div style={{fontSize:13,color:'var(--text-2)',marginTop:2}}>{t('Odešle se přes Konverzace v aplikaci')}</div></div>
          <button className="modal-x" onClick={onClose}><Icon name="x" size={20} /></button>
        </div>
        <div className="modal-body">
          <textarea className="input" rows={4} value={msg} onChange={e=>setMsg(e.target.value)} />
          <div style={{display:'flex',gap:8,marginTop:12,flexWrap:'wrap'}}>
            {['Povzbuzení','Pozvánka na skupinku','Nabídka pomoci'].map(lbl=>(
              <button key={lbl} className="btn btn-ghost btn-sm" onClick={()=>setMsg(
                lbl==='Povzbuzení'?tf('Ahoj {0}, jen ti chci říct, že na tebe myslíme a fandíme ti. Drž se! 🙏', first):
                lbl==='Pozvánka na skupinku'?tf('Ahoj {0}, v pátek se schází naše skupinka v 17:00. Budeme rádi, když dorazíš!', first):
                tf('Ahoj {0}, můžu ti s něčím pomoct na tvé cestě? Napiš mi, kdykoliv budeš chtít.', first)
              )}>{t(lbl)}</button>
            ))}
          </div>
        </div>
        <div className="modal-foot">
          <button className="btn btn-ghost" onClick={onClose}>{t('Zrušit')}</button>
          <button className="btn btn-primary" onClick={()=>{onClose();toast(tf('Zpráva odeslána {0}.', person.name.split(' ')[0]));}}><Icon name="send" />{t('Odeslat zprávu')}</button>
        </div>
      </div>
    </div>
  );
}

// ── Pilot login modal ────────────────────────────────────────
function LoginModal({ onClose, onDone, toast, startMode }) {
  const [mode, setMode] = useState(startMode === 'register' ? 'register' : 'login');
  const reg = mode === 'register', forgot = mode === 'forgot';
  const [community, setCommunity] = useState('');
  const [name, setName] = useState('');
  const [email, setEmail] = useState('');
  const [pass, setPass] = useState('');
  const [err, setErr] = useState('');
  const [busy, setBusy] = useState(false);
  const [sent, setSent] = useState(false);
  const [showPass, setShowPass] = useState(false);
  const [accepted, setAccepted] = useState(false);
  const lbl = { fontSize:12.5, fontWeight:600, color:'var(--text-2)' };
  const strongPass = (pw) => pw.length >= 6 && /\p{Ll}/u.test(pw) && /\p{Lu}/u.test(pw);

  const submit = async () => {
    if (forgot) {
      setBusy(true); setErr('');
      await api.post('/api/forgot', { email });
      setBusy(false); setSent(true);
      window.track && window.track('password_reset_requested', {});
      return;
    }
    if (reg && !strongPass(pass)) { setErr(t('Heslo musí mít aspoň 6 znaků a obsahovat malé i velké písmeno.')); return; }
    if (reg && !accepted) { setErr(t('Pro vytvoření společenství potvrď prosím souhlas s podmínkami a zpracováním osobních údajů.')); return; }
    setBusy(true); setErr('');
    const { ok, data } = reg
      ? await api.post('/api/register', { communityName: community, pastorName: name, email, password: pass, acceptedTerms: accepted, lang: window.LOCALE })
      : await api.post('/api/login', { email, password: pass });
    setBusy(false);
    if (!ok) { setErr(data.error || (reg ? t('Registrace selhala.') : t('Přihlášení selhalo.'))); return; }
    api.setToken(data.token); api.setProfile({ pastor: data.pastor, community: data.community }); onDone(data);
    window.identifyCommunity && window.identifyCommunity(data.community);
    window.track && window.track(reg ? 'community_registered' : 'pastor_logged_in', { community: data.community.name });
    toast(reg ? tf('Společenství „{0}" vytvořeno. Ověřovací e-mail je na cestě.', data.community.name) : tf('Přihlášen(a) jako {0}.', data.community.name));
  };

  const title = reg ? t('Vytvořit společenství') : forgot ? t('Zapomenuté heslo') : t('Přihlášení vedoucího');
  const subtitle = reg ? t('Založ si vlastní onboarding za pár vteřin') : forgot ? t('Pošleme ti odkaz na obnovu hesla') : t('Přístup k onboardingu vašeho společenství');

  return (
    <div className="modal-overlay" onClick={onClose}>
      <div className="modal" onClick={e=>e.stopPropagation()} style={{maxWidth:430}}>
        <div className="modal-head">
          <div style={{width:40,height:40,borderRadius:10,background:'var(--brand-soft)',color:'var(--brand-fg)',display:'flex',alignItems:'center',justifyContent:'center'}}><Icon name={reg?'community':forgot?'mail':'user'} size={22} /></div>
          <div><h3>{title}</h3><div style={{fontSize:13,color:'var(--text-2)',marginTop:2}}>{subtitle}</div></div>
          <button className="modal-x" onClick={onClose}><Icon name="x" size={20} /></button>
        </div>
        <div className="modal-body">
          {forgot && sent ? (
            <div style={{textAlign:'center',padding:'10px 0'}}>
              <div style={{width:54,height:54,borderRadius:14,background:'var(--green-soft)',color:'var(--green)',display:'flex',alignItems:'center',justifyContent:'center',margin:'0 auto 14px'}}><Icon name="checkCircle" size={28} /></div>
              <div style={{fontWeight:700,marginBottom:6}}>{t('Hotovo — zkontroluj e-mail')}</div>
              <p style={{fontSize:13.5,color:'var(--text-2)',lineHeight:1.55,margin:0}}>{t('Pokud na')} <strong>{email}</strong> {t('existuje účet, právě jsme poslali odkaz na nastavení nového hesla. Platí 1 hodinu.')}</p>
            </div>
          ) : (<>
            {reg && (<>
              <label style={lbl}>{t('Název společenství')}</label>
              <input className="input" style={{marginTop:6,marginBottom:12}} value={community} onChange={e=>setCommunity(e.target.value)} placeholder={t('např. Sbor Živá voda')} autoFocus />
              <label style={lbl}>{t('Tvé jméno')}</label>
              <input className="input" style={{marginTop:6,marginBottom:12}} value={name} onChange={e=>setName(e.target.value)} placeholder={t('Jméno a příjmení')} />
            </>)}
            <label style={lbl}>{t('E-mail')}</label>
            <input className="input" style={{marginTop:6,marginBottom:forgot?0:12}} value={email} onChange={e=>setEmail(e.target.value)} placeholder={t('vas@email.cz')} autoFocus={!reg} onKeyDown={e=>e.key==='Enter'&&forgot&&submit()} />
            {!forgot && (<>
              <label style={lbl}>{t('Heslo')}{reg && <span style={{color:'var(--text-3)',fontWeight:400}}> {t('(min. 6 znaků, malé i velké písmeno)')}</span>}</label>
              <div style={{position:'relative',marginTop:6}}>
                <input className="input" type={showPass?'text':'password'} style={{paddingRight:42,width:'100%'}} value={pass} onChange={e=>setPass(e.target.value)} placeholder="••••••••" onKeyDown={e=>e.key==='Enter'&&submit()} />
                <button type="button" onClick={()=>setShowPass(v=>!v)} title={showPass?t('Skrýt heslo'):t('Zobrazit heslo')} aria-label={showPass?t('Skrýt heslo'):t('Zobrazit heslo')}
                  style={{position:'absolute',right:6,top:'50%',transform:'translateY(-50%)',background:'none',border:'none',cursor:'pointer',color:'var(--text-3)',padding:6,display:'flex'}}>
                  <Icon name={showPass?'eyeOff':'eye'} size={18} />
                </button>
              </div>
            </>)}
            {reg && (
              <label style={{display:'flex',alignItems:'flex-start',gap:9,marginTop:14,fontSize:12.5,color:'var(--text-2)',lineHeight:1.5,cursor:'pointer'}}>
                <input type="checkbox" checked={accepted} onChange={e=>setAccepted(e.target.checked)} style={{marginTop:2,flexShrink:0,width:16,height:16,accentColor:'var(--brand)'}} />
                <span>{t('Souhlasím s')} <a href="https://believer.eu/terms.html" target="_blank" rel="noopener" style={{color:'var(--brand-fg)',fontWeight:600}}>{t('obchodními podmínkami')}</a> {t('a se')} <a href="https://believer.eu/privacy.html" target="_blank" rel="noopener" style={{color:'var(--brand-fg)',fontWeight:600}}>{t('zpracováním osobních údajů')}</a>.</span>
              </label>
            )}
            {!reg && !forgot && <div style={{textAlign:'right',marginTop:8}}><button onClick={()=>{setErr('');setMode('forgot');}} style={{background:'none',border:'none',color:'var(--brand-fg)',fontWeight:600,cursor:'pointer',fontSize:12.5}}>{t('Zapomenuté heslo?')}</button></div>}
            {err && <div style={{background:'var(--red-soft)',color:'var(--red)',borderRadius:8,padding:'9px 12px',fontSize:13,marginTop:12}}>{err}</div>}
            <div style={{textAlign:'center',marginTop:16,fontSize:13,color:'var(--text-2)'}}>
              {forgot ? <>{t('Vzpomněl(a) sis?')} <button onClick={()=>{setErr('');setMode('login');}} style={{background:'none',border:'none',color:'var(--brand-fg)',fontWeight:700,cursor:'pointer',fontSize:13}}>{t('Zpět na přihlášení')}</button></>
                : <>{reg ? t('Už máš účet? ') : t('Nemáš ještě společenství? ')}<button onClick={()=>{setErr('');setMode(reg?'login':'register');}} style={{background:'none',border:'none',color:'var(--brand-fg)',fontWeight:700,cursor:'pointer',fontSize:13}}>{reg ? t('Přihlásit se') : t('Vytvořit nové')}</button></>}
            </div>
          </>)}
        </div>
        <div className="modal-foot">
          <button className="btn btn-ghost" onClick={onClose}>{forgot&&sent?t('Zavřít'):t('Zrušit')}</button>
          {!(forgot&&sent) && <button className="btn btn-primary" onClick={submit} disabled={busy}>{busy ? '…' : reg?t('Vytvořit a začít'):forgot?t('Poslat odkaz'):t('Přihlásit se')}</button>}
        </div>
      </div>
    </div>
  );
}

// ── Share modal (QR + code) ──────────────────────────────────
function ShareModal({ tpl, shareCode, onClose, toast }) {
  const qrRef = useRef(null);
  const [url, setUrl] = useState(joinUrl(shareCode));
  useEffect(() => { let on = true; api.loadConfig().then(() => { if (on) setUrl(joinUrl(shareCode)); }); return () => { on = false; }; }, [shareCode]);
  useEffect(() => {
    if (qrRef.current && window.QRCode) {
      qrRef.current.innerHTML = '';
      new window.QRCode(qrRef.current, { text: url, width: 188, height: 188, colorDark: '#253D83', colorLight: '#ffffff', correctLevel: window.QRCode.CorrectLevel.M });
    }
  }, [url]);
  const copy = (text, msg) => { navigator.clipboard?.writeText(text); toast(msg); };
  return (
    <div className="modal-overlay" onClick={onClose}>
      <div className="modal" onClick={e=>e.stopPropagation()} style={{maxWidth:460}}>
        <div className="modal-head">
          <span className="tpl-ico" style={{background:tpl.color,overflow:'hidden'}}><OnbIcon icon={tpl.icon} size={18} /></span>
          <div><h3>{tf('Sdílet „{0}"', tpl.name)}</h3><div style={{fontSize:13,color:'var(--text-2)',marginTop:2}}>{t('Nováčci se připojí naskenováním QR nebo zadáním kódu')}</div></div>
          <button className="modal-x" onClick={onClose}><Icon name="x" size={20} /></button>
        </div>
        <div className="modal-body" style={{textAlign:'center'}}>
          <div style={{display:'inline-block',padding:14,background:'#fff',border:'1px solid var(--border)',borderRadius:16,boxShadow:'var(--shadow-card)'}}><div ref={qrRef} /></div>
          <div style={{margin:'18px 0 6px',fontSize:12.5,fontWeight:700,textTransform:'uppercase',letterSpacing:'.05em',color:'var(--text-3)'}}>{t('Kód onboardingu')}</div>
          <button onClick={()=>copy(shareCode,t('Kód zkopírován.'))} title={t('Kopírovat kód')}
            style={{fontSize:30,fontWeight:800,letterSpacing:'.12em',color:'var(--brand-fg)',background:'var(--brand-soft)',border:'none',borderRadius:12,padding:'12px 22px',cursor:'pointer',fontFamily:'var(--wordmark)'}}>{shareCode}</button>
          <div style={{display:'flex',gap:8,marginTop:18}}>
            <button className="btn btn-ghost" style={{flex:1}} onClick={()=>copy(url,t('Odkaz zkopírován.'))}><Icon name="list" />{t('Kopírovat odkaz')}</button>
            <button className="btn btn-ghost" style={{flex:1}} onClick={()=>window.open(`${location.origin}/join.html?code=${shareCode}`,'_blank')}><Icon name="arrowUpRight" />{t('Otevřít náhled')}</button>
          </div>
          <div style={{fontSize:12,color:'var(--text-3)',marginTop:14,wordBreak:'break-all'}}>{url}</div>
          <div style={{fontSize:11.5,color:'var(--text-3)',marginTop:6,lineHeight:1.45}}><Icon name="phone" size={12} style={{verticalAlign:'-2px'}} /> {t('QR a odkaz výše fungují na telefonu připojeném ke stejné Wi-Fi. „Otevřít náhled" otevře onboarding tady na počítači.')}</div>
        </div>
      </div>
    </div>
  );
}

// ── Templates switch: real backend editor when logged in, demo otherwise ─
function Templates(props) {
  const [tok, setTok] = useState(api.token());
  useEffect(() => { setTok(api.token()); }, [props.authTick]);
  useEffect(() => { const h = () => setTok(api.token()); window.addEventListener('believer-auth', h); return () => window.removeEventListener('believer-auth', h); }, []);
  return tok ? <TemplatesReal {...props} /> : <TemplatesDemo {...props} />;
}

const ICON_CHOICES = ['rocket','book','cross','sparkle','heart','groups','bell','trophy'];
// True when an onboarding "icon" is an uploaded image (data URL or http URL), not a Fluent name.
const isImageIcon = (v) => typeof v === 'string' && /^(data:|https?:)/.test(v);
// Renders an onboarding icon: uploaded image OR a named Fluent icon.
function OnbIcon({ icon, size = 22 }) {
  if (isImageIcon(icon)) return <img src={icon} alt="" style={{ width:'100%', height:'100%', objectFit:'cover', display:'block' }} />;
  return <Icon name={icon} size={size} />;
}
const COLOR_CHOICES = ['#253D83','#FF814A','#3E7CB1','#255B84','#A23E5C','#1F7A5B','#7A5CA8','#B5612E'];
const TAG_CHOICES = ['Vítej','Poznávání','Růst','Zapojení'];
const meta = (type) => BLOCK_TYPES.find(b => b.type === type);

// Shared block canvas (used by both real + demo editors)
function BlockCanvas({ blocks, preview, paletteOpen, setPaletteOpen, patch, remove, dup, move, add }) {
  return (
    <div className="tpl-canvas">
      {blocks.map((b, i) => {
        const m = meta(b.type);
        return (
          <div key={b.id} className={'blk'+(preview?' preview':'')}>
            <div className="blk-side">
              <span className="blk-badge" style={{background:m.color}}><Icon name={m.icon} size={14} /></span>
              {!preview && <span className="blk-grip"><Icon name="grip" size={16} /></span>}
            </div>
            <div className="blk-main">
              <div className="blk-top">
                <span className="blk-type" style={{color:m.color}}>{m.label}</span>
                {!preview && (
                  <div className="blk-tools">
                    <button onClick={()=>move(b.id,-1)} disabled={i===0} title={t('Nahoru')}><Icon name="chevUp" size={15} /></button>
                    <button onClick={()=>move(b.id,1)} disabled={i===blocks.length-1} title={t('Dolů')}><Icon name="chevDown" size={15} /></button>
                    <button onClick={()=>dup(b.id)} title={t('Duplikovat')}><Icon name="copy" size={15} /></button>
                    <button onClick={()=>remove(b.id)} title={t('Smazat')} className="danger"><Icon name="trash" size={15} /></button>
                  </div>
                )}
              </div>
              {preview
                ? <div className="blk-title-static">{b.title}</div>
                : <input className="blk-title-input" value={b.title} onChange={e=>patch(b.id,{title:e.target.value})} placeholder={t('Název bloku')} />}
              <BlockBody block={b} preview={preview} patch={patch} />
            </div>
          </div>
        );
      })}
      {blocks.length===0 && <div className="tpl-empty">{t('Onboarding je prázdný — přidej první blok níže.')}</div>}
      {!preview && (
        <div className="blk-add">
          {!paletteOpen
            ? <button className="blk-add-btn" onClick={()=>setPaletteOpen(true)}><Icon name="plus" />{t('Přidat blok')}</button>
            : (
              <div className="blk-palette">
                <div className="blk-palette-head">{t('Co chceš vložit?')}<button className="modal-x" onClick={()=>setPaletteOpen(false)}><Icon name="x" size={16} /></button></div>
                <div className="blk-palette-grid">
                  {BLOCK_TYPES.map(bt => (
                    <button key={bt.type} className="blk-opt" onClick={()=>add(bt.type)}>
                      <span className="blk-badge" style={{background:bt.color}}><Icon name={bt.icon} size={16} /></span>
                      <span className="blk-opt-name">{bt.label}</span>
                      <span className="blk-opt-hint">{bt.hint}</span>
                    </button>
                  ))}
                </div>
              </div>
            )}
        </div>
      )}
    </div>
  );
}

// Cache poslední načtené sady onboardingů — zabrání problikání při přepnutí záložky.
let _tplCache = null;
// ── Real backend-driven editor (logged-in account) ───────────
function TemplatesReal({ toast }) {
  const [list, setList] = useState(_tplCache?.list || []);
  const [selId, setSelId] = useState(_tplCache?.selId ?? null);
  const [loaded, setLoaded] = useState(!!_tplCache);
  const [preview, setPreview] = useState(false);
  const [paletteOpen, setPaletteOpen] = useState(false);
  const [share, setShare] = useState(null);
  const [busy, setBusy] = useState(false);
  const [saving, setSaving] = useState(false);
  const [appearance, setAppearance] = useState(false);
  const [picker, setPicker] = useState(false);
  const timer = useRef();
  const iconInputRef = useRef();

  const reload = async (pick) => {
    const { ok, data } = await api.get('/api/onboardings');
    if (!ok) { setLoaded(true); return; }
    setList(data.onboardings);
    let nextSel;
    setSelId(s => (nextSel = pick !== undefined ? pick : (s ?? data.onboardings[0]?.id ?? null)));
    setLoaded(true);
    _tplCache = { list: data.onboardings, selId: nextSel };
  };
  useEffect(() => { reload(); }, []);

  const sel = list.find(o => o.id === selId) || null;
  const selRef = useRef(); selRef.current = sel;

  const doSave = async () => {
    const o = selRef.current; if (!o) return;
    setSaving(true);
    await api.post('/api/onboardings', { clientId: o.clientId, name: o.name, desc: o.desc, icon: o.icon, color: o.color, tag: o.tag, blocks: o.blocks });
    setSaving(false);
  };
  const scheduleSave = () => { clearTimeout(timer.current); timer.current = setTimeout(doSave, 700); };
  const updateSel = (patch) => { setList(L => L.map(o => o.id===selId ? { ...o, ...patch } : o)); scheduleSave(); };
  const setBlocks = (fn) => updateSel({ blocks: fn(sel.blocks) });

  const patch = (id, p) => setBlocks(bs => bs.map(b => b.id===id ? {...b, ...p} : b));
  const remove = (id) => setBlocks(bs => bs.filter(b => b.id!==id));
  const dup = (id) => setBlocks(bs => { const i = bs.findIndex(b=>b.id===id); const c={...bs[i], id:'b'+Math.random().toString(36).slice(2,8)}; const n=[...bs]; n.splice(i+1,0,c); return n; });
  const move = (id, dir) => setBlocks(bs => { const i=bs.findIndex(b=>b.id===id); const j=i+dir; if(j<0||j>=bs.length) return bs; const n=[...bs]; [n[i],n[j]]=[n[j],n[i]]; return n; });
  const add = (type) => { setBlocks(bs => [...bs, newBlock(type)]); setPaletteOpen(false); toast(tf('{0} přidán.', meta(type).label)); };

  // Deep-clone blocks with fresh ids (so a copy never shares ids with its source).
  const regenIds = (blocks) => (blocks || []).map(b => {
    const nb = { ...b, id: 'b' + Math.random().toString(36).slice(2,8) };
    if (b.type === 'choice') nb.branches = (b.branches || []).map(br => ({ ...br, id: 'br' + Math.random().toString(36).slice(2,8), blocks: regenIds(br.blocks) }));
    if (b.type === 'quiz') nb.options = (b.options || []).map(o => ({ ...o }));
    return nb;
  });

  const createWith = async ({ name, desc, icon, color, tag, blocks }, source) => {
    const clientId = 'onb_' + Math.random().toString(36).slice(2,8);
    const { ok, data } = await api.post('/api/onboardings', { clientId, name, desc, icon, color, tag, blocks });
    if (ok) { setList(L => [...L, data]); setSelId(data.id); setPreview(false); setPicker(false); toast(tf('Onboarding „{0}" vytvořen.', name));
      window.track && window.track('onboarding_created', { source: source || 'blank', blocks: (blocks||[]).length }); }
  };
  const createBlank = () => createWith({ name:t('Nový onboarding'), desc:t('Krátký popis, o čem onboarding je…'), icon:'rocket', color:'#253D83', tag:'Vítej', blocks:[] }, 'blank');
  const createFromTemplate = (t) => createWith({ name: t.name, desc: t.desc, icon: t.icon, color: t.color, tag: t.tag, blocks: regenIds(t.blocks) }, 'template');
  const duplicateOnb = () => sel && createWith({ name: tf('{0} (kopie)', sel.name), desc: sel.desc, icon: sel.icon, color: sel.color, tag: sel.tag, blocks: regenIds(sel.blocks) }, 'copy');
  const deleteOnb = async (o) => {
    const { ok } = await api.del('/api/onboardings/' + o.id);
    if (ok) { const rest = list.filter(x => x.id !== o.id); setList(rest); setSelId(rest[0]?.id ?? null); toast(t('Onboarding smazán.')); }
  };
  const publish = async () => {
    await doSave(); setBusy(true);
    const pub = await api.post(`/api/onboardings/${selId}/publish`);
    setBusy(false);
    if (!pub.ok) { toast(pub.data.code === 'EMAIL_UNVERIFIED' ? t('Nejdřív si ověř e-mail — pak můžeš publikovat. Ověřovací odkaz máš v e-mailu (nebo si ho pošli znovu z banneru nahoře).') : (pub.data.error || t('Publikace selhala.'))); return; }
    setList(L => L.map(o => o.id===selId ? { ...o, published:true, shareCode:pub.data.shareCode } : o));
    setShare({ tpl: { ...sel, name: sel.name, icon: sel.icon, color: sel.color }, shareCode: pub.data.shareCode });
    window.track && window.track('onboarding_published', { name: sel.name, blocks: (sel.blocks||[]).length });
    toast(t('Publikováno — sdílej QR kód.'));
  };

  if (!loaded) return <div className="tpl-empty" style={{padding:'80px'}}>{t('Načítám onboardingy…')}</div>;

  return (
    <div className="tpl-layout">
      <aside className="tpl-rail">
        <div className="sr-section-title" style={{marginBottom:12}}>{t('Vaše onboardingy')}</div>
        {list.map(o => (
          <button key={o.id} className={'tpl-card'+(o.id===selId?' on':'')} onClick={()=>{setSelId(o.id);setPreview(false);setPaletteOpen(false);setAppearance(false);}}>
            <span className="tpl-ico" style={{background:o.color,overflow:'hidden'}}><OnbIcon icon={o.icon} size={18} /></span>
            <span className="tpl-card-body">
              <span className="tpl-card-name">{o.name}</span>
              <span className="tpl-card-meta">{tf('{0} bloků', o.blocks.length)} · {o.published ? <span style={{color:'var(--green)'}}>{t('publikováno')}</span> : t('koncept')} · {tf('{0} nováčků', o.newcomerCount)}</span>
            </span>
          </button>
        ))}
        <button className="btn btn-primary" style={{width:'100%',marginTop:10,justifyContent:'center'}} onClick={()=>setPicker(true)}><Icon name="plus" />{t('Nový onboarding')}</button>
        {list.length===0 && <div style={{fontSize:12.5,color:'var(--text-3)',marginTop:12,lineHeight:1.5,textAlign:'center'}}>{t('Zatím tu nic není.')}<br/>{t('Vytvoř svůj první onboarding. 👆')}</div>}
      </aside>

      {sel ? (
        <section className="tpl-editor">
          <div className="tpl-editor-head">
            <div className="tpl-head-main">
              <button className="tpl-ico lg" style={{background:sel.color,border:'none',cursor:'pointer',overflow:'hidden'}} title={t('Změnit vzhled')} onClick={()=>setAppearance(a=>!a)}><OnbIcon icon={sel.icon} size={24} /></button>
              <div style={{flex:1,minWidth:0}}>
                <input className="tpl-name-input" value={sel.name} onChange={e=>updateSel({name:e.target.value})} placeholder={t('Název onboardingu')} />
                <input className="tpl-desc-input" value={sel.desc||''} onChange={e=>updateSel({desc:e.target.value})} placeholder={t('Krátký popis, o čem onboarding je…')} />
              </div>
            </div>
            <div className="tpl-head-actions">
              <span style={{fontSize:12,color:'var(--text-3)',marginRight:'auto'}}>{saving?t('Ukládám…'):t('Uloženo ✓')}</span>
              <button className="btn btn-ghost" onClick={duplicateOnb} title={t('Vytvořit kopii (navázat na tuto šablonu)')}><Icon name="copy" /></button>
              <button className="btn btn-ghost" onClick={()=>deleteOnb(sel)} title={t('Smazat onboarding')}><Icon name="trash" /></button>
              <button className={'btn btn-ghost'+(preview?' on':'')} onClick={()=>setPreview(p=>!p)}><Icon name="eye" />{preview?t('Editor'):t('Náhled')}</button>
              {sel.published && <button className="btn btn-ghost" onClick={()=>setShare({tpl:sel,shareCode:sel.shareCode})}><Icon name="arrowUpRight" />QR</button>}
              <button className="btn btn-primary" onClick={publish} disabled={busy}><Icon name="rocket" />{busy?t('Publikuji…'):sel.published?t('Znovu publikovat'):t('Publikovat & sdílet')}</button>
            </div>
          </div>

          {appearance && (
            <div className="appbar">
              <span className="appbar-label">{t('Ikona')}</span>
              {ICON_CHOICES.map(ic => <button key={ic} className={'app-ico'+(sel.icon===ic?' on':'')} onClick={()=>{updateSel({icon:ic});toast(t('Ikona uložena ✓'));}}><Icon name={ic} size={16} /></button>)}
              <button className={'app-ico app-upload'+(isImageIcon(sel.icon)?' on':'')} title={t('Nahrát vlastní ikonu')} onClick={()=>iconInputRef.current && iconInputRef.current.click()}>
                {isImageIcon(sel.icon) ? <img src={sel.icon} alt="" style={{width:'100%',height:'100%',objectFit:'cover',borderRadius:6}} /> : <Icon name="image" size={16} />}
              </button>
              <input ref={iconInputRef} type="file" accept="image/*" style={{display:'none'}} onChange={(e)=>{const f=e.target.files&&e.target.files[0];e.target.value='';if(f&&/^image\//.test(f.type)) fileToResizedDataUrl(f,128,0.85,(url)=>{updateSel({icon:url});toast(t('Vlastní ikona nahrána a uložena ✓'));});}} />
              <span className="appbar-div" />
              <span className="appbar-label">{t('Barva')}</span>
              {COLOR_CHOICES.map(c => <button key={c} className={'app-col'+(sel.color===c?' on':'')} style={{background:c}} onClick={()=>{updateSel({color:c});toast(t('Barva uložena ✓'));}} />)}
              <span className="appbar-div" />
              <span className="appbar-label">{t('Fáze')}</span>
              <select className="select" style={{maxWidth:150}} value={sel.tag||'Vítej'} onChange={e=>{updateSel({tag:e.target.value});toast(t('Fáze uložena ✓'));}}>{TAG_CHOICES.map(tg=><option key={tg} value={tg}>{t(tg)}</option>)}</select>
              <button className="btn btn-primary btn-sm" style={{marginLeft:'auto'}} onClick={()=>{setAppearance(false);toast(t('Vzhled uložen ✓'));}}><Icon name="check" />{t('Hotovo')}</button>
            </div>
          )}

          <BlockCanvas blocks={sel.blocks} preview={preview} paletteOpen={paletteOpen} setPaletteOpen={setPaletteOpen}
            patch={patch} remove={remove} dup={dup} move={move} add={add} />
        </section>
      ) : (
        <section className="tpl-editor" style={{display:'flex',alignItems:'center',justifyContent:'center',minHeight:360}}>
          <div style={{textAlign:'center',color:'var(--text-3)',padding:40}}>
            <div style={{width:64,height:64,borderRadius:16,background:'var(--brand-soft)',color:'var(--brand-fg)',display:'flex',alignItems:'center',justifyContent:'center',margin:'0 auto 16px'}}><Icon name="layers" size={30} /></div>
            <h2 style={{margin:'0 0 8px',color:'var(--text-2)',fontSize:20}}>{t('Začni svým prvním onboardingem')}</h2>
            <p style={{margin:'0 0 18px',maxWidth:360,lineHeight:1.5}}>{t('Vytvoř onboarding, poskládej bloky (video, text, kvíz, úkol) a publikuj ho s QR kódem.')}</p>
            <button className="btn btn-primary" onClick={()=>setPicker(true)}><Icon name="plus" />{t('Nový onboarding')}</button>
          </div>
        </section>
      )}

      {share && <ShareModal tpl={share.tpl} shareCode={share.shareCode} onClose={()=>setShare(null)} toast={toast} />}
      {picker && <NewOnboardingModal mine={list} onBlank={createBlank} onTemplate={createFromTemplate} onCopy={(o)=>createWith({name:o.name+' (kopie)',desc:o.desc,icon:o.icon,color:o.color,tag:o.tag,blocks:regenIds(o.blocks)},'copy')} onClose={()=>setPicker(false)} />}
    </div>
  );
}

// ── New-onboarding picker: blank, a starter template, or a copy of your own ─
function NewOnboardingModal({ mine, onBlank, onTemplate, onCopy, onClose }) {
  return (
    <div className="modal-overlay" onClick={onClose}>
      <div className="modal" onClick={e=>e.stopPropagation()} style={{maxWidth:560}}>
        <div className="modal-head">
          <div style={{width:40,height:40,borderRadius:10,background:'var(--brand-soft)',color:'var(--brand-fg)',display:'flex',alignItems:'center',justifyContent:'center'}}><Icon name="layers" size={22} /></div>
          <div><h3>{t('Nový onboarding')}</h3><div style={{fontSize:13,color:'var(--text-2)',marginTop:2}}>{t('Začni od nuly, z připraveného vzoru, nebo navaž na svůj.')}</div></div>
          <button className="modal-x" onClick={onClose}><Icon name="x" size={20} /></button>
        </div>
        <div className="modal-body">
          <button className="pick-row pick-blank" onClick={onBlank}>
            <span className="pick-ico" style={{background:'var(--surface-3)',color:'var(--text-2)'}}><Icon name="plus" size={20} /></span>
            <span><span className="pick-name">{t('Prázdný onboarding')}</span><span className="pick-sub">{t('Začni s čistým plátnem.')}</span></span>
          </button>

          <div className="pick-label">{t('Připravené vzory')}</div>
          <div className="pick-grid">
            {TEMPLATES.map(tp => (
              <button key={tp.id} className="pick-row" onClick={()=>onTemplate(tp)}>
                <span className="pick-ico" style={{background:tp.color}}><Icon name={tp.icon} size={18} /></span>
                <span><span className="pick-name">{tp.name}</span><span className="pick-sub">{tf('{0} bloků · {1}', tp.blocks.length, t(tp.tag))}</span></span>
              </button>
            ))}
          </div>

          {mine.length > 0 && <>
            <div className="pick-label">{t('Navázat na svůj onboarding')}</div>
            <div className="pick-grid">
              {mine.map(o => (
                <button key={o.id} className="pick-row" onClick={()=>onCopy(o)}>
                  <span className="pick-ico" style={{background:o.color}}><Icon name={o.icon} size={18} /></span>
                  <span><span className="pick-name">{o.name}</span><span className="pick-sub">{tf('kopie · {0} bloků', o.blocks.length)}</span></span>
                </button>
              ))}
            </div>
          </>}
        </div>
      </div>
    </div>
  );
}

// ── Demo editor (sample templates for the unauthenticated prototype) ─
function TemplatesDemo({ toast, onLogin, onRegister }) {
  const [selId, setSelId] = useState(TEMPLATES[0].id);
  const [store, setStore] = useState(() => Object.fromEntries(TEMPLATES.map(t => [t.id, t.blocks.map(b => ({...b}))])));
  const [preview, setPreview] = useState(false);
  const [paletteOpen, setPaletteOpen] = useState(false);

  const tpl = TEMPLATES.find(t => t.id === selId);
  const blocks = store[selId];
  const setBlocks = (fn) => setStore(s => ({ ...s, [selId]: fn(s[selId]) }));
  const patch = (id, p) => setBlocks(bs => bs.map(b => b.id===id ? {...b, ...p} : b));
  const remove = (id) => setBlocks(bs => bs.filter(b => b.id!==id));
  const dup = (id) => setBlocks(bs => { const i=bs.findIndex(b=>b.id===id); const c={...bs[i], id:'b'+Math.random().toString(36).slice(2,8)}; const n=[...bs]; n.splice(i+1,0,c); return n; });
  const move = (id, dir) => setBlocks(bs => { const i=bs.findIndex(b=>b.id===id); const j=i+dir; if(j<0||j>=bs.length) return bs; const n=[...bs]; [n[i],n[j]]=[n[j],n[i]]; return n; });
  const add = (type) => { setBlocks(bs => [...bs, newBlock(type)]); setPaletteOpen(false); toast(tf('{0} přidán do šablony.', meta(type).label)); };

  return (
    <div className="tpl-layout">
      <aside className="tpl-rail">
        <div className="live-panel" style={{marginBottom:14,padding:'12px 14px',display:'flex',gap:10,alignItems:'center'}}>
          <Icon name="user" size={18} />
          <div style={{flex:1,fontSize:12.5,color:'var(--text-2)',lineHeight:1.4}}>{t('Tohle jsou')} <strong>{t('ukázkové')}</strong> {t('šablony. Vytvoř si vlastní společenství a pracuj s vlastními.')}</div>
        </div>
        <div className="sr-section-title" style={{marginBottom:12}}>{t('Ukázkové šablony')}</div>
        {TEMPLATES.map(tp => (
          <button key={tp.id} className={'tpl-card'+(tp.id===selId?' on':'')} onClick={()=>{setSelId(tp.id);setPreview(false);setPaletteOpen(false);}}>
            <span className="tpl-ico" style={{background:tp.color}}><Icon name={tp.icon} size={18} /></span>
            <span className="tpl-card-body"><span className="tpl-card-name">{tp.name}</span><span className="tpl-card-meta">{tf('{0} bloků', store[tp.id].length)}</span></span>
          </button>
        ))}
        <button className="btn btn-primary" style={{width:'100%',marginTop:10,justifyContent:'center'}} onClick={onRegister}><Icon name="community" />{t('Vytvořit společenství')}</button>
        <button className="btn btn-ghost" style={{width:'100%',marginTop:8,justifyContent:'center'}} onClick={onLogin}><Icon name="user" />{t('Přihlásit se')}</button>
      </aside>

      <section className="tpl-editor">
        <div className="tpl-editor-head">
          <span className="tpl-ico lg" style={{background:tpl.color}}><Icon name={tpl.icon} size={22} /></span>
          <div style={{flex:1,minWidth:0}}>
            <div style={{display:'flex',alignItems:'center',gap:10}}><h2 style={{margin:0,fontSize:20}}>{tpl.name}</h2><span className="chip" style={{background:'var(--surface-2)',color:'var(--text-2)'}}>{t(tpl.tag)}</span></div>
            <p style={{margin:'4px 0 0',color:'var(--text-2)',fontSize:13.5,maxWidth:560}}>{tpl.desc}</p>
          </div>
          <div style={{display:'flex',gap:8,flexShrink:0}}>
            <button className={'btn btn-ghost'+(preview?' on':'')} onClick={()=>setPreview(p=>!p)}><Icon name="eye" />{preview?t('Editor'):t('Náhled')}</button>
            <button className="btn btn-primary" onClick={onLogin}><Icon name="rocket" />{t('Publikovat & sdílet')}</button>
          </div>
        </div>
        <BlockCanvas blocks={blocks} preview={preview} paletteOpen={paletteOpen} setPaletteOpen={setPaletteOpen}
          patch={patch} remove={remove} dup={dup} move={move} add={add} />
      </section>
    </div>
  );
}

// Per-type block body (preview + edit)
function BlockBody({ block:b, preview, patch }) {
  if (b.type==='text') {
    return preview
      ? <p className="blk-text">{b.body}</p>
      : <textarea className="blk-area" rows={3} value={b.body} onChange={e=>patch(b.id,{body:e.target.value})} />;
  }
  if (b.type==='video') return <VideoBlock block={b} preview={preview} patch={patch} />;
  if (b.type==='image') return <ImageBlock block={b} preview={preview} patch={patch} />;
  if (b.type==='choice') return <ChoiceBlock block={b} preview={preview} patch={patch} />;
  if (b.type==='task') {
    return (
      <div className="blk-task">
        <span className="tdot" style={{borderColor:'var(--brand)'}} />
        {preview
          ? <span className="blk-task-desc">{b.desc}</span>
          : <input className="blk-line" value={b.desc} onChange={e=>patch(b.id,{desc:e.target.value})} placeholder={t('Co má nováček udělat')} />}
      </div>
    );
  }
  if (b.type==='quiz') {
    const setOpt = (i, p) => patch(b.id, { options: b.options.map((o,j)=>j===i?{...o,...p}:o) });
    const setCorrect = (i) => patch(b.id, { options: b.options.map((o,j)=>({...o,correct:j===i})) });
    const addOpt = () => patch(b.id, { options:[...b.options, {label:t('Další možnost'),correct:false}] });
    return (
      <div className="blk-quiz">
        {preview
          ? <div className="blk-q">{b.question}</div>
          : <input className="blk-line" style={{fontWeight:600}} value={b.question} onChange={e=>patch(b.id,{question:e.target.value})} placeholder={t('Otázka?')} />}
        {b.options.map((o,i)=>(
          <div key={i} className={'blk-q-opt'+(o.correct?' correct':'')}>
            <button className="blk-q-radio" onClick={()=>!preview&&setCorrect(i)} title={t('Označit jako správnou')} style={{cursor:preview?'default':'pointer'}}>
              {o.correct ? <Icon name="check" size={13} /> : null}
            </button>
            {preview
              ? <span>{o.label}</span>
              : <input className="blk-line" value={o.label} onChange={e=>setOpt(i,{label:e.target.value})} />}
          </div>
        ))}
        {!preview && <button className="blk-q-add" onClick={addOpt}><Icon name="plus" size={13} />{t('Přidat možnost')}</button>}
      </div>
    );
  }
  if (b.type==='section') {
    if (preview) {
      return (
        <div className="blk-section-prev">
          <span className="blk-section-flag" style={{color:'var(--brand)'}}><Icon name="flag" size={15} /></span>
          <div className="blk-section-txt">
            <div className="blk-section-title">{b.title || t('Část cesty')}</div>
            {b.subtitle && <div className="blk-section-sub">{b.subtitle}</div>}
          </div>
        </div>
      );
    }
    return (
      <div className="blk-section">
        <div className="blk-line-ico"><Icon name="flag" size={15} />
          <input className="blk-line" value={b.title||''} onChange={e=>patch(b.id,{title:e.target.value})} placeholder={t('Část cesty')} />
        </div>
        <textarea className="blk-area" rows={2} style={{marginTop:8}} value={b.subtitle||''} onChange={e=>patch(b.id,{subtitle:e.target.value})} placeholder={t('Podnadpis')} />
      </div>
    );
  }
  if (b.type==='link') {
    const channels = (typeof window!=='undefined' && window.LINK_CHANNELS) || [];
    const ch = channels.find(c => c.key===b.channel) || channels[0] || { label:'', icon:'link', color:'var(--brand)' };
    if (preview) {
      return (
        <div className="blk-link-prev">
          <span className="blk-link-btn" style={{background:ch.color}}>
            <Icon name={ch.icon} size={15} />
            <span>{b.label || t('Tlačítko')}</span>
          </span>
        </div>
      );
    }
    return (
      <div className="blk-link">
        <input className="blk-line" value={b.label||''} onChange={e=>patch(b.id,{label:e.target.value})} placeholder={t('Tlačítko')} />
        <input className="blk-line" style={{marginTop:8}} value={b.url||''} onChange={e=>patch(b.id,{url:e.target.value})} placeholder={t('https://… (nechte prázdné pro odkaz v Believeru)')} />
        <div className="blk-link-channels" style={{display:'flex',gap:6,flexWrap:'wrap',marginTop:8}}>
          {channels.map(c => (
            <button key={c.key} type="button" onClick={()=>patch(b.id,{channel:c.key})}
              className="blk-link-ch"
              style={{display:'inline-flex',alignItems:'center',gap:5,padding:'5px 10px',borderRadius:8,
                border:'1.5px solid '+(b.channel===c.key?c.color:'var(--border)'),
                background:b.channel===c.key?c.color:'transparent',
                color:b.channel===c.key?'#fff':'var(--text-2)',cursor:'pointer',fontWeight:600,fontSize:13}}
              title={t('Kanál')}>
              <Icon name={c.icon} size={14} />{t(c.label)}
            </button>
          ))}
        </div>
      </div>
    );
  }
  return null;
}

// Resize an image file to a bounded JPEG data URL (keeps onboarding JSON small).
function fileToResizedDataUrl(file, maxDim, quality, cb){
  const reader = new FileReader();
  reader.onload = () => {
    const img = new Image();
    img.onload = () => {
      const scale = Math.min(1, maxDim / Math.max(img.width, img.height));
      const w = Math.round(img.width * scale), h = Math.round(img.height * scale);
      const c = document.createElement('canvas'); c.width = w; c.height = h;
      c.getContext('2d').drawImage(img, 0, 0, w, h);
      try { cb(c.toDataURL('image/jpeg', quality)); } catch { cb(reader.result); }
    };
    img.onerror = () => cb(reader.result);
    img.src = reader.result;
  };
  reader.readAsDataURL(file);
}

// Image block — upload from device (auto-resized) or paste a URL.
function ImageBlock({ block:b, preview, patch }){
  const inputRef = useRef();
  const [busy, setBusy] = useState(false);
  const onFile = (e) => {
    const f = e.target.files && e.target.files[0];
    e.target.value = '';
    if (!f) return;
    if (!/^image\//.test(f.type)) return;
    setBusy(true);
    fileToResizedDataUrl(f, 1280, 0.82, (url) => { patch(b.id, { url }); setBusy(false); });
  };
  return (
    <div className="blk-image">
      <div className={'blk-image-ph'+(b.url?' has':'')} onClick={()=>!preview && inputRef.current && inputRef.current.click()}
        style={{cursor:preview?'default':'pointer'}} title={preview?null:t('Klikni a nahraj obrázek')}>
        {b.url
          ? <img src={b.url} alt={b.caption||''} className="blk-image-img" />
          : <div className="blk-image-empty">{busy ? t('Nahrávám…') : <><Icon name="image" size={26} /><span>{preview?t('Bez obrázku'):t('Klikni a nahraj obrázek')}</span></>}</div>}
        {!preview && b.url && <button className="blk-image-change" onClick={(e)=>{e.stopPropagation();inputRef.current.click();}}><Icon name="refresh" size={13} />{t('Změnit')}</button>}
      </div>
      <input ref={inputRef} type="file" accept="image/*" style={{display:'none'}} onChange={onFile} />
      {!preview && (
        <>
          <div className="blk-line-ico" style={{marginTop:8}}><Icon name="list" size={15} />
            <input className="blk-line" value={/^data:/.test(b.url||'')?'':(b.url||'')} onChange={e=>patch(b.id,{url:e.target.value})} placeholder={t('…nebo vlož odkaz na obrázek (https://…)')} />
          </div>
          <input className="blk-line" style={{marginTop:8}} value={b.caption||''} onChange={e=>patch(b.id,{caption:e.target.value})} placeholder={t('Popisek obrázku')} />
        </>
      )}
      {preview && b.caption && <div className="blk-cap">{b.caption}</div>}
    </div>
  );
}

// Choice block — a fork where the newcomer picks which branch (path) to follow.
const newBranch = () => ({ id:'br'+Math.random().toString(36).slice(2,8), label:t('Nová cesta'), icon:'sparkle', color:'#253D83', blocks:[] });
const BRANCH_BLOCK_TYPES = BLOCK_TYPES.filter(t => t.type !== 'choice'); // no nested forks

function ChoiceBlock({ block:b, preview, patch }){
  const [paletteFor, setPaletteFor] = useState(null);
  const branches = b.branches || [];
  const meta = (type) => BLOCK_TYPES.find(x => x.type === type);
  const setBranches = (fn) => patch(b.id, { branches: fn(branches) });
  const patchBranch = (bid, p) => setBranches(brs => brs.map(br => br.id===bid ? {...br, ...p} : br));
  const cycleIcon = (bid) => setBranches(brs => brs.map(br => {
    if (br.id!==bid) return br;
    const i = BRANCH_PRESETS.findIndex(p => p.icon===br.icon);
    const nx = BRANCH_PRESETS[(i+1) % BRANCH_PRESETS.length];
    return {...br, icon:nx.icon, color:nx.color};
  }));
  const addBranch = () => setBranches(brs => [...brs, newBranch()]);
  const removeBranch = (bid) => setBranches(brs => brs.length<=2 ? brs : brs.filter(br => br.id!==bid));
  const addBlk = (bid, type) => { setBranches(brs => brs.map(br => br.id===bid ? {...br, blocks:[...(br.blocks||[]), newBlock(type)]} : br)); setPaletteFor(null); };
  const patchBlkOf = (bid) => (sid, p) => setBranches(brs => brs.map(br => br.id===bid ? {...br, blocks:br.blocks.map(s => s.id===sid ? {...s, ...p} : s)} : br));
  const removeBlk = (bid, sid) => setBranches(brs => brs.map(br => br.id===bid ? {...br, blocks:br.blocks.filter(s => s.id!==sid)} : br));

  if (preview) {
    return (
      <div className="choice-prev">
        <div className="choice-q"><Icon name="signpost" size={16} />{t('Nováček si volí cestu')}</div>
        <div className="choice-branches">
          {branches.map(br => (
            <div key={br.id} className="choice-branch-prev" style={{borderColor:br.color}}>
              <span className="choice-bico" style={{background:br.color}}><Icon name={br.icon} size={16} /></span>
              <span style={{fontWeight:700}}>{br.label}</span>
              <span style={{marginLeft:'auto',fontSize:12,color:'var(--text-3)'}}>{tf('{0} bloků', (br.blocks||[]).length)}</span>
            </div>
          ))}
        </div>
      </div>
    );
  }

  return (
    <div className="choice-edit">
      <div className="choice-hint"><Icon name="signpost" size={13} />{t('Název bloku výše je otázka na rozcestí. Nováček si zvolí jednu cestu — započítají se mu úkoly jen z ní.')}</div>
      {branches.map(br => (
        <div key={br.id} className="choice-branch" style={{['--bc']:br.color}}>
          <div className="choice-branch-head">
            <button className="choice-bico" style={{background:br.color}} onClick={()=>cycleIcon(br.id)} title={t('Změnit ikonu a barvu')}><Icon name={br.icon} size={16} /></button>
            <input className="blk-line" style={{fontWeight:700}} value={br.label} onChange={e=>patchBranch(br.id,{label:e.target.value})} placeholder={t('Název cesty')} />
            <button className="choice-del" disabled={branches.length<=2} onClick={()=>removeBranch(br.id)} title={branches.length<=2?t('Musí zůstat aspoň 2 cesty'):t('Smazat cestu')}><Icon name="trash" size={14} /></button>
          </div>
          <div className="choice-branch-body">
            {(br.blocks||[]).map(sb => { const m = meta(sb.type); return (
              <div key={sb.id} className="choice-subblk">
                <div className="choice-subhead">
                  <span className="blk-type" style={{color:m.color}}><Icon name={m.icon} size={12} /> {m.label}</span>
                  <button className="choice-del" onClick={()=>removeBlk(br.id, sb.id)} title={t('Smazat blok')}><Icon name="trash" size={13} /></button>
                </div>
                <input className="blk-title-input" style={{fontSize:14}} value={sb.title} onChange={e=>patchBlkOf(br.id)(sb.id,{title:e.target.value})} placeholder={t('Název bloku')} />
                <BlockBody block={sb} preview={false} patch={patchBlkOf(br.id)} />
              </div>
            ); })}
            {(br.blocks||[]).length===0 && <div className="choice-empty">{t('Zatím prázdná cesta — přidej první blok.')}</div>}
            {paletteFor===br.id ? (
              <div className="choice-palette">
                {BRANCH_BLOCK_TYPES.map(bt => (
                  <button key={bt.type} className="blk-opt" onClick={()=>addBlk(br.id, bt.type)}>
                    <span className="blk-badge" style={{background:bt.color}}><Icon name={bt.icon} size={14} /></span>
                    <span className="blk-opt-name">{bt.label}</span>
                  </button>
                ))}
                <button className="choice-cancel" onClick={()=>setPaletteFor(null)}><Icon name="x" size={14} />{t('Zavřít')}</button>
              </div>
            ) : (
              <button className="choice-addblk" onClick={()=>setPaletteFor(br.id)}><Icon name="plus" size={14} />{t('Přidat blok do této cesty')}</button>
            )}
          </div>
        </div>
      ))}
      <button className="choice-addbranch" onClick={addBranch}><Icon name="plus" size={15} />{t('Přidat cestu')}</button>
    </div>
  );
}

// Parse a YouTube ID from common URL shapes (watch, youtu.be, embed, shorts).
function youtubeId(url){
  if(!url) return null;
  const m = String(url).match(/(?:youtu\.be\/|youtube\.com\/(?:watch\?(?:.*&)?v=|embed\/|shorts\/))([\w-]{11})/);
  return m ? m[1] : (/^[\w-]{11}$/.test(url.trim()) ? url.trim() : null);
}

// Video block — supports a real YouTube embed (thumbnail → click to play).
function VideoBlock({ block:b, preview, patch }){
  const [playing, setPlaying] = useState(false);
  const yt = youtubeId(b.url);
  return (
    <div className="blk-video">
      <div className="blk-video-thumb" onClick={()=>yt && setPlaying(true)} style={{cursor:yt?'pointer':'default'}}
        title={yt?t('Přehrát video'):null}>
        {playing && yt ? (
          <iframe className="blk-video-frame" src={`https://www.youtube.com/embed/${yt}?autoplay=1&rel=0`}
            title={b.title} frameBorder="0" allow="autoplay; encrypted-media; picture-in-picture" allowFullScreen />
        ) : (
          <>
            {yt && <img className="blk-video-img" src={`https://i.ytimg.com/vi/${yt}/hqdefault.jpg`} alt="" />}
            <span className="blk-play"><Icon name="play" size={20} /></span>
            {b.duration && <span className="blk-dur">{b.duration}</span>}
            {yt && <span className="blk-yt"><Icon name="video" size={13} />YouTube</span>}
          </>
        )}
      </div>
      {preview ? (
        <div className="blk-video-src">{b.source}{!yt && b.url ? ' · '+b.url : ''}</div>
      ) : (
        <div className="blk-video-edit">
          <div className="blk-line-ico"><Icon name="video" size={15} />
            <input className="blk-line" value={b.url||''} onChange={e=>patch(b.id,{url:e.target.value})} placeholder={t('Vlož odkaz na YouTube video (youtube.com/watch?v=… nebo youtu.be/…)')} />
          </div>
          <div className="blk-video-row">
            <input className="blk-line" value={b.source} onChange={e=>patch(b.id,{source:e.target.value})} placeholder={t('Popisek zdroje (kdo / co)')} />
            <input className="blk-line blk-line-sm" value={b.duration} onChange={e=>patch(b.id,{duration:e.target.value})} placeholder={t('Délka 0:00')} />
          </div>
          {b.url && !yt && <div className="blk-warn"><Icon name="alert" size={13} />{t('Tohle nevypadá jako YouTube odkaz — zkontroluj ho.')}</div>}
        </div>
      )}
    </div>
  );
}

// ── Analytics switch: real data when logged in, demo otherwise ─
function Analytics(props) {
  const [tok, setTok] = useState(api.token());
  useEffect(() => { setTok(api.token()); }, [props.authTick]);
  useEffect(() => { const h = () => setTok(api.token()); window.addEventListener('believer-auth', h); return () => window.removeEventListener('believer-auth', h); }, []);
  return tok ? <RealAnalytics {...props} /> : <DemoAnalytics {...props} />;
}

// ── Real analytics (computed from live backend data) ─────────
function RealAnalytics({ authTick, toast }) {
  const [rows, setRows] = useState([]);
  const [obsAgg, setObsAgg] = useState([]);
  const [loaded, setLoaded] = useState(false);
  const sigRef = useRef('');

  useEffect(() => {
    let alive = true;
    const tick = async () => {
      if (document.hidden) return;
      const res = await fetchPublishedNewcomers();
      if (!res || !alive) return;
      const all = res.rows;
      const agg = res.onboardings.filter(o => o.published).map(o => {
        const ncs = all.filter(n => n.onb === o.name);
        return { label: o.name, value: ncs.length ? Math.round(ncs.reduce((a,n)=>a+n.pct,0)/ncs.length) : 0, color: o.color };
      });
      const sig = JSON.stringify({ all, agg });
      if (sig === sigRef.current) { if (!loaded) setLoaded(true); return; }
      sigRef.current = sig;
      setRows(all); setObsAgg(agg); setLoaded(true);
    };
    tick(); const id = setInterval(tick, 8000);
    const onVis = () => { if (!document.hidden) tick(); };
    document.addEventListener('visibilitychange', onVis);
    return () => { alive = false; clearInterval(id); document.removeEventListener('visibilitychange', onVis); };
  }, [authTick]);

  const idleOf = (n) => (Date.now()-new Date(n.lastActive).getTime())/86400000 >= 7;
  const done = rows.filter(n=>n.pct===100).length;
  const idle = rows.filter(idleOf).length;
  const prog = rows.length - done - idle;
  const avg = rows.length ? Math.round(rows.reduce((a,n)=>a+n.pct,0)/rows.length) : 0;
  // Rozšířené metriky pro vedení společenství
  const daysBetween = (a,b) => (new Date(b).getTime()-new Date(a).getTime())/86400000;
  const completionRate = rows.length ? Math.round(done/rows.length*100) : 0;
  const started = rows.filter(n=>n.doneTasks>0).length;            // aktivace = splnil aspoň 1 krok
  const activationRate = rows.length ? Math.round(started/rows.length*100) : 0;
  const completedRows = rows.filter(n=>n.pct===100);
  const avgDaysComplete = completedRows.length ? completedRows.reduce((a,n)=>a+Math.max(0,daysBetween(n.joinedAt,n.lastActive)),0)/completedRows.length : null;
  const new7  = rows.filter(n=>daysBetween(n.joinedAt,Date.now())<=7).length;
  const new30 = rows.filter(n=>daysBetween(n.joinedAt,Date.now())<=30).length;
  const fmtDays = (d) => d==null ? '—' : d<1 ? t('<1 den') : (Math.round(d*10)/10)+(d<1.5?' '+t('den'):d<5?' '+t('dny'):' '+t('dní'));
  // Rozložení podle zvoleného směru z rozcestníku
  const pathMap = {};
  rows.forEach(n => { if (n.chosenPath) { const k=n.chosenPath.label; (pathMap[k] = pathMap[k] || {label:k,value:0,color:n.chosenPath.color||'#253D83'}).value++; } });
  const pathDist = Object.values(pathMap).sort((a,b)=>b.value-a.value);
  const chosenCount = pathDist.reduce((a,p)=>a+p.value,0);
  const funnel = [
    { label:t('Připojili se'),        value: rows.length, color:'#253D83' },
    { label:t('Začali (1+ krok)'),    value: started,     color:'#3E7CB1' },
    { label:t('Dokončili cestu'),     value: done,        color:'#107C41' },
  ];

  const exportCSV = () => {
    const head = [t('Nováček'),'Onboarding',t('Telefon'),t('E-mail'),t('Dokončeno %'),t('Splněné úkoly'),t('Celkem úkolů'),t('Stav'),t('Zvolený směr'),t('Připojen'),t('Poslední aktivita')];
    const cell = (v) => '"' + String(v ?? '').replace(/"/g,'""') + '"';
    const stav = (n) => n.pct===100 ? t('Dokončeno') : idleOf(n) ? t('Bez aktivity') : t('Probíhá');
    const lines = [head.map(cell).join(',')].concat(rows.map(n => [
      n.name, n.onb, n.phone||'', n.email||'', n.pct, n.doneTasks, n.totalTasks, stav(n), n.chosenPath?n.chosenPath.label:'', n.joinedAt, n.lastActive
    ].map(cell).join(',')));
    const blob = new Blob(['﻿' + lines.join('\r\n')], { type: 'text/csv;charset=utf-8' });
    const a = document.createElement('a');
    a.href = URL.createObjectURL(blob);
    a.download = 'believer-onboarding-nováčci.csv';
    a.click(); URL.revokeObjectURL(a.href);
    window.track && window.track('analytics_export', { format: 'csv', rows: rows.length });
  };

  const exportPDF = () => {
    const esc = (s) => String(s ?? '').replace(/[&<>]/g, c => ({ '&':'&amp;','<':'&lt;','>':'&gt;' }[c]));
    const comm = (api.getProfile()?.community?.name) || t('Společenství');
    const when = new Date().toLocaleString(window.LOCALE==='en'?'en-GB':'cs-CZ');
    const stav = (n) => n.pct===100 ? t('Dokončeno') : idleOf(n) ? t('Bez aktivity') : t('Probíhá');
    const ncRows = rows.map(n => `<tr><td>${esc(n.name)}</td><td>${esc(n.onb)}</td><td class="r">${n.pct}%</td><td class="r">${n.doneTasks}/${n.totalTasks}</td><td>${stav(n)}</td><td>${esc(n.chosenPath?n.chosenPath.label:'—')}</td><td>${esc(n.email||n.phone||'—')}</td></tr>`).join('');
    const aggRows = obsAgg.map(a => `<tr><td>${esc(a.label)}</td><td class="r">${a.value} %</td></tr>`).join('');
    const pathRows = pathDist.map(pth => `<tr><td>${esc(pth.label)}</td><td class="r">${pth.value}</td><td class="r">${chosenCount?Math.round(pth.value/chosenCount*100):0} %</td></tr>`).join('');
    const html = `<!doctype html><html lang="${window.LOCALE==='en'?'en':'cs'}"><head><meta charset="utf-8"><title>${t('Believer · Report onboardingu')}</title>
      <style>
        @page{margin:18mm}
        *{box-sizing:border-box} body{font-family:'Segoe UI',-apple-system,system-ui,sans-serif;color:#1F1E1D;margin:0}
        .head{display:flex;align-items:baseline;justify-content:space-between;border-bottom:2px solid #253D83;padding-bottom:10px;margin-bottom:18px}
        .head h1{font-size:20px;margin:0;color:#253D83} .head .sub{font-size:12px;color:#605E5C}
        .cards{display:flex;gap:12px;margin-bottom:22px}
        .card{flex:1;border:1px solid #E6E4E2;border-radius:10px;padding:12px 14px}
        .card .l{font-size:11px;color:#605E5C} .card .v{font-size:24px;font-weight:800}
        h2{font-size:14px;color:#253D83;margin:18px 0 8px}
        table{width:100%;border-collapse:collapse;font-size:12px} th,td{text-align:left;padding:7px 8px;border-bottom:1px solid #E6E4E2}
        th{background:#F4F3F2;font-size:10px;text-transform:uppercase;letter-spacing:.04em;color:#605E5C} td.r,th.r{text-align:right}
        .foot{margin-top:24px;font-size:10px;color:#8A8784;text-align:center}
      </style></head><body>
      <div class="head"><h1>${tf('Report onboardingu — {0}', esc(comm))}</h1><div class="sub">${tf('Vygenerováno {0}', esc(when))}</div></div>
      <div class="cards">
        <div class="card"><div class="l">${t('Průměrné dokončení')}</div><div class="v">${avg} %</div></div>
        <div class="card"><div class="l">${t('Aktivních nováčků')}</div><div class="v">${rows.length}</div></div>
        <div class="card"><div class="l">${t('Dokončili cestu')}</div><div class="v">${done}</div></div>
        <div class="card"><div class="l">${t('Bez aktivity (7+ dní)')}</div><div class="v">${idle}</div></div>
      </div>
      <div class="cards">
        <div class="card"><div class="l">${t('Míra dokončení')}</div><div class="v">${completionRate} %</div></div>
        <div class="card"><div class="l">${t('Míra aktivace')}</div><div class="v">${activationRate} %</div></div>
        <div class="card"><div class="l">${t('Ø doba k dokončení')}</div><div class="v">${fmtDays(avgDaysComplete)}</div></div>
        <div class="card"><div class="l">${t('Noví za 30 dní')}</div><div class="v">${new30}</div></div>
      </div>
      <h2>${t('Aktivační trychtýř')}</h2>
      <table><tbody>
        <tr><td>${t('Připojili se')}</td><td class="r">${rows.length}</td></tr>
        <tr><td>${t('Začali (1+ krok)')}</td><td class="r">${started}</td></tr>
        <tr><td>${t('Dokončili cestu')}</td><td class="r">${done}</td></tr>
      </tbody></table>
      ${pathRows ? `<h2>${t('Kam nováčci míří (rozcestník)')}</h2><table><thead><tr><th>${t('Směr')}</th><th class="r">${t('Počet')}</th><th class="r">${t('Podíl')}</th></tr></thead><tbody>${pathRows}</tbody></table>` : ''}
      ${aggRows ? `<h2>${t('Průměrné dokončení podle onboardingu')}</h2><table><tbody>${aggRows}</tbody></table>` : ''}
      <h2>${tf('Nováčci ({0})', rows.length)}</h2>
      <table><thead><tr><th>${t('Jméno')}</th><th>Onboarding</th><th class="r">${t('Dokončeno')}</th><th class="r">${t('Úkoly')}</th><th>${t('Stav')}</th><th>${t('Směr')}</th><th>${t('Kontakt')}</th></tr></thead>
        <tbody>${ncRows || '<tr><td colspan="7" style="color:#8A8784;text-align:center;padding:18px">'+t('Zatím žádní nováčci.')+'</td></tr>'}</tbody></table>
      <div class="foot">${t('© 2026 Believer s.r.o.')}</div>
      <script>window.onload=function(){setTimeout(function(){window.print();},300);};<\/script>
      </body></html>`;
    const w = window.open('', '_blank');
    if (!w) { toast && toast(t('Povol prosím vyskakovací okna pro export.')); return; }
    w.document.write(html); w.document.close();
    window.track && window.track('analytics_export', { format: 'pdf', rows: rows.length });
  };

  const stats = [
    { label:t('Průměrné dokončení checklistu'), val:avg+' %', sub:t('napříč všemi nováčky'), icon:'chart', c:'var(--brand-soft)', fg:'var(--brand-fg)' },
    { label:t('Aktivních nováčků'), val:rows.length, sub:t('právě teď v procesu'), icon:'users', c:'var(--green-soft)', fg:'var(--green)' },
    { label:t('Dokončili cestu'), val:done, sub:t('na 100 %'), icon:'trophy', c:'var(--accent-soft)', fg:'var(--accent)' },
    { label:t('Nováčci bez aktivity'), val:idle, sub:t('7+ dní bez pohybu'), icon:'alert', c:'var(--amber-soft)', fg:'var(--amber)' },
  ];
  const statusData = [
    { label:t('Probíhá'), value:prog, color:'#253D83' },
    { label:t('Dokončeno'), value:done, color:'#107C41' },
    { label:t('Bez aktivity'), value:idle, color:'#B8860B' },
  ];
  const kpis = [
    { label:t('Míra dokončení'), val:completionRate+' %', sub:tf('{0} z {1} došlo do konce', done, rows.length), icon:'trophy', c:'var(--green-soft)', fg:'var(--green)' },
    { label:t('Míra aktivace'), val:activationRate+' %', sub:tf('{0} splnilo aspoň 1 krok', started), icon:'flame', c:'var(--accent-soft)', fg:'var(--accent)' },
    { label:t('Ø doba k dokončení'), val:fmtDays(avgDaysComplete), sub:t('od připojení ke 100 %'), icon:'clock', c:'var(--brand-soft)', fg:'var(--brand-fg)' },
    { label:t('Noví za 30 dní'), val:new30, sub:tf('{0} z toho za 7 dní', new7), icon:'users', c:'var(--sky-soft)', fg:'var(--brand-fg)' },
  ];

  return (
    <>
      <div className="page-head" style={{marginBottom:18}}>
        <p style={{maxWidth:560}}>{t('Trendy a úspěšnost práce s nováčky — počítáno naživo z reálných dat vašeho společenství.')}</p>
        <div className="ph-actions">
          <button className="btn btn-ghost" onClick={exportPDF} disabled={!rows.length} title={rows.length?t('Vytisknout / uložit report jako PDF'):t('Zatím není co exportovat')}><Icon name="download" />{t('Export PDF')}</button>
          <button className="btn btn-ghost" onClick={exportCSV} disabled={!rows.length} title={rows.length?t('Stáhnout data nováčků jako CSV'):t('Zatím není co exportovat')}><Icon name="download" />{t('Export CSV')}</button>
        </div>
      </div>
      <div className="stat-grid">
        {stats.map((s,i)=>(
          <div className="stat card" key={i}>
            <div style={{display:'flex',justifyContent:'space-between',alignItems:'flex-start'}}>
              <div><div className="s-label">{s.label}</div><div className="s-val">{s.val}</div><div className="s-sub">{s.sub}</div></div>
              <div className="s-ico" style={{background:s.c,color:s.fg}}><Icon name={s.icon} size={19} /></div>
            </div>
          </div>
        ))}
      </div>
      {loaded && rows.length===0 ? (
        <div className="card" style={{display:'flex',flexDirection:'column',alignItems:'center',textAlign:'center',padding:'56px 0',color:'var(--text-3)'}}>
          <div style={{width:64,height:64,borderRadius:16,background:'var(--surface-2)',display:'flex',alignItems:'center',justifyContent:'center',marginBottom:16}}><Icon name="chart" size={30} /></div>
          <h2 style={{margin:'0 0 8px',color:'var(--text-2)',fontSize:20}}>{t('Zatím nejsou žádná data')}</h2>
          <p style={{margin:0,maxWidth:420,lineHeight:1.55}}>{t('Jakmile se k tvým onboardingům připojí první nováčci, uvidíš tady jejich pokrok, rozložení a trendy.')}</p>
        </div>
      ) : (<>
        <div className="stat-grid" style={{marginTop:14}}>
          {kpis.map((s,i)=>(
            <div className="stat card" key={i}>
              <div style={{display:'flex',justifyContent:'space-between',alignItems:'flex-start'}}>
                <div><div className="s-label">{s.label}</div><div className="s-val">{s.val}</div><div className="s-sub">{s.sub}</div></div>
                <div className="s-ico" style={{background:s.c,color:s.fg}}><Icon name={s.icon} size={19} /></div>
              </div>
            </div>
          ))}
        </div>
        <div className="analytics-grid">
          <div className="card chart-card">
            <h3>{t('Nováčci podle stavu')}</h3>
            <p className="csub">{t('Kolik lidí právě probíhá, dokončilo cestu, nebo je bez aktivity.')}</p>
            <div style={{marginTop:8}}><DonutChart data={statusData} /></div>
          </div>
          <div className="card chart-card">
            <h3>{t('Aktivační trychtýř')}</h3>
            <p className="csub">{t('Kolik lidí se připojilo, rozhýbalo a došlo až do konce — kde nováčci odpadávají.')}</p>
            <div style={{marginTop:12,display:'flex',flexDirection:'column',gap:12}}>
              {funnel.map((f,i)=>{
                const pctOfTop = funnel[0].value ? Math.round(f.value/funnel[0].value*100) : 0;
                return (
                  <div key={i}>
                    <div style={{display:'flex',justifyContent:'space-between',fontSize:13,marginBottom:4}}><span style={{fontWeight:600}}>{f.label}</span><span style={{color:'var(--text-3)'}}>{f.value} · {pctOfTop} %</span></div>
                    <div className="pbar"><i style={{width:pctOfTop+'%',background:f.color}}/></div>
                  </div>
                );
              })}
            </div>
          </div>
        </div>
        <div className="analytics-grid">
          <div className="card chart-card">
            <h3>{t('Kam nováčci míří')}</h3>
            <p className="csub">{t('Co si lidé zvolili na závěrečném rozcestníku — dobrý podklad pro plánování služby a skupinek.')}</p>
            {chosenCount ? <BarChart data={pathDist} unit="" /> : <div style={{padding:'24px 0',color:'var(--text-3)',fontSize:13}}>{t('Zatím si nikdo nezvolil směr na rozcestníku. Objeví se tu, jakmile někdo dojde na konec uvítací cesty.')}</div>}
          </div>
          <div className="card chart-card">
            <h3>{t('Průměrné dokončení podle onboardingu')}</h3>
            <p className="csub">{t('Jak si vedou nováčci v jednotlivých onboardinzích.')}</p>
            <BarChart data={obsAgg} unit=" %" />
          </div>
        </div>
      </>)}
    </>
  );
}

// ── Demo analytics (sample data for the unauthenticated prototype) ─
function DemoAnalytics({ toast }) {
  const a = ANALYTICS;
  const stats = [
    { label:t('Průměrné dokončení checklistu'), val:a.avgCompletion+' %', sub:t('napříč všemi nováčky'), icon:'chart', c:'var(--brand-soft)', fg:'var(--brand-fg)' },
    { label:t('Nejrychlejší dokončení'), val:a.fastest, sub:t('od registrace ke 100 %'), icon:'flame', c:'var(--accent-soft)', fg:'var(--accent)' },
    { label:t('Nováčci bez aktivity'), val:a.inactive, sub:t('7+ dní bez pohybu'), icon:'alert', c:'var(--amber-soft)', fg:'var(--amber)' },
    { label:t('Aktivních nováčků'), val:a.activeCount, sub:t('právě teď v procesu'), icon:'users', c:'var(--green-soft)', fg:'var(--green)' },
  ];
  return (
    <>
      <div className="page-head" style={{marginBottom:18}}>
        <p style={{maxWidth:560}}>{t('Trendy a úspěšnost práce s nováčky za poslední 3 měsíce.')}</p>
        <div className="ph-actions">
          <button className="btn btn-ghost" onClick={()=>toast(t('Export do PDF připraven ke stažení.'))}><Icon name="download" />PDF</button>
          <button className="btn btn-ghost" onClick={()=>toast(t('Export do Excelu připraven ke stažení.'))}><Icon name="download" />Excel</button>
        </div>
      </div>
      <div className="stat-grid">
        {stats.map((s,i)=>(
          <div className="stat card" key={i}>
            <div style={{display:'flex',justifyContent:'space-between',alignItems:'flex-start'}}>
              <div><div className="s-label">{s.label}</div><div className="s-val">{s.val}</div><div className="s-sub">{s.sub}</div></div>
              <div className="s-ico" style={{background:s.c,color:s.fg}}><Icon name={s.icon} size={19} /></div>
            </div>
          </div>
        ))}
      </div>
      <div className="analytics-grid" style={{marginBottom:20}}>
        <div className="card chart-card">
          <h3>{t('Počet nováčků podle fáze cesty')}</h3>
          <p className="csub">{t('Kolik lidí se právě nachází v jednotlivých fázích duchovní cesty.')}</p>
          <BarChart data={a.byPhase} unit={' '+t('lidí')} />
        </div>
        <div className="card chart-card">
          <h3>{t('Nejčastěji nedokončené úkoly')}</h3>
          <p className="csub">{t('Které kroky nováčci přeskakují nejvíc.')}</p>
          <div style={{marginTop:8}}><DonutChart data={a.unfinished} /></div>
        </div>
      </div>
      <div className="card chart-card">
        <h3>{t('Průměrné dokončení checklistu v čase')}</h3>
        <p className="csub">{t('Vývoj průměrného procenta dokončení za posledních 5 měsíců — trend roste.')}</p>
        <LineChart data={a.overTime} />
      </div>
    </>
  );
}

// ── Reminders ────────────────────────────────────────────────
// Reminders switch: real idle newcomers when logged in, demo otherwise.
function Reminders(props) {
  const [tok, setTok] = useState(api.token());
  useEffect(() => { setTok(api.token()); }, [props.authTick]);
  useEffect(() => { const h = () => setTok(api.token()); window.addEventListener('believer-auth', h); return () => window.removeEventListener('believer-auth', h); }, []);
  return tok ? <RealReminders {...props} /> : <DemoReminders {...props} />;
}

// ── Real reminders: who to nudge (idle 7+ days), with WhatsApp / E-mail ─
function RealReminders({ toast, authTick }) {
  const [rows, setRows] = useState([]);
  const [loaded, setLoaded] = useState(false);
  const [freq, setFreq] = useState('inactivity');
  const [pastorReminder, setPastorReminder] = useState(true);
  const [compose, setCompose] = useState(null);
  const [dueCount, setDueCount] = useState(null);
  const [saving, setSaving] = useState(false);
  const [sendingEnabled, setSendingEnabled] = useState(false);
  const [testing, setTesting] = useState(false);

  // Load saved reminder settings + a preview of who is due.
  useEffect(() => {
    let alive = true;
    (async () => {
      const s = await api.get('/api/reminders');
      if (s.ok && alive) { setFreq(s.data.freq); setPastorReminder(s.data.pastor); setSendingEnabled(!!s.data.sendingEnabled); }
      const d = await api.get('/api/reminders/due');
      if (d.ok && alive) setDueCount(d.data.due.length);
    })();
    return () => { alive = false; };
  }, [authTick]);

  const sendTest = async () => {
    setTesting(true);
    const r = await api.post('/api/reminders/test', {});
    setTesting(false);
    toast(r.ok ? tf('Testovací e-mail odeslán na {0}.', r.data.to) : (r.data.error || t('Odeslání selhalo.')));
  };

  const saveReminders = async () => {
    setSaving(true);
    const r = await api.post('/api/reminders', { freq, pastor: pastorReminder });
    setSaving(false);
    if (r.ok) { const d = await api.get('/api/reminders/due'); if (d.ok) setDueCount(d.data.due.length); toast(sendingEnabled ? t('Předvolba uložena. Připomínky se nováčkům s e-mailem posílají automaticky.') : t('Předvolba uložena. Automatické odesílání teprve připravujeme.')); }
    else toast(t('Uložení se nepovedlo.'));
  };

  const sigRef = useRef('');
  useEffect(() => {
    let alive = true;
    const tick = async () => {
      if (document.hidden) return;
      const res = await fetchPublishedNewcomers();
      if (!res || !alive) return;
      const sig = JSON.stringify(res.rows);
      if (sig === sigRef.current) { if (!loaded) setLoaded(true); return; }
      sigRef.current = sig;
      setRows(res.rows); setLoaded(true);
    };
    tick(); const id = setInterval(tick, 8000);
    const onVis = () => { if (!document.hidden) tick(); };
    document.addEventListener('visibilitychange', onVis);
    return () => { alive = false; clearInterval(id); document.removeEventListener('visibilitychange', onVis); };
  }, [authTick]);

  const idleDays = (n) => Math.floor((Date.now() - new Date(n.lastActive).getTime()) / 86400000);
  const idle = rows.filter(n => idleDays(n) >= 7 && n.pct < 100);
  const FREQ = [
    { k:'daily', label:t('Denně'), sub:t('každý den ráno') },
    { k:'weekly', label:t('Týdně'), sub:t('pondělní souhrn') },
    { k:'inactivity', label:t('Po nečinnosti'), sub:t('po 3 dnech bez aktivity') },
  ];

  return (
    <>
      <div className="summary-banner">
        <div className="sb-num">{idle.length}</div>
        <div style={{flex:1}}>
          <div style={{fontSize:18,fontWeight:700,marginBottom:3}}>{idle.length===0 ? t('Nikdo nepotřebuje povzbudit') : idle.length===1 ? t('1 člověk potřebuje povzbudit') : idle.length<5 ? tf('{0} lidé potřebují povzbudit', idle.length) : tf('{0} lidí potřebuje povzbudit', idle.length)}</div>
          <div style={{color:'var(--text-2)',fontSize:14}}>{idle.length===0 ? t('Všichni nováčci jsou aktivní — skvělá práce!') : t('Tito nováčci jsou 7+ dní bez aktivity. Krátká zpráva může hodně pomoct.')}</div>
        </div>
      </div>

      <div style={{display:'grid',gridTemplateColumns:'1.5fr 1fr',gap:20,alignItems:'start'}}>
        <div>
          <div className="sr-section-title">{t('Koho oslovit')}</div>
          {!loaded && <div className="card" style={{padding:'30px',textAlign:'center',color:'var(--text-3)'}}>{t('Načítám…')}</div>}
          {loaded && idle.length===0 && <div className="card" style={{padding:'34px',textAlign:'center',color:'var(--text-3)'}}>{t('Zatím nikdo bez aktivity. 🙂')}</div>}
          {idle.map(n=>(
            <div className="rem-card card" key={n.id}>
              <Avatar name={n.name} size={46} />
              <div style={{flex:1,minWidth:0}}>
                <div style={{fontWeight:700,fontSize:15}}>{n.name}</div>
                <div style={{fontSize:13,color:'var(--text-2)',marginTop:2}}>{tf('{0} · {1}/{2} úkolů · aktivní {3}', n.onb, n.doneTasks, n.totalTasks, relTime(n.lastActive))}</div>
              </div>
              <span className="chip idle"><Icon name="clock" />{relTime(n.lastActive)}</span>
              <div style={{display:'flex',gap:7}}>
                {n.phone && <button className="btn btn-wa btn-sm" onClick={()=>setCompose({newcomer:n,channel:'whatsapp'})} title={tf('WhatsApp: {0}', n.phone)}><Icon name="whatsapp" />WhatsApp</button>}
                {n.email && <button className="btn btn-ghost btn-sm" onClick={()=>setCompose({newcomer:n,channel:'email'})} title={tf('E-mail: {0}', n.email)}><Icon name="mail" />{t('E-mail')}</button>}
                {!n.phone && !n.email && <span style={{fontSize:12,color:'var(--text-3)',alignSelf:'center'}}>{t('bez kontaktu')}</span>}
              </div>
            </div>
          ))}
        </div>

        <div className="card" style={{padding:'22px 24px'}}>
          <div className="sr-section-title" style={{marginBottom:14}}>{t('Automatické připomínky')}</div>
          <div style={{fontSize:13.5,color:'var(--text-2)',marginBottom:14}}>{t('Jak často mají nováčci dostávat e-mailem připomínku k dalším krokům.')}</div>
          {FREQ.map(f=>(
            <button key={f.k} onClick={()=>setFreq(f.k)} style={{display:'flex',alignItems:'center',gap:12,width:'100%',textAlign:'left',padding:'12px 14px',borderRadius:10,border:'1px solid '+(freq===f.k?'var(--brand)':'var(--border-2)'),background:freq===f.k?'var(--brand-soft)':'transparent',marginBottom:9,color:'var(--text)'}}>
              <span style={{width:18,height:18,borderRadius:'50%',border:'2px solid '+(freq===f.k?'var(--brand)':'var(--border-2)'),display:'flex',alignItems:'center',justifyContent:'center',flexShrink:0}}>{freq===f.k && <span style={{width:8,height:8,borderRadius:'50%',background:'var(--brand)'}}/>}</span>
              <span style={{flex:1}}><span style={{fontWeight:600,fontSize:14}}>{f.label}</span><span style={{display:'block',fontSize:12,color:'var(--text-3)'}}>{f.sub}</span></span>
            </button>
          ))}
          <label style={{display:'flex',alignItems:'center',gap:12,marginTop:14,paddingTop:16,borderTop:'1px solid var(--border)',cursor:'pointer'}}>
            <span onClick={()=>setPastorReminder(v=>!v)} style={{width:42,height:24,borderRadius:999,background:pastorReminder?'var(--brand)':'var(--border-2)',position:'relative',transition:'.2s',flexShrink:0}}>
              <span style={{position:'absolute',top:2,left:pastorReminder?20:2,width:20,height:20,borderRadius:'50%',background:'#fff',transition:'.2s',boxShadow:'0 1px 3px rgba(0,0,0,.3)'}}/>
            </span>
            <span style={{fontSize:13.5}}>{t('Připomínat i mně (pastorovi), koho povzbudit')}</span>
          </label>
          <div style={{display:'flex',gap:9,alignItems:'flex-start',borderRadius:9,padding:'10px 12px',marginTop:14,fontSize:12.5,lineHeight:1.45,background:sendingEnabled?'var(--green-soft)':'var(--amber-soft)',color:sendingEnabled?'var(--green)':'var(--amber)'}}>
            <Icon name={sendingEnabled?'checkCircle':'alert'} size={16} style={{flexShrink:0,marginTop:1}} />
            <span>{sendingEnabled
              ? <>{t('Odesílání')} <strong>{t('aktivní')}</strong> {t('(e-mail přes Resend). Připomínky chodí nováčkům, kteří zadali e-mail.')}</>
              : <>{t('Odesílání')} <strong>{t('zatím vypnuté')}</strong> {t('(chybí napojení e-mailu). Tady si jen předvolíš frekvenci. Nováčky zatím oslovuj ručně vlevo.')}</>}</span>
          </div>
          {dueCount!=null && freq!=='off' && <div style={{marginTop:10,fontSize:12.5,color:'var(--text-2)',background:'var(--surface-2)',borderRadius:9,padding:'10px 12px'}}><Icon name="clock" size={14} style={{verticalAlign:'-2px',marginRight:6}} />{t('Při dnešním nastavení by připomínku dostalo')} <strong>{dueCount}</strong> {dueCount===1?t('nováček'):dueCount<5?t('nováčci'):t('nováčků')}.</div>}
          <div style={{display:'flex',gap:8,marginTop:14}}>
            <button className="btn btn-primary" style={{flex:1}} disabled={saving} onClick={saveReminders}>{saving?t('Ukládám…'):t('Uložit')}</button>
            {sendingEnabled && <button className="btn btn-ghost" disabled={testing} onClick={sendTest} title={t('Poslat testovací e-mail na tvou adresu')}>{testing?t('Posílám…'):t('Test e-mailu')}</button>}
          </div>
        </div>
      </div>
      {compose && <ContactComposeModal newcomer={compose.newcomer} channel={compose.channel} onClose={()=>setCompose(null)} toast={toast} />}
    </>
  );
}

function DemoReminders({ onContact, toast }) {
  const idle = PEOPLE.filter(p=>p.status==='idle');
  const [pastorReminder, setPastorReminder] = useState(true);
  const [freq, setFreq] = useState('inactivity');
  const FREQ = [
    { k:'daily', label:t('Denně'), sub:t('každý den ráno') },
    { k:'weekly', label:t('Týdně'), sub:t('pondělní souhrn') },
    { k:'inactivity', label:t('Po nečinnosti'), sub:t('po 3 dnech bez aktivity') },
  ];
  return (
    <>
      <div className="summary-banner">
        <div className="sb-num">{idle.length}</div>
        <div style={{flex:1}}>
          <div style={{fontSize:18,fontWeight:700,marginBottom:3}}>{tf('{0} lidé potřebují povzbudit', idle.length)}</div>
          <div style={{color:'var(--text-2)',fontSize:14}}>{t('Tito nováčci jsou 7+ dní bez aktivity. Krátká zpráva může hodně pomoct.')}</div>
        </div>
      </div>

      <div style={{display:'grid',gridTemplateColumns:'1.5fr 1fr',gap:20,alignItems:'start'}}>
        <div>
          <div className="sr-section-title">{t('Koho oslovit')}</div>
          {idle.map(p=>(
            <div className="rem-card card" key={p.id}>
              <Avatar name={p.name} size={46} />
              <div style={{flex:1,minWidth:0}}>
                <div style={{fontWeight:700,fontSize:15}}>{p.name}</div>
                <div style={{fontSize:13,color:'var(--text-2)',marginTop:2}}>{tf('{0} · zasekl{1} se na ', p.group, p.name.endsWith('á')?'a':'')}<strong>{PHASES.find(f=>f.key===p.phase).name}</strong>{tf(' · aktivní {0}', p.last)}</div>
              </div>
              <span className="chip idle"><Icon name="clock" />{p.last}</span>
              <button className="btn btn-primary btn-sm" onClick={()=>onContact(p)}><Icon name="mail" />{t('Povzbudit')}</button>
            </div>
          ))}
          <div style={{display:'flex',gap:12,alignItems:'center',background:'var(--brand-soft)',color:'var(--brand-fg)',padding:'14px 18px',borderRadius:10,marginTop:14,fontSize:14}}>
            <Icon name="sparkle" size={20} />
            <div><strong>{t('Tip:')}</strong> {t('Petr Svoboda dlouho nereagoval — oslovte ho osobně, často to zabere víc než notifikace.')}</div>
          </div>
        </div>

        <div className="card" style={{padding:'22px 24px'}}>
          <div className="sr-section-title" style={{marginBottom:14}}>{t('Automatické připomínky')}</div>
          <div style={{fontSize:13.5,color:'var(--text-2)',marginBottom:14}}>{t('Jak často mají nováčci dostávat e-mailem připomínku k dalším krokům.')}</div>
          {FREQ.map(f=>(
            <button key={f.k} onClick={()=>setFreq(f.k)} style={{display:'flex',alignItems:'center',gap:12,width:'100%',textAlign:'left',padding:'12px 14px',borderRadius:10,border:'1px solid '+(freq===f.k?'var(--brand)':'var(--border-2)'),background:freq===f.k?'var(--brand-soft)':'transparent',marginBottom:9,color:'var(--text)'}}>
              <span style={{width:18,height:18,borderRadius:'50%',border:'2px solid '+(freq===f.k?'var(--brand)':'var(--border-2)'),display:'flex',alignItems:'center',justifyContent:'center',flexShrink:0}}>{freq===f.k && <span style={{width:8,height:8,borderRadius:'50%',background:'var(--brand)'}}/>}</span>
              <span style={{flex:1}}><span style={{fontWeight:600,fontSize:14}}>{f.label}</span><span style={{display:'block',fontSize:12,color:'var(--text-3)'}}>{f.sub}</span></span>
            </button>
          ))}
          <label style={{display:'flex',alignItems:'center',gap:12,marginTop:14,paddingTop:16,borderTop:'1px solid var(--border)',cursor:'pointer'}}>
            <span onClick={()=>setPastorReminder(v=>!v)} style={{width:42,height:24,borderRadius:999,background:pastorReminder?'var(--brand)':'var(--border-2)',position:'relative',transition:'.2s',flexShrink:0}}>
              <span style={{position:'absolute',top:2,left:pastorReminder?20:2,width:20,height:20,borderRadius:'50%',background:'#fff',transition:'.2s',boxShadow:'0 1px 3px rgba(0,0,0,.3)'}}/>
            </span>
            <span style={{fontSize:13.5}}>{t('Připomínat i mně (pastorovi), koho povzbudit')}</span>
          </label>
          <button className="btn btn-primary" style={{width:'100%',marginTop:18}} onClick={()=>toast(t('Předvolba uložena. Automatické odesílání teprve připravujeme.'))}>{t('Uložit předvolbu')}</button>
        </div>
      </div>
    </>
  );
}

// ─────────────────────────────────────────────────────────────
// Shell
// ─────────────────────────────────────────────────────────────
function DesktopApp({ theme, onTheme, toast }) {
  const [active, setActive] = useState('onboarding');
  const LABELS = {home:'Online nástěnka',events:'Události společenství',agenda:'Moje agenda',planner:'Plánovač událostí',chat:'Konverzace',dary:'Dary',skupiny:'Skupiny',mladez:'Mládež',bible:'Skupina na štúdium Biblie',prehled:'Přehled',kontakty:'Kontakty',finance:'Finanční přehled',uzivatele:'Uživatelé',pozvat:'Pozvat přátele'};
  return (
    <div className="app" data-screen-label="Desktop · Pastor">
      <div className="main">
        <TopBar theme={theme} onTheme={onTheme} />
        <VerifyBanner toast={toast} />
        <div className="content">
          <Onboarding toast={toast} />
        </div>
      </div>
    </div>
  );
}

Object.assign(window, { DesktopApp });

// ── English dictionary (keyed by exact Czech source string) ──
registerEN({
  // Contact / messaging
  'Vítej u nás 🙂': 'Welcome to our community 🙂',
  'Ahoj {0},\n\njak se ti daří na tvé cestě? Kdyby cokoliv, klidně se ozvi.\n\nS pozdravem,\ntvůj mentor': 'Hi {0},\n\nhow are you getting on with your journey? If you need anything at all, feel free to reach out.\n\nWarm regards,\nyour mentor',
  'Ahoj {0}, vítej u nás! Jsme rádi, že ses připojil(a). Kdyby cokoliv, klidně se ozvi. 🙂': 'Hi {0}, welcome! We\'re glad you joined us. If you need anything, feel free to reach out. 🙂',
  'Ahoj {0}, jen ti chci říct, že na tebe myslíme a fandíme ti. Drž se! 🙏': 'Hi {0}, I just wanted to say we\'re thinking of you and cheering you on. Hang in there! 🙏',
  'Ahoj {0}, v pátek se schází naše skupinka v 17:00. Budeme rádi, když dorazíš!': 'Hi {0}, our small group meets on Friday at 5pm. We\'d love to see you there!',
  'Ahoj {0}, můžu ti s něčím pomoct na tvé cestě? Napiš mi, kdykoliv budeš chtít.': 'Hi {0}, is there anything I can help you with on your journey? Message me anytime.',
  'Ahoj {0} 🙂': 'Hi {0} 🙂',
  'Uvítání': 'Welcome',
  'Povzbuzení': 'Encouragement',
  'Pozvánka na skupinku': 'Small-group invite',
  'Nabídka pomoci': 'Offer to help',
  'Výchozí klient': 'Default client',
  'Zpráva zkopírována — vlož ji v Seznam e-mailu.': 'Message copied — paste it into your Seznam email.',
  '{0} pro {1}': '{0} for {1}',
  'E-mail': 'Email',
  'Předpřipravená zpráva': 'Prepared message',
  'Předmět': 'Subject',
  'Zpráva': 'Message',
  'Odeslat přes': 'Send via',
  'Zpráva zkopírována do schránky.': 'Message copied to clipboard.',
  'Zkopírovat zprávu, kdyby předvyplnění nefungovalo': 'Copy the message in case prefilling doesn\'t work',
  'Kopírovat': 'Copy',
  'Zrušit': 'Cancel',
  'Otevřít WhatsApp': 'Open WhatsApp',
  'Otevřít e-mail': 'Open email',
  // Newcomer detail blocks
  'hotovo': 'done',
  'čeká': 'pending',
  'Zvolená cesta:': 'Chosen path:',
  'Zatím si nezvolil(a) cestu.': 'Hasn\'t chosen a path yet.',
  'Odpověděl(a):': 'Answered:',
  'Zatím neodpověděl(a).': 'Hasn\'t answered yet.',
  'Nepodařilo se načíst detail.': 'Couldn\'t load the detail.',
  'Načítám…': 'Loading…',
  '{0} · připojen(a) {1}': '{0} · joined {1}',
  'bez kontaktu': 'no contact',
  'Pokrok onboardingu': 'Onboarding progress',
  '{0}/{1} úkolů · aktivní {2}': '{0}/{1} tasks · active {2}',
  'Po uvítací cestě si zvolil(a) tento směr a pokračuje dál.': 'After the welcome journey they chose this direction and keep going.',
  'Obsah a postup': 'Content and progress',
  'Nováček nezadal kontakt.': 'The newcomer didn\'t provide contact details.',
  // Sidebar / footer
  'Onboarding nováčků': 'Newcomers',
  'Verze: 0.0.5957': 'Version: 0.0.5957',
  '© 2026 Believer s.r.o. Všechna práva vyhrazena.': '© 2026 Believer s.r.o. All rights reserved.',
  // Confirm dialog
  'Potvrdit': 'Confirm',
  // Top bar
  'Administrátor': 'Administrator',
  'Jazyk': 'Language',
  'Přepnout motiv': 'Toggle theme',
  'Odhlásit se': 'Sign out',
  'odhlásit': 'sign out',
  'Odhlásit se?': 'Sign out?',
  'Opravdu se chceš odhlásit z účtu {0}?': 'Are you sure you want to sign out of the {0} account?',
  // Verify banner
  'E-mail je už ověřený.': 'Your email is already verified.',
  'Ověřovací e-mail jsme poslali znovu.': 'We\'ve sent the verification email again.',
  'E-mail se nepodařilo odeslat. Zkuste to za chvíli.': 'We couldn\'t send the email. Please try again shortly.',
  'Neověřeno': 'Unverified',
  'Nejdřív prosím ověřte svůj e-mail': 'Please verify your email first',
  'poslali jsme vám potvrzovací odkaz.': 'we\'ve sent you a confirmation link.',
  'Odesílám…': 'Sending…',
  'Poslat znovu': 'Resend',
  // Placeholder
  'Tato sekce není součástí prototypu onboardingu. Otevři': 'This section isn\'t part of the onboarding prototype. Open',
  'v levém menu.': 'in the left menu.',
  // Welcome gate
  'Sestav onboarding': 'Build the onboarding',
  'Poskládej video, text, kvíz, úkol nebo rozcestník.': 'Combine video, text, a quiz, a task or a signpost.',
  'Sdílej přes QR': 'Share via QR',
  'Nováčci se připojí naskenováním kódu.': 'Newcomers join by scanning the code.',
  'Sleduj pokrok': 'Track progress',
  'Vidíš živě, kdo postupuje a koho povzbudit.': 'See live who\'s progressing and who needs encouragement.',
  'Vítej v onboardingu Believer': 'Welcome to Believer onboarding',
  'Provázej nové lidi ve vašem společenství krok za krokem — od prvního přivítání až po zapojení. Začni založením svého společenství.': 'Guide new people in your community step by step — from the first welcome to getting involved. Start by creating your community.',
  'Vytvořit společenství': 'Create community',
  'Už máš účet?': 'Already have an account?',
  'Přihlásit se': 'Sign in',
  'Po založení máš prostředí prázdné a připravíme ti jednu': 'After you create it, your workspace starts empty and we\'ll prepare one',
  'ukázkovou šablonu': 'sample template',
  ', ať vidíš, jak to funguje.': ' so you can see how it works.',
  // Onboarding page head
  'Sledujte, jak se noví lidé v': 'See how new people in',
  'vašem společenství': 'your community',
  'zabydlují — kdo postupuje, kdo se zasekl a koho je dobré povzbudit.': 'are settling in — who\'s progressing, who\'s stuck and who could use some encouragement.',
  // relTime
  'právě teď': 'just now',
  'před {0} min': '{0} min ago',
  'před {0} h': '{0} h ago',
  'před {0} dny': '{0} days ago',
  // Tabs
  'Přehled nováčků': 'Newcomers',
  'Šablony': 'Templates',
  'Analytika': 'Analytics',
  'Připomínky': 'Reminders',
  // Live newcomers
  'Živí nováčci z QR kódu': 'Live newcomers from the QR code',
  'Vytvoř si společenství a publikuj onboarding v záložce': 'Create your community and publish an onboarding in the',
  '— kdo se připojí přes QR, objeví se tady živě.': 'tab — anyone who joins via QR shows up here live.',
  'Přihlásit': 'Sign in',
  'Živí nováčci z QR': 'Live newcomers from QR',
  'aktualizuje se automaticky': 'updates automatically',
  '{0} připojeno': '{0} joined',
  'Zatím se nikdo nepřipojil. Sdílej QR kód z onboardingu a sleduj, jak tu přibývají. 🙂': 'No one has joined yet. Share the onboarding QR code and watch them appear here. 🙂',
  // Real dashboard
  'Nováček „{0}" odebrán.': 'Newcomer "{0}" removed.',
  'Smazání se nepovedlo.': 'Deletion failed.',
  'Průměrné dokončení': 'Average completion',
  'Aktivních nováčků': 'Active newcomers',
  'Dokončili cestu': 'Completed the journey',
  'Bez aktivity': 'Inactive',
  'Zatím tu nikdo není': 'No one here yet',
  'Vytvoř si onboarding v záložce': 'Create an onboarding in the',
  ', publikuj ho a sdílej QR kód. Jakmile se někdo připojí, objeví se tady — naživo.': 'tab, publish it and share the QR code. As soon as someone joins, they\'ll appear here — live.',
  'Vytvořit onboarding': 'Create onboarding',
  'Hledat nováčka…': 'Search for a newcomer…',
  'živě': 'live',
  '{0} nováčků': '{0} newcomers',
  'Nováček': 'Newcomer',
  'Postup checklistu': 'Checklist progress',
  'Stav': 'Status',
  'Akce': 'Actions',
  'Zobrazit detail nováčka': 'View newcomer detail',
  '{0}/{1} úkolů': '{0}/{1} tasks',
  'Dokončeno': 'Completed',
  'Probíhá': 'In progress',
  'Po dokončení uvítací cesty si zvolil(a) směr: {0}': 'After finishing the welcome journey they chose the direction: {0}',
  'Směřuje: {0}': 'Heading: {0}',
  'aktivní {0}': 'active {0}',
  'WhatsApp: {0}': 'WhatsApp: {0}',
  'E-mail: {0}': 'Email: {0}',
  'Odebrat nováčka': 'Remove newcomer',
  'Žádný nováček neodpovídá hledání.': 'No newcomer matches your search.',
  'Odebrat nováčka?': 'Remove newcomer?',
  'Opravdu odebrat „{0}" z onboardingu? Jeho postup se trvale smaže. Pokud se znovu připojí přes QR, začne od začátku.': 'Really remove "{0}" from the onboarding? Their progress will be permanently deleted. If they rejoin via QR, they\'ll start over.',
  'Odebrat': 'Remove',
  // Demo dashboard
  'Nový': 'New',
  'Skupina': 'Group',
  'Pokrok': 'Progress',
  'Vše': 'All',
  'Řadit podle': 'Sort by',
  'Pokroku': 'Progress',
  'Aktivity': 'Activity',
  'Jména': 'Name',
  'vy jako nováček': 'you as a newcomer',
  '{0} · registrace {1}': '{0} · registered {1}',
  '{0}/{1} úkolů · {2}': '{0}/{1} tasks · {2}',
  'Kontaktovat': 'Contact',
  'Žádný nováček neodpovídá filtrům.': 'No newcomer matches the filters.',
  // Newcomer drawer
  'Aktuální fáze': 'Current phase',
  '{0} dlouho nereagoval{1} ({2}). Zkuste {3} povzbudit.': '{0} hasn\'t responded for a while ({2}). Try giving {3} some encouragement.',
  'ji': 'her',
  'ho': 'him',
  'Postup v checklistu': 'Checklist progress',
  'Poslat připomínku': 'Send a reminder',
  // Contact modal (demo)
  'Ahoj {0}, jak se ti daří na tvé cestě? Kdyby cokoliv, klidně se ozvi — rádi tě uvidíme na skupince. 🙂': 'Hi {0}, how are you getting on with your journey? If you need anything, feel free to reach out — we\'d love to see you at the small group. 🙂',
  'Zpráva pro {0}': 'Message for {0}',
  'Odešle se přes Konverzace v aplikaci': 'Sends via Conversations in the app',
  'Zpráva odeslána {0}.': 'Message sent to {0}.',
  'Odeslat zprávu': 'Send message',
  // Login modal
  'Heslo musí mít aspoň 6 znaků a obsahovat malé i velké písmeno.': 'The password must be at least 6 characters and include a lowercase and an uppercase letter.',
  'Pro vytvoření společenství potvrď prosím souhlas s podmínkami a zpracováním osobních údajů.': 'To create a community, please confirm your agreement with the terms and the processing of personal data.',
  'Registrace selhala.': 'Registration failed.',
  'Přihlášení selhalo.': 'Sign-in failed.',
  'Společenství „{0}" vytvořeno. Ověřovací e-mail je na cestě.': 'Community "{0}" created. A verification email is on its way.',
  'Přihlášen(a) jako {0}.': 'Signed in as {0}.',
  'Zapomenuté heslo': 'Forgotten password',
  'Přihlášení vedoucího': 'Leader sign-in',
  'Založ si vlastní onboarding za pár vteřin': 'Set up your own onboarding in seconds',
  'Pošleme ti odkaz na obnovu hesla': 'We\'ll send you a password reset link',
  'Přístup k onboardingu vašeho společenství': 'Access to your community\'s onboarding',
  'Hotovo — zkontroluj e-mail': 'Done — check your email',
  'Pokud na': 'If an account exists for',
  'existuje účet, právě jsme poslali odkaz na nastavení nového hesla. Platí 1 hodinu.': 'we\'ve just sent a link to set a new password. It\'s valid for 1 hour.',
  'Název společenství': 'Community name',
  'např. Sbor Živá voda': 'e.g. Living Water Community',
  'Tvé jméno': 'Your name',
  'Jméno a příjmení': 'First and last name',
  'vas@email.cz': 'you@email.com',
  'Heslo': 'Password',
  '(min. 6 znaků, malé i velké písmeno)': '(min. 6 characters, lowercase and uppercase)',
  'Skrýt heslo': 'Hide password',
  'Zobrazit heslo': 'Show password',
  'Souhlasím s': 'I agree to the',
  'obchodními podmínkami': 'terms of service',
  'a se': 'and the',
  'zpracováním osobních údajů': 'processing of personal data',
  'Zapomenuté heslo?': 'Forgotten password?',
  'Vzpomněl(a) sis?': 'Remembered it?',
  'Zpět na přihlášení': 'Back to sign-in',
  'Už máš účet? ': 'Already have an account? ',
  'Nemáš ještě společenství? ': 'Don\'t have a community yet? ',
  'Vytvořit nové': 'Create a new one',
  'Zavřít': 'Close',
  'Vytvořit a začít': 'Create and start',
  'Poslat odkaz': 'Send link',
  // Share modal
  'Sdílet „{0}"': 'Share "{0}"',
  'Nováčci se připojí naskenováním QR nebo zadáním kódu': 'Newcomers join by scanning the QR or entering the code',
  'Kód onboardingu': 'Onboarding code',
  'Kód zkopírován.': 'Code copied.',
  'Kopírovat kód': 'Copy code',
  'Odkaz zkopírován.': 'Link copied.',
  'Kopírovat odkaz': 'Copy link',
  'Otevřít náhled': 'Open preview',
  'QR a odkaz výše fungují na telefonu připojeném ke stejné Wi-Fi. „Otevřít náhled" otevře onboarding tady na počítači.': 'The QR and link above work on a phone connected to the same Wi-Fi. "Open preview" opens the onboarding here on your computer.',
  // Block canvas
  'Nahoru': 'Move up',
  'Dolů': 'Move down',
  'Duplikovat': 'Duplicate',
  'Smazat': 'Delete',
  'Název bloku': 'Block title',
  'Onboarding je prázdný — přidej první blok níže.': 'The onboarding is empty — add your first block below.',
  'Přidat blok': 'Add block',
  'Co chceš vložit?': 'What would you like to add?',
  '{0} přidán.': '{0} added.',
  // Templates real
  'Onboarding „{0}" vytvořen.': 'Onboarding "{0}" created.',
  'Nový onboarding': 'New onboarding',
  'Krátký popis, o čem onboarding je…': 'A short description of what the onboarding is about…',
  '{0} (kopie)': '{0} (copy)',
  'Onboarding smazán.': 'Onboarding deleted.',
  'Publikace selhala.': 'Publishing failed.',
  'Publikováno — sdílej QR kód.': 'Published — share the QR code.',
  'Načítám onboardingy…': 'Loading onboardings…',
  'Vaše onboardingy': 'Your onboardings',
  '{0} bloků': '{0} blocks',
  'publikováno': 'published',
  'koncept': 'draft',
  'Zatím tu nic není.': 'Nothing here yet.',
  'Vytvoř svůj první onboarding. 👆': 'Create your first onboarding. 👆',
  'Změnit vzhled': 'Change appearance',
  'Název onboardingu': 'Onboarding name',
  'Ukládám…': 'Saving…',
  'Uloženo ✓': 'Saved ✓',
  'Vytvořit kopii (navázat na tuto šablonu)': 'Create a copy (build on this template)',
  'Smazat onboarding': 'Delete onboarding',
  'Editor': 'Editor',
  'Náhled': 'Preview',
  'Publikuji…': 'Publishing…',
  'Znovu publikovat': 'Publish again',
  'Publikovat & sdílet': 'Publish & share',
  'Ikona': 'Icon',
  'Ikona uložena ✓': 'Icon saved ✓',
  'Nahrát vlastní ikonu': 'Upload a custom icon',
  'Vlastní ikona nahrána a uložena ✓': 'Custom icon uploaded and saved ✓',
  'Barva': 'Colour',
  'Barva uložena ✓': 'Colour saved ✓',
  'Fáze': 'Phase',
  'Fáze uložena ✓': 'Phase saved ✓',
  'Vzhled uložen ✓': 'Appearance saved ✓',
  'Hotovo': 'Done',
  'Začni svým prvním onboardingem': 'Start with your first onboarding',
  'Vytvoř onboarding, poskládej bloky (video, text, kvíz, úkol) a publikuj ho s QR kódem.': 'Create an onboarding, combine blocks (video, text, quiz, task) and publish it with a QR code.',
  // Tag choices
  'Vítej': 'Welcome',
  'Poznávání': 'Getting to know',
  'Růst': 'Growth',
  'Zapojení': 'Involvement',
  // New onboarding modal
  'Začni od nuly, z připraveného vzoru, nebo navaž na svůj.': 'Start from scratch, from a ready-made template, or build on your own.',
  'Prázdný onboarding': 'Blank onboarding',
  'Začni s čistým plátnem.': 'Start with a blank canvas.',
  'Připravené vzory': 'Ready-made templates',
  '{0} bloků · {1}': '{0} blocks · {1}',
  'Navázat na svůj onboarding': 'Build on your own onboarding',
  'kopie · {0} bloků': 'copy · {0} blocks',
  // Templates demo
  '{0} přidán do šablony.': '{0} added to the template.',
  'Tohle jsou': 'These are',
  'ukázkové': 'sample',
  'šablony. Vytvoř si vlastní společenství a pracuj s vlastními.': 'templates. Create your own community and work with your own.',
  'Ukázkové šablony': 'Sample templates',
  // Block bodies
  'Co má nováček udělat': 'What the newcomer should do',
  'Další možnost': 'Another option',
  'Otázka?': 'Question?',
  'Označit jako správnou': 'Mark as correct',
  'Přidat možnost': 'Add option',
  'Klikni a nahraj obrázek': 'Click to upload an image',
  'Nahrávám…': 'Uploading…',
  'Bez obrázku': 'No image',
  'Změnit': 'Change',
  '…nebo vlož odkaz na obrázek (https://…)': '…or paste an image link (https://…)',
  'Popisek obrázku': 'Image caption',
  // Choice block
  'Nová cesta': 'New path',
  'Nováček si volí cestu': 'The newcomer chooses a path',
  'Název bloku výše je otázka na rozcestí. Nováček si zvolí jednu cestu — započítají se mu úkoly jen z ní.': 'The block title above is the signpost question. The newcomer picks one path — only its tasks count toward their progress.',
  'Změnit ikonu a barvu': 'Change icon and colour',
  'Název cesty': 'Path name',
  'Musí zůstat aspoň 2 cesty': 'At least 2 paths must remain',
  'Smazat cestu': 'Delete path',
  'Smazat blok': 'Delete block',
  'Zatím prázdná cesta — přidej první blok.': 'Empty path — add your first block.',
  'Přidat blok do této cesty': 'Add a block to this path',
  'Přidat cestu': 'Add path',
  // Video block
  'Přehrát video': 'Play video',
  'Vlož odkaz na YouTube video (youtube.com/watch?v=… nebo youtu.be/…)': 'Paste a YouTube video link (youtube.com/watch?v=… or youtu.be/…)',
  'Popisek zdroje (kdo / co)': 'Source caption (who / what)',
  'Délka 0:00': 'Length 0:00',
  'Tohle nevypadá jako YouTube odkaz — zkontroluj ho.': 'This doesn\'t look like a YouTube link — please check it.',
  // Day units
  '<1 den': '<1 day',
  'den': 'day',
  'dny': 'days',
  'dní': 'days',
  // Analytics
  'Připojili se': 'Joined',
  'Začali (1+ krok)': 'Started (1+ step)',
  'Telefon': 'Phone',
  'Dokončeno %': 'Completion %',
  'Splněné úkoly': 'Completed tasks',
  'Celkem úkolů': 'Total tasks',
  'Zvolený směr': 'Chosen direction',
  'Připojen': 'Joined',
  'Poslední aktivita': 'Last activity',
  'Společenství': 'Community',
  'Believer · Report onboardingu': 'Believer · Onboarding report',
  'Report onboardingu — {0}': 'Onboarding report — {0}',
  'Vygenerováno {0}': 'Generated {0}',
  'Bez aktivity (7+ dní)': 'Inactive (7+ days)',
  'Míra dokončení': 'Completion rate',
  'Míra aktivace': 'Activation rate',
  'Ø doba k dokončení': 'Avg. time to complete',
  'Noví za 30 dní': 'New in 30 days',
  'Aktivační trychtýř': 'Activation funnel',
  'Kam nováčci míří (rozcestník)': 'Where newcomers head (signpost)',
  'Směr': 'Direction',
  'Počet': 'Count',
  'Podíl': 'Share',
  'Průměrné dokončení podle onboardingu': 'Average completion by onboarding',
  'Nováčci ({0})': 'Newcomers ({0})',
  'Jméno': 'Name',
  'Úkoly': 'Tasks',
  'Kontakt': 'Contact',
  'Zatím žádní nováčci.': 'No newcomers yet.',
  '© 2026 Believer s.r.o.': '© 2026 Believer s.r.o.',
  'Povol prosím vyskakovací okna pro export.': 'Please allow pop-ups to export.',
  'Průměrné dokončení checklistu': 'Average checklist completion',
  'napříč všemi nováčky': 'across all newcomers',
  'právě teď v procesu': 'currently in progress',
  'na 100 %': 'at 100%',
  'Nováčci bez aktivity': 'Inactive newcomers',
  '7+ dní bez pohybu': '7+ days without movement',
  '{0} z {1} došlo do konce': '{0} of {1} reached the end',
  '{0} splnilo aspoň 1 krok': '{0} completed at least 1 step',
  'od připojení ke 100 %': 'from joining to 100%',
  '{0} z toho za 7 dní': '{0} of those in 7 days',
  'Trendy a úspěšnost práce s nováčky — počítáno naživo z reálných dat vašeho společenství.': 'Trends and success in working with newcomers — calculated live from your community\'s real data.',
  'Vytisknout / uložit report jako PDF': 'Print / save the report as PDF',
  'Zatím není co exportovat': 'Nothing to export yet',
  'Export PDF': 'Export PDF',
  'Stáhnout data nováčků jako CSV': 'Download newcomer data as CSV',
  'Export CSV': 'Export CSV',
  'Zatím nejsou žádná data': 'No data yet',
  'Jakmile se k tvým onboardingům připojí první nováčci, uvidíš tady jejich pokrok, rozložení a trendy.': 'Once the first newcomers join your onboardings, you\'ll see their progress, distribution and trends here.',
  'Nováčci podle stavu': 'Newcomers by status',
  'Kolik lidí právě probíhá, dokončilo cestu, nebo je bez aktivity.': 'How many people are in progress, completed the journey, or are inactive.',
  'Kolik lidí se připojilo, rozhýbalo a došlo až do konce — kde nováčci odpadávají.': 'How many people joined, got moving and made it to the end — where newcomers drop off.',
  'Kam nováčci míří': 'Where newcomers head',
  'Co si lidé zvolili na závěrečném rozcestníku — dobrý podklad pro plánování služby a skupinek.': 'What people chose at the final signpost — a useful basis for planning services and small groups.',
  'Zatím si nikdo nezvolil směr na rozcestníku. Objeví se tu, jakmile někdo dojde na konec uvítací cesty.': 'No one has chosen a direction at the signpost yet. It\'ll appear here once someone reaches the end of the welcome journey.',
  'Jak si vedou nováčci v jednotlivých onboardinzích.': 'How newcomers are doing across the individual onboardings.',
  'Nejrychlejší dokončení': 'Fastest completion',
  'od registrace ke 100 %': 'from registration to 100%',
  'Trendy a úspěšnost práce s nováčky za poslední 3 měsíce.': 'Trends and success in working with newcomers over the last 3 months.',
  'Export do PDF připraven ke stažení.': 'PDF export ready to download.',
  'Export do Excelu připraven ke stažení.': 'Excel export ready to download.',
  'Počet nováčků podle fáze cesty': 'Number of newcomers by journey phase',
  'Kolik lidí se právě nachází v jednotlivých fázích duchovní cesty.': 'How many people are currently in each phase of the spiritual journey.',
  'lidí': 'people',
  'Nejčastěji nedokončené úkoly': 'Most often unfinished tasks',
  'Které kroky nováčci přeskakují nejvíc.': 'Which steps newcomers skip the most.',
  'Průměrné dokončení checklistu v čase': 'Average checklist completion over time',
  'Vývoj průměrného procenta dokončení za posledních 5 měsíců — trend roste.': 'How the average completion percentage developed over the last 5 months — the trend is rising.',
  // Reminders
  'Testovací e-mail odeslán na {0}.': 'Test email sent to {0}.',
  'Odeslání selhalo.': 'Sending failed.',
  'Předvolba uložena. Připomínky se nováčkům s e-mailem posílají automaticky.': 'Preference saved. Reminders are sent automatically to newcomers who provided an email.',
  'Předvolba uložena. Automatické odesílání teprve připravujeme.': 'Preference saved. Automatic sending is still in the works.',
  'Uložení se nepovedlo.': 'Saving failed.',
  'Denně': 'Daily',
  'každý den ráno': 'every morning',
  'Týdně': 'Weekly',
  'pondělní souhrn': 'Monday summary',
  'Po nečinnosti': 'After inactivity',
  'po 3 dnech bez aktivity': 'after 3 days without activity',
  'Nikdo nepotřebuje povzbudit': 'No one needs encouragement',
  '1 člověk potřebuje povzbudit': '1 person needs encouragement',
  '{0} lidé potřebují povzbudit': '{0} people need encouragement',
  '{0} lidí potřebuje povzbudit': '{0} people need encouragement',
  'Všichni nováčci jsou aktivní — skvělá práce!': 'All newcomers are active — great work!',
  'Tito nováčci jsou 7+ dní bez aktivity. Krátká zpráva může hodně pomoct.': 'These newcomers have been inactive for 7+ days. A short message can help a lot.',
  'Koho oslovit': 'Who to reach out to',
  'Zatím nikdo bez aktivity. 🙂': 'No one inactive yet. 🙂',
  '{0} · {1}/{2} úkolů · aktivní {3}': '{0} · {1}/{2} tasks · active {3}',
  'Automatické připomínky': 'Automatic reminders',
  'Jak často mají nováčci dostávat e-mailem připomínku k dalším krokům.': 'How often newcomers should get an email reminder about their next steps.',
  'Připomínat i mně (pastorovi), koho povzbudit': 'Remind me (the pastor) too about who to encourage',
  'Odesílání': 'Sending',
  'aktivní': 'active',
  '(e-mail přes Resend). Připomínky chodí nováčkům, kteří zadali e-mail.': '(email via Resend). Reminders go to newcomers who provided an email.',
  'zatím vypnuté': 'off for now',
  '(chybí napojení e-mailu). Tady si jen předvolíš frekvenci. Nováčky zatím oslovuj ručně vlevo.': '(email isn\'t connected). Here you just preset the frequency. For now, reach out to newcomers manually on the left.',
  'Při dnešním nastavení by připomínku dostalo': 'With today\'s settings, a reminder would go to',
  'nováček': 'newcomer',
  'nováčci': 'newcomers',
  'nováčků': 'newcomers',
  'Uložit': 'Save',
  'Poslat testovací e-mail na tvou adresu': 'Send a test email to your address',
  'Posílám…': 'Sending…',
  'Test e-mailu': 'Test email',
  '{0} · zasekl{1} se na ': '{0} · got stuck on ',
  ' · aktivní {0}': ' · active {0}',
  'Povzbudit': 'Encourage',
  'Tip:': 'Tip:',
  'Petr Svoboda dlouho nereagoval — oslovte ho osobně, často to zabere víc než notifikace.': 'Petr Svoboda hasn\'t responded for a while — reach out personally; it often works better than a notification.',
  'Uložit předvolbu': 'Save preference',
  // Section & link blocks
  'Část cesty': 'Journey part',
  'Podnadpis': 'Subtitle',
  'Odkaz': 'Link',
  'Tlačítko': 'Button',
  'Kanál': 'Channel',
  'https://… (nechte prázdné pro odkaz v Believeru)': 'https://… (leave empty for a link inside Believer)',
});

// Překlady pro správu více administrátorů.
registerEN({
  'Správci společenství': 'Community administrators',
  'Spravujte onboarding ve více lidech.': 'Manage the onboarding together as a team.',
  'to jsi ty': 'this is you',
  'neověřeno': 'unverified',
  'Opustit společenství': 'Leave community',
  'Odebrat správce': 'Remove administrator',
  'Zrušit pozvánku': 'Cancel invitation',
  'Zrušení se nepovedlo.': 'Couldn\'t cancel.',
  'Pozvánka odeslána — čeká na přijetí': 'Invitation sent — awaiting acceptance',
  'Pozvat dalšího správce': 'Invite another administrator',
  'Pozvat': 'Invite',
  'Pošleme mu e-mailem odkaz, kde si nastaví jméno a heslo. Pak má plný přístup ke správě.': 'We\'ll email them a link to set their name and password. Then they\'ll have full management access.',
  'Pozvánku se nepodařilo odeslat.': 'Couldn\'t send the invitation.',
  'Odebrání se nepovedlo.': 'Removal failed.',
  'Pozvánka odeslána na {0}.': 'Invitation sent to {0}.',
  'Opustit společenství?': 'Leave community?',
  'Odebrat správce?': 'Remove administrator?',
  'Přijdeš o přístup ke správě tohoto společenství. Pokračovat?': 'You\'ll lose access to managing this community. Continue?',
  'Opravdu odebrat správce „{0}"? Ztratí přístup ke správě.': 'Remove administrator "{0}"? They\'ll lose management access.',
  'Opustit': 'Leave',
});

// Překlad hlášky pro publikaci bez ověřeného e-mailu.
registerEN({
  'Nejdřív si ověř e-mail — pak můžeš publikovat. Ověřovací odkaz máš v e-mailu (nebo si ho pošli znovu z banneru nahoře).': 'Verify your email first — then you can publish. The verification link is in your inbox (or resend it from the banner above).',
});

// Překlady pro uvítací průvodce + nápovědu.
registerEN({
  'Nápověda — průvodce': 'Help — quick guide',
  'Vítej v Believeru{0} 👋': 'Welcome to Believer{0} 👋',
  'Tady provedeš nové lidi ve svém společenství krok za krokem — od přivítání po zapojení. Ukážeme ti to ve třech krocích.': 'Here you guide new people in your community step by step — from welcome to belonging. We\'ll show you in three steps.',
  '1. Sestav cestu v Šablonách': '1. Build the journey in Templates',
  'V záložce Šablony poskládáš uvítací cestu z bloků — text, video, kvíz, odkaz i rozcestník. Rozděl ji na části, ať má nováček přehled.': 'In Templates you assemble the welcome journey from blocks — text, video, quiz, link and a signpost. Split it into parts so newcomers stay oriented.',
  '2. Publikuj a sdílej QR': '2. Publish and share the QR',
  'Až bude cesta hotová, publikuj ji a sdílej QR kód nebo krátký kód. (Stačí mít ověřený e-mail — odkaz najdeš v poště.)': 'Once the journey is ready, publish it and share the QR code or a short code. (Just verify your email — the link is in your inbox.)',
  '3. Sleduj nováčky': '3. Track newcomers',
  'V Přehledu nováčků vidíš živě, kdo postupuje a kdo se zasekl. V Analytice máš report pro vedení, v Připomínkách koho povzbudit.': 'In Newcomers you see live who\'s progressing and who\'s stuck. Analytics gives you a report for leadership, Reminders shows who to encourage.',
  'Přeskočit': 'Skip',
  'Zpět': 'Back',
  'Jdeme na to': 'Let\'s go',
  'Dál': 'Next',
});
