/* Curio — main screens: Home, Explore, QuestDetail, Profile */
const {useState:useMainState} = React;

function greetingKey(){ const h=new Date().getHours(); return h<12?'goodMorning':h<18?'goodAfternoon':'goodEvening'; }

function HomeQuickCard({icon, title, sub, onClick, accent}){
  return <button type="button" onClick={onClick} className="cu-press" style={{flexShrink:0,width:168,minHeight:148,textAlign:'left',padding:16,borderRadius:20,border:`1.5px solid ${accent?accent.bd:T.line}`,background:accent?accent.bg:T.card,boxShadow:SH,cursor:'pointer',display:'flex',flexDirection:'column',justifyContent:'space-between'}}>
    <span style={{width:44,height:44,borderRadius:14,background:accent?accent.iconBg:tint(10),color:accent?accent.iconColor:'var(--ink-deep)',display:'inline-flex',alignItems:'center',justifyContent:'center'}}>{icon}</span>
    <span>
      <span style={{display:'block',color:T.text,fontSize:fz(14.5),fontWeight:800,fontFamily:F,lineHeight:1.25,marginBottom:4}}>{title}</span>
      <span style={{display:'block',color:T.muted,fontSize:fz(11.5),fontFamily:F,lineHeight:1.4}}>{sub}</span>
    </span>
  </button>;
}

/* ── HOME ── */
function HomeScreen(){
  const{t,lang,state,user,nav,actions}=useApp();
  const L=(v)=>pick(v,lang);
  const active = state.activeQuestId ? window.DATA.questById(state.activeQuestId) : null;
  const activeProg = active ? (state.questProgress[active.id]||{stop:0,total:active.stops.length}) : null;
  const activeLive = active && activeProg && !activeProg.completed && activeProg.started;
  const visitLive = state.activeVisit;
  const visitQuest = visitLive ? window.DATA.questById(visitLive.questId) : null;
  /* top pick: highest-interest quest not yet completed (recommended after you finish one) */
  const completedIds=Object.keys(state.questProgress||{}).filter(id=>state.questProgress[id].completed);
  const interestMap={art:['golestan'],history:['golestan','deutsches'],science:['deutsches'],tech:['deutsches'],design:['golestan'],architecture:['golestan'],nature:['golestan'],photo:['golestan'],cinema:['golestan']};
  const wanted=[...new Set((state.interests||[]).flatMap(i=>interestMap[i]||[]))];
  const pick1=window.DATA.QUESTS.find(q=>q.featured&&!completedIds.includes(q.id)&&q.id!==state.activeQuestId)
    ||window.DATA.QUESTS.find(q=>wanted.includes(q.id)&&!completedIds.includes(q.id)&&q.id!==state.activeQuestId)
    ||window.DATA.QUESTS.find(q=>!completedIds.includes(q.id)&&q.id!==state.activeQuestId)
    ||window.DATA.QUESTS[0];
  const hero = activeLive ? active : visitLive && visitQuest ? visitQuest : pick1;
  const prog = activeLive ? activeProg : null;
  const featured = hero;
  const threads=state.threads||[];
  const unread=threads.length;
  const nearby = window.DATA.QUESTS.filter(q=>q.id!==hero.id&&!completedIds.includes(q.id)).slice(0,3);
  const people = window.DATA.PEOPLE.filter(p=>p.online).slice(0,5);
  const info = window.CurioStore.levelInfo(state.xp);

  return <div data-screen-label="Home" className="cu-scroll" style={{flex:1,overflowY:'auto',background:T.bg}}>
    
    <header style={{padding:`10px ${SP.safe}px 0`,display:'flex',justifyContent:'space-between',alignItems:'center'}}>
      <div>
        <p style={{color:T.muted,fontSize:fz(13.5),fontFamily:F,margin:'4px 0 0'}}>{t(greetingKey())},</p>
        <h1 style={{color:T.text,fontSize:fz(28),fontWeight:700,fontFamily:FD,letterSpacing:'-0.6px',margin:'2px 0 0'}}>{state.name||user.name}</h1>
      </div>
      <div style={{display:'flex',alignItems:'center',gap:12}}>
        <button type="button" onClick={()=>nav.push('messages')} aria-label={t('messages')} className="cu-press" style={{position:'relative',width:46,height:46,borderRadius:14,border:`1.5px solid ${T.line}`,background:T.card,boxShadow:SH,cursor:'pointer',display:'flex',alignItems:'center',justifyContent:'center',color:T.sub}}>
          <Ic k="chat" size={22}/>
          {unread>0&&<span style={{position:'absolute',top:-5,right:-5,minWidth:18,height:18,padding:'0 5px',borderRadius:9,background:'var(--ink)',color:'#fff',fontSize:11,fontWeight:800,fontFamily:F,display:'flex',alignItems:'center',justifyContent:'center',border:`2px solid ${T.bg}`}}>{unread}</span>}
        </button>
        <button type="button" onClick={()=>nav.goTab('profile')} aria-label={t('tabProfile')} className="cu-press" style={{border:'none',background:'transparent',padding:0,cursor:'pointer'}}><Av n={state.name||user.name} ci={state.avatar} sz={48} photo={state.photo}/></button>
      </div>
    </header>
    <Gap n={20}/>
    {/* gamification card — quiet & neutral by default, warms up with color while a quest is actively in progress */}
    <div style={{padding:`0 ${SP.safe}px`}}>
      <button type="button" onClick={()=>nav.goTab('profile')} aria-label={`${t('level')} ${info.level}, ${info.into} of ${info.span} XP, ${state.streak} ${t('dayStreak')}`} className="cu-press" style={{width:'100%',display:'block',textAlign:'left',cursor:'pointer',borderRadius:18,padding:'13px 15px 15px',background:activeLive?tint(6):T.card,border:`1.5px solid ${activeLive?tint(20):T.line}`,boxShadow:SH,fontFamily:F}}>
        <div style={{display:'flex',alignItems:'center',justifyContent:'space-between',marginBottom:11}}>
          <span style={{display:'inline-flex',alignItems:'center',gap:9}}>
            <span style={{display:'inline-flex',alignItems:'center',gap:5,padding:'4px 9px',borderRadius:9,background:activeLive?T.goldBg:T.cardAlt,border:`1px solid ${activeLive?T.goldLine:T.line}`}}>
              <span style={{fontSize:fz(13),filter:activeLive?'none':'grayscale(1) opacity(.7)'}}>🔥</span>
              <span style={{color:activeLive?T.gold:T.muted,fontSize:fz(13.5),fontWeight:700,fontFamily:F}}>{state.streak}</span>
            </span>
            <span style={{color:T.muted,fontSize:fz(12.5),fontWeight:600,fontFamily:F}}>{t('dayStreak')}</span>
          </span>
          <span style={{display:'inline-flex',alignItems:'center',gap:7}}>
            <span style={{display:'inline-flex',alignItems:'center',gap:6,color:activeLive?'var(--ink-deep)':T.sub,fontSize:fz(13),fontWeight:700,fontFamily:F}}>
              <span style={{width:20,height:20,borderRadius:7,background:activeLive?'var(--ink)':T.lineMd,color:activeLive?'#fff':T.sub,display:'inline-flex',alignItems:'center',justifyContent:'center',fontSize:fz(11),fontWeight:700}}>{info.level}</span>
              {t('level')} {info.level}
            </span>
            <Ic k="chevR" size={18} color={T.muted}/>
          </span>
        </div>
        <PBar val={info.pct} grad={activeLive} label="Level progress"/>
        <div style={{display:'flex',justifyContent:'space-between',alignItems:'baseline',marginTop:9}}>
          <span style={{color:T.sub,fontSize:fz(12.5),fontWeight:600,fontFamily:F}}>{info.into.toLocaleString()} / {info.span.toLocaleString()} XP</span>
          <span style={{color:T.muted,fontSize:fz(12),fontWeight:500,fontFamily:F}}>{info.toNext.toLocaleString()} {lang==='de'?`XP bis Lvl ${info.level+1}`:`XP to Lvl ${info.level+1}`}</span>
        </div>
      </button>
    </div>
    <Gap n={24}/>
    <div style={{padding:`0 ${SP.safe}px`}}>
      <button type="button" onClick={()=>activeLive?nav.push('group-board',{questId:featured.id}):visitLive?nav.push('visit-hub'):nav.push('event-detail',{questId:featured.id})} className="cu-press" aria-label={L((hero).title)} style={{position:'relative',display:'block',width:'100%',textAlign:'left',padding:0,borderRadius:22,border:'none',cursor:'pointer',boxShadow:SHmd,fontFamily:F,overflow:'hidden',background:'#1a1530'}}>
        <img src={(hero).img} alt="" onError={e=>{e.currentTarget.style.opacity=0;}} style={{position:'absolute',inset:0,width:'100%',height:'100%',objectFit:'cover'}}/>
        <span aria-hidden="true" style={{position:'absolute',inset:0,background:'linear-gradient(180deg, rgba(16,12,28,.18) 0%, rgba(16,12,28,.85) 100%)'}}></span>
        <span style={{position:'relative',display:'block',padding:20,minHeight:202}}>
          <span style={{display:'flex',justifyContent:'space-between',alignItems:'center',marginBottom:54,gap:10}}>
            <Chip label={activeLive?t('activeQuest'):visitLive?(lang==='de'?'Aktiver Besuch':'Active visit'):t('topPick')} kind={activeLive||visitLive?'goldOnDark':'onDark'} dot={activeLive||visitLive}/>
            {activeLive?<span style={{color:'#fff',fontSize:fz(13),fontWeight:700,fontFamily:F,flexShrink:0}}>{prog.stop}/{prog.total} {t('stops')}</span>:visitLive?<span style={{color:'#fff',fontSize:fz(13),fontWeight:700,fontFamily:F,flexShrink:0}}>{Math.min((visitLive.currentStop||0)+1,visitLive.stops.length)}/{visitLive.stops.length}</span>:<Chip label={featured.distance} kind="onDark"/>}
          </span>
          <span style={{display:'-webkit-box',WebkitLineClamp:2,WebkitBoxOrient:'vertical',overflow:'hidden',color:'#fff',fontSize:fz(22),fontWeight:700,fontFamily:FD,letterSpacing:'-0.4px',marginBottom:4,lineHeight:1.2}}>{L((hero).title)}</span>
          <span style={{display:'block',color:'rgba(255,255,255,.88)',fontSize:fz(13),fontFamily:F,marginBottom:16,overflow:'hidden',textOverflow:'ellipsis',whiteSpace:'nowrap'}}>{(hero).venue}</span>
          {activeLive
            ?<span style={{display:'block'}}><PBar val={prog.stop/prog.total*100} onDark label="progress"/><span style={{display:'flex',justifyContent:'flex-end',marginTop:14}}><span style={{display:'inline-flex',alignItems:'center',gap:6,minHeight:40,padding:'9px 20px',borderRadius:100,background:'#fff',color:'var(--ink-deep)',fontSize:fz(13.5),fontWeight:700}}>{t('continueQuest')}<Ic k="arrowR" size={16}/></span></span></span>
            :visitLive
            ?<span style={{display:'block'}}><PBar val={visitLive.stops.length?(visitLive.currentStop||0)/visitLive.stops.length*100:0} onDark label="progress"/><span style={{display:'flex',justifyContent:'flex-end',marginTop:14}}><span style={{display:'inline-flex',alignItems:'center',gap:6,minHeight:40,padding:'9px 20px',borderRadius:100,background:'#fff',color:'var(--ink-deep)',fontSize:fz(13.5),fontWeight:700}}>{lang==='de'?'Besuch fortsetzen':'Continue visit'}<Ic k="arrowR" size={16}/></span></span></span>
            :<span style={{display:'inline-flex',alignItems:'center',gap:6,minHeight:40,padding:'9px 20px',borderRadius:100,background:'#fff',color:'var(--ink-deep)',fontSize:fz(13.5),fontWeight:700}}>{t('viewQuest')}<Ic k="arrowR" size={16}/></span>}
        </span>
      </button>
    </div>
    <Gap n={24}/>
    <SecTitle c={t('quickActions')}/>
    <div className="cu-hscroll" style={{display:'flex',gap:12,overflowX:'auto',padding:`0 ${SP.safe}px 4px`}}>
      <HomeQuickCard
        icon={<Ic k="users" size={22}/>}
        title={t('homeCreateCrew')}
        sub={t('homeCreateCrewSub')}
        accent={{bg:tint(8),bd:tint(24),iconBg:tint(14),iconColor:'var(--ink-deep)'}}
        onClick={()=>{actions.update({activeQuestId:featured.id}); nav.push('crew-mode',{questId:featured.id});}}
      />
      <HomeQuickCard
        icon={<Ic k="sparkle" size={22} fill/>}
        title={t('homeCreateEvent')}
        sub={t('homeCreateEventSub')}
        accent={{bg:'#FBF1DE',bd:'#EACE9B',iconBg:'#F5E6C8',iconColor:T.gold}}
        onClick={()=>nav.push('create')}
      />
      <HomeQuickCard
        icon={<Ic k="map" size={22}/>}
        title={t('homePlanVisit')}
        sub={t('homePlanVisitSub')}
        onClick={()=>nav.push('visit-planner')}
      />
      <HomeQuickCard
        icon={<Ic k="search" size={22}/>}
        title={lang==='de'?'Objekt-Katalog':'Object catalog'}
        sub={lang==='de'?'Scanbare Exponate entdecken':'Browse scannable exhibits'}
        onClick={()=>nav.push('object-catalog')}
      />
    </div>
    <Gap n={28}/>
    {/* explorers near you — only when meeting is on */}
    {state.meetEnabled&&<React.Fragment>
    <SecTitle c={t('peopleNearby')} action={t('seeAll')} onAction={()=>nav.push('discover')}/>
    <div className="cu-hscroll" style={{display:'flex',gap:12,overflowX:'auto',padding:'0 20px 4px'}}>
      {people.map(p=>{
        const lookMap={date:t('lookingDate'),friends:t('lookingFriends'),family:t('lookingFamily'),any:t('lookingAny')};
        return <button key={p.id} type="button" onClick={()=>nav.push('discover',{focus:p.id})} className="cu-press" style={{flexShrink:0,width:148,textAlign:'left',padding:14,borderRadius:18,background:T.card,border:`1.5px solid ${T.line}`,boxShadow:SH,cursor:'pointer'}}>
          <span style={{display:'flex',justifyContent:'space-between',alignItems:'flex-start'}}><Av n={p.name} ci={p.ci} sz={48} photo={p.photo}/><span style={{width:9,height:9,borderRadius:'50%',background:T.green,boxShadow:`0 0 0 2px ${T.card}`,marginTop:3}}></span></span>
          <span style={{display:'block',color:T.text,fontSize:fz(14.5),fontWeight:800,fontFamily:F,margin:'10px 0 1px'}}>{p.name}{p.age?`, ${p.age}`:''}</span>
          <span style={{display:'block',color:'var(--ink-deep)',fontSize:fz(11.5),fontWeight:700,fontFamily:F,marginBottom:3}}>{lookMap[p.looking]}</span>
          <span style={{display:'block',color:T.muted,fontSize:fz(11.5),fontFamily:F}}>{p.dist} {t('away')}</span>
        </button>;
      })}
    </div>
    <Gap n={32}/>
    </React.Fragment>}
    <SecTitle c={t('nearbyChallenges')} action={t('seeAll')} onAction={()=>nav.goTab('explore')}/>
    <div style={{padding:`0 ${SP.safe}px`,display:'flex',flexDirection:'column',gap:12}}>
      {nearby.map(q=><QuestCard key={q.id} q={q} compact/>)}
    </div>
    <Gap n={40}/>
  </div>;
}

/* shared quest card */
function QuestCard({q,compact}){
  const{lang,nav,t}=useApp();
  const L=(v)=>pick(v,lang);
  return <Card onClick={()=>nav.push('event-detail',{questId:q.id})} padding="13px">
    <div style={{display:'flex',gap:13,alignItems:'center'}}>
      <div style={{position:'relative',flexShrink:0}}>
        <Thumb src={q.img} alt="" size={compact?70:84} radius={14}/>
        {q.special&&<span style={{position:'absolute',top:-5,left:-5}}><Chip label={q.badge==='official'?t('official'):t('special')} kind="gold" style={{fontSize:fz(10),padding:'2px 7px',boxShadow:SH}}/></span>}
      </div>
      <div style={{flex:1,minWidth:0}}>
        <div style={{color:T.text,fontSize:fz(15),fontWeight:700,fontFamily:F,lineHeight:1.3,marginBottom:3,overflow:'hidden',textOverflow:'ellipsis',whiteSpace:'nowrap'}}>{L(q.title)}</div>
        <p style={{color:T.muted,fontSize:fz(12),fontFamily:F,margin:'0 0 7px',overflow:'hidden',textOverflow:'ellipsis',whiteSpace:'nowrap'}}>{q.venue} · {q.distance}</p>
        <div style={{display:'flex',gap:12}}>
          <span style={{color:T.sub,fontSize:fz(12),fontFamily:F}}>{q.stops.length} {t('stops')}</span>
          <span style={{color:T.sub,fontSize:fz(12),fontFamily:F}}>{q.dur} {t('min')}</span>
          <span style={{color:'var(--ink-deep)',fontSize:fz(12),fontWeight:700,fontFamily:F}}>{q.teams} {t('teams')}</span>
        </div>
      </div>
      <Ic k="chevR" size={20} color={T.muted} style={{flexShrink:0}}/>
    </div>
  </Card>;
}

/* ── EXPLORE ── */
function ExploreScreen(){
  const{t,lang,nav}=useApp();
  const L=(v)=>pick(v,lang);
  const[f,setF]=useMainState('allFilter');
  const[q,setQ]=useMainState('');
  const filters=['allFilter','museumFilter','outdoorFilter','familyFilter','competitiveFilter'];
  let list=window.DATA.QUESTS;
  if(f==='outdoorFilter') list=list.filter(x=>x.outdoor);
  if(f==='competitiveFilter') list=list.filter(x=>x.teams>30);
  if(q) list=list.filter(x=>(L(x.title)+x.venue).toLowerCase().includes(q.toLowerCase()));
  return <div data-screen-label="Explore" className="cu-scroll" style={{flex:1,overflowY:'auto',background:T.bg}}>
    
    <header style={{padding:`10px ${SP.safe}px 16px`,display:'flex',justifyContent:'space-between',alignItems:'center'}}>
      <div><h1 style={{color:T.text,fontSize:fz(28),fontWeight:700,fontFamily:FD,letterSpacing:'-0.7px',margin:0}}>{t('explore')}</h1>
      <p style={{color:T.muted,fontSize:fz(14),fontFamily:F,margin:'4px 0 0'}}>Tehran · Munich</p></div>
      <Btn label={`+ ${t('create')}`} variant="tonal" sm full={false} onClick={()=>nav.push('create')}/>
    </header>
    <div style={{padding:`0 ${SP.safe}px 16px`}}>
      <label style={{display:'flex',gap:10,alignItems:'center',padding:'0 14px',minHeight:50,borderRadius:14,background:T.card,border:`1.5px solid ${T.line}`,boxShadow:SH}}>
        <Ic k="search" size={18} color={T.muted}/>
        <input type="search" value={q} onChange={e=>setQ(e.target.value)} aria-label={t('searchPlaceholder')} placeholder={t('searchPlaceholder')} style={{flex:1,border:'none',outline:'none',background:'transparent',color:T.text,fontSize:fz(14.5),fontFamily:F,minWidth:0}}/>
      </label>
    </div>
    <div className="cu-hscroll" style={{padding:`0 ${SP.safe}px`,display:'flex',gap:8,overflowX:'auto',marginBottom:20}}>
      {filters.map(fi=><button key={fi} type="button" onClick={()=>setF(fi)} className="cu-press" style={{minHeight:40,padding:'8px 16px',borderRadius:100,border:`1.5px solid ${fi===f?'var(--ink)':T.lineMd}`,cursor:'pointer',background:fi===f?'var(--ink)':T.card,color:fi===f?'#fff':T.sub,fontSize:fz(13),fontWeight:700,fontFamily:F,whiteSpace:'nowrap',flexShrink:0}}>{t(fi)}</button>)}
    </div>
    <div style={{padding:`0 ${SP.safe}px`,display:'flex',flexDirection:'column',gap:14}}>
      {list.length===0
        ?<EmptyState icon={<Ic k="search" size={22}/>} title={lang==='de'?'Keine Quests gefunden':'No quests found'} message={lang==='de'?'Versuche einen anderen Filter oder Suchbegriff.':'Try a different filter or search term.'}/>
        :list.map(qq=>
        <Card key={qq.id} onClick={()=>nav.push('event-detail',{questId:qq.id})} padding="0" style={{overflow:'hidden'}}>
          <Photo src={qq.img} alt={qq.venue} h={150} radius={0} overlay="linear-gradient(180deg,rgba(16,12,28,0) 30%,rgba(16,12,28,.7) 100%)">
            <div style={{position:'absolute',top:12,left:12,right:12,display:'flex',justifyContent:'space-between'}}>
              {qq.special?<Chip label={qq.badge==='official'?t('official'):t('special')} kind="gold"/>:<span></span>}
              <Chip label={qq.distance} kind="onDark"/>
            </div>
            <div style={{position:'absolute',left:14,bottom:12,right:14}}>
              <span style={{display:'block',color:'#fff',fontSize:fz(18),fontWeight:700,fontFamily:FD,letterSpacing:'-0.3px',overflow:'hidden',textOverflow:'ellipsis',whiteSpace:'nowrap'}}>{L(qq.title)}</span>
              <span style={{display:'block',color:'rgba(255,255,255,.86)',fontSize:fz(12.5),fontFamily:F,overflow:'hidden',textOverflow:'ellipsis',whiteSpace:'nowrap'}}>{qq.venue}</span>
            </div>
          </Photo>
          <div style={{padding:'12px 14px 14px'}}>
            <div style={{display:'flex',gap:12,alignItems:'center',marginBottom:8}}>
              <span style={{color:T.sub,fontSize:fz(12.5),fontFamily:F}}>{qq.stops.length} {t('stops')}</span>
              <span style={{color:T.sub,fontSize:fz(12.5),fontFamily:F}}>{qq.dur} {t('min')}</span>
              <span style={{color:T.sub,fontSize:fz(12.5),fontFamily:F}}>{qq.teams} {t('teams')}</span>
            </div>
            <div style={{display:'flex',alignItems:'center',gap:5,color:T.gold,fontSize:fz(12.5),fontWeight:700,fontFamily:F,overflow:'hidden',textOverflow:'ellipsis',whiteSpace:'nowrap'}}><span style={{flexShrink:0}}>🏆</span><span style={{overflow:'hidden',textOverflow:'ellipsis'}}>{L(qq.prize)}</span></div>
          </div>
        </Card>
      )}
    </div>
    <Gap n={32}/>
  </div>;
}

/* ── QUEST DETAIL ── */
function EventDetailScreen(){
  const{t,lang,nav,route,actions,state}=useApp();
  const L=(v)=>pick(v,lang);
  const[showAllJoin,setShowAllJoin]=useMainState(false);
  const q=window.DATA.questById(route.p.questId)||window.DATA.QUESTS[0];
  const stops=q.stops.map(L);
  const nearbyTeams=(window.DATA.OPEN_TEAMS||[]).filter(ot=>ot.questId===q.id);
  const nearbySolo=(window.DATA.OPEN_SOLO||[]).filter(os=>os.questId===q.id);
  const lookMap={date:t('lookingDate'),friends:t('lookingFriends'),family:t('lookingFamily'),any:t('lookingAny')};
  const hasNearby=nearbyTeams.length>0||nearbySolo.length>0;

  function joinTeam(ot){
    const requested=(state?.requestedTeams||[]).includes(ot.id);
    if(requested) return;
    const team=actions.joinOpenTeam(ot.id);
    if(team){ actions.update({activeQuestId:q.id}); showToast(`${t('joinedToast')} · ${team.name}`,{icon:<Ic k="check" size={15} color="#34C759"/>}); nav.push('group-lobby',{code:team.code}); }
  }
  function invitePerson(os){
    const p=window.DATA.PEOPLE.find(x=>x.id===os.personId);
    if(!p||(state?.invitedSolo||[]).includes(os.id)) return;
    const c=actions.createCrew({questId:q.id,mode:'friends',name:`${p.name}'s team`});
    actions.update(s=>{
      const crews=s.crews.map(cr=>cr.code===c.code?{...cr,invites:[...(cr.invites||[]),{id:'solo'+os.id,type:'email',value:p.name,status:'pending',name:p.name}]}:cr);
      const updated=crews.find(cr=>cr.code===c.code);
      if(updated) window.CurioStore.savePublicCrew(updated.code, updated);
      return {...s,crews,activeQuestId:q.id,invitedSolo:[...(s.invitedSolo||[]),os.id]};
    });
    showToast(lang==='de'?`${p.name} eingeladen`:`Invite sent to ${p.name}`,{icon:<Ic k="check" size={15} color="#34C759"/>});
    nav.push('group-lobby',{code:c.code});
  }

  function renderTeamCard(ot,{compact=false}={}){
    const requested=(state?.requestedTeams||[]).includes(ot.id);
    const meta=`${ot.members} ${t('members')} · ${lang==='de'?`${ot.needs} Plätze frei`:`${ot.needs} spots open`}`;
    return <Card key={'t-'+ot.id} padding="14px" style={compact?{flexShrink:0,width:248,display:'flex',flexDirection:'column'}:undefined}>
      <div style={{display:'flex',justifyContent:'space-between',alignItems:'flex-start',gap:8,marginBottom:12}}>
        <div style={{flex:1,minWidth:0}}>
          <div style={{color:T.text,fontSize:fz(14.5),fontWeight:800,fontFamily:F,lineHeight:1.25,overflow:'hidden',textOverflow:'ellipsis',whiteSpace:compact?'nowrap':'normal'}}>{ot.name}</div>
          <div style={{color:T.muted,fontSize:fz(12),fontFamily:F,marginTop:4}}>{t('crew')} · {meta}</div>
        </div>
        <Chip label={ot.distance||''} kind="neutral"/>
      </div>
      <div style={{display:'flex',gap:10,alignItems:'center',marginBottom:10}}>
        <AvStack names={Array(ot.members).fill('T')} photos={ot.photos} sz={28}/>
      </div>
      <p style={{color:T.sub,fontSize:fz(12.5),fontFamily:F,margin:'0 0 12px',lineHeight:1.5,flex:compact?1:undefined,display:compact?'-webkit-box':'block',WebkitLineClamp:compact?2:undefined,WebkitBoxOrient:compact?'vertical':undefined,overflow:compact?'hidden':undefined}}>{L(ot.blurb)}</p>
      <Btn label={requested?(lang==='de'?'Angefragt':'Requested'):t('join')} variant="secondary" sm disabled={requested} onClick={()=>joinTeam(ot)}/>
    </Card>;
  }

  function renderPersonCard(os,{compact=false}={}){
    const p=window.DATA.PEOPLE.find(x=>x.id===os.personId);
    if(!p) return null;
    const invited=(state?.invitedSolo||[]).includes(os.id);
    return <Card key={'p-'+os.id} padding="14px" style={compact?{flexShrink:0,width:248,display:'flex',flexDirection:'column'}:undefined}>
      <div style={{display:'flex',gap:12,alignItems:'center',marginBottom:10}}>
        <div style={{position:'relative',flexShrink:0}}>
          <Av n={p.name} ci={p.ci} sz={40} photo={p.photo} ring/>
          {p.online&&<span style={{position:'absolute',bottom:0,right:0,width:10,height:10,borderRadius:'50%',background:T.green,border:`2px solid ${T.card}`}}></span>}
        </div>
        <div style={{flex:1,minWidth:0}}>
          <div style={{display:'flex',justifyContent:'space-between',alignItems:'flex-start',gap:6}}>
            <div style={{color:T.text,fontSize:fz(14.5),fontWeight:800,fontFamily:F,lineHeight:1.25,overflow:'hidden',textOverflow:'ellipsis',whiteSpace:'nowrap'}}>{p.name}{p.age?`, ${p.age}`:''}</div>
            <Chip label={os.distance||p.dist||''} kind="neutral"/>
          </div>
          <div style={{color:T.muted,fontSize:fz(12),fontFamily:F,marginTop:4}}>{lang==='de'?'Einzelperson':'Individual'} · {lookMap[p.looking]||lookMap.friends}</div>
        </div>
      </div>
      <p style={{color:T.sub,fontSize:fz(12.5),fontFamily:F,margin:'0 0 12px',lineHeight:1.5,flex:compact?1:undefined,display:compact?'-webkit-box':'block',WebkitLineClamp:compact?2:undefined,WebkitBoxOrient:compact?'vertical':undefined,overflow:compact?'hidden':undefined}}>{L(os.blurb)}</p>
      <div style={{display:'flex',gap:8}}>
        <Btn label={invited?(lang==='de'?'Eingeladen':'Invited'):t('inviteToCrew')} variant="secondary" sm disabled={invited} onClick={()=>invitePerson(os)} style={{flex:1}}/>
        {!compact&&<Btn label={t('connect')} variant="tonal" sm full={false} onClick={()=>nav.push('discover',{focus:p.id})}/>}
      </div>
    </Card>;
  }

  return <div data-screen-label="Quest Detail" className="cu-step-shell">
    <div className="cu-step-body cu-scroll" style={{flex:1,overflowY:'auto',background:T.bg}}>
    <Photo src={q.img} alt={q.venue} h={240} radius={0} overlay="linear-gradient(180deg, rgba(16,12,28,.1) 0%, rgba(16,12,28,.82) 100%)">
      <div style={{position:'absolute',top:12,left:14}}><IconBtn k="arrowL" onDark onClick={nav.pop} ariaLabel={t('back')}/></div>
      <div style={{position:'absolute',left:20,right:20,bottom:18}}>
        {q.special&&<Chip label={q.badge==='official'?t('official'):t('special')} kind="onDark"/>}
        <h1 style={{display:'-webkit-box',WebkitLineClamp:2,WebkitBoxOrient:'vertical',overflow:'hidden',color:'#fff',fontSize:fz(26),fontWeight:700,fontFamily:FD,letterSpacing:'-0.7px',margin:'10px 0 4px',lineHeight:1.15}}>{L(q.title)}</h1>
        <p style={{color:'rgba(255,255,255,.88)',fontSize:fz(13.5),fontFamily:F,margin:0,display:'flex',alignItems:'center',gap:5,overflow:'hidden',textOverflow:'ellipsis',whiteSpace:'nowrap'}}><Ic k="location" size={15} style={{flexShrink:0}}/>{q.venue}</p>
      </div>
    </Photo>
    <div style={{padding:`16px ${SP.safe}px calc(24px + var(--cu-safe-bottom))`}}>
      <p style={{color:T.sub,fontSize:fz(15),fontFamily:F,lineHeight:1.65,margin:'0 0 18px'}}>{L(q.blurb)}</p>
      <div style={{display:'flex',gap:10,marginBottom:20}}>
        {[{l:t('difficulty'),v:L(q.difficulty)},{l:t('players'),v:q.players},{l:t('stops'),v:q.stops.length},{l:t('min'),v:q.dur}].map(s=>
          <div key={s.l} style={{flex:1,padding:'12px 4px',borderRadius:14,background:T.card,border:`1.5px solid ${T.line}`,boxShadow:SH,textAlign:'center'}}>
            <div style={{color:T.text,fontSize:fz(14),fontWeight:800,fontFamily:F,whiteSpace:'nowrap'}}>{s.v}</div>
            <div style={{color:T.muted,fontSize:fz(10.5),fontFamily:F,marginTop:2}}>{s.l}</div>
          </div>)}
      </div>

      {hasNearby&&<>
        <SecTitle c={t('joinNearbyTeams')} action={t('seeAll')} onAction={()=>setShowAllJoin(true)}/>
        <div className="cu-hscroll" style={{display:'flex',gap:12,overflowX:'auto',padding:`0 ${SP.safe}px 16px`,margin:`0 -${SP.safe}px 8px`}}>
          {nearbyTeams.map(ot=>renderTeamCard(ot,{compact:true}))}
          {nearbySolo.map(os=>renderPersonCard(os,{compact:true}))}
        </div>
      </>}

      <div style={{display:'flex',flexDirection:'row',alignItems:'stretch',gap:8,marginBottom:24}}>
        <Btn label={t('createYourCrew')} variant="tonal" icon={<Ic k="users" size={15}/>} sm full={false} style={{flex:1,minHeight:36,padding:'8px 10px',fontSize:fz(12.5),borderRadius:12}} onClick={()=>{actions.update({activeQuestId:q.id}); nav.push('crew-mode',{questId:q.id});}}/>
        <Btn label={t('soloRun')} variant="secondary" sm full={false} style={{flex:1,minHeight:36,padding:'8px 10px',fontSize:fz(12.5),borderRadius:12}} onClick={()=>{actions.startQuest(q.id,'solo'); nav.push('quest-brief',{questId:q.id});}}/>
      </div>

      <h2 style={{color:T.text,fontSize:fz(17),fontWeight:700,fontFamily:FD,margin:'0 0 12px'}}>{t('liveMap')}</h2>
      <div style={{margin:`0 -${SP.safe}px 20px`}}>
        <MuseumMapContent q={q} prog={{stop:0,total:q.stops.length,completed:false}} lang={lang} nav={nav} hideStops compact showObjects nextLabel={t('nextStop')}/>
      </div>
      <h2 style={{color:T.text,fontSize:fz(17),fontWeight:700,fontFamily:FD,margin:'0 0 12px'}}>{t('prizes')}</h2>
      <div style={{display:'flex',flexDirection:'column',gap:10,marginBottom:22}}>
        {q.prizes.map((p,i)=><ListRow key={i} iconKind="gold" emoji={p.top?'🏆':'🎖️'} title={L(p.p)} sub={L(p.r)} trailing={p.top?<Chip label={t('special')} kind="gold"/>:null}/>)}
      </div>
      <h2 style={{color:T.text,fontSize:fz(17),fontWeight:700,fontFamily:FD,margin:'0 0 14px'}}>{t('questStops')}</h2>
      <Stops stops={stops} activeIndex={-1}/>
    </div>
    </div>

    {showAllJoin&&<Sheet onClose={()=>setShowAllJoin(false)}>
      <h2 style={{color:T.text,fontSize:fz(20),fontWeight:800,fontFamily:FD,margin:'0 0 16px'}}>{t('joinNearbyTeams')}</h2>
      <div style={{display:'flex',flexDirection:'column',gap:10,maxHeight:'min(62vh,520px)',overflowY:'auto'}}>
        {nearbyTeams.map(ot=>renderTeamCard(ot))}
        {nearbySolo.map(os=>renderPersonCard(os))}
      </div>
      <Gap n={12}/>
      <Btn label={t('close')} variant="secondary" onClick={()=>setShowAllJoin(false)}/>
    </Sheet>}
  </div>;
}

/* ── PROFILE ── */
function ProfileScreen(){
  const{t,lang,state,user,nav,actions,setLang}=useApp();
  const L=(v)=>pick(v,lang);
  const[showShare,setShowShare]=useMainState(false);
  const[shareCopied,setShareCopied]=useMainState(false);
  const info=window.CurioStore.levelInfo(state.xp);
  const earned=window.DATA.BADGES.filter(b=>state.badges.includes(b.id));
  const locked=window.DATA.BADGES.filter(b=>!state.badges.includes(b.id));
  const stats=[{l:t('quests'),v:Object.values(state.questProgress).filter(p=>p.completed).length||0},{l:t('badges'),v:state.badges.length},{l:t('groups'),v:state.crews.length},{l:t('connections'),v:state.connections.length}];
  /* illustrative global rank — derived from XP, no live backend to rank against */
  const totalExplorers=3800;
  const globalRank=Math.max(1,totalExplorers-Math.round(state.xp*1.8));
  return <div data-screen-label="Profile" className="cu-scroll" style={{flex:1,overflowY:'auto',background:T.bg}}>
    
    <div style={{padding:'10px 20px 0',textAlign:'center'}}>
      <span style={{display:'inline-flex',marginBottom:12}}><Av n={state.name||user.name} ci={state.avatar} sz={84} photo={state.photo}/></span>
      <h1 style={{color:T.text,fontSize:fz(23),fontWeight:800,fontFamily:FD,letterSpacing:'-0.5px',margin:0}}>{state.name||user.name}</h1>
      <p style={{color:T.muted,fontSize:fz(13.5),fontFamily:F,margin:'3px 0 10px'}}>{t('level')} {info.level} {t('explorerLvl')} · 🔥 {state.streak}</p>
      <span style={{display:'inline-flex',alignItems:'center',gap:6,padding:'5px 12px',borderRadius:100,background:tint(10),border:`1px solid ${tint(26)}`,marginBottom:16}}>
        <Ic k="trophy" size={13} color="var(--ink-deep)"/>
        <span style={{color:'var(--ink-deep)',fontSize:fz(12.5),fontWeight:700,fontFamily:F}}>{lang==='de'?`Rang #${globalRank.toLocaleString()} von ${totalExplorers.toLocaleString()}`:`Rank #${globalRank.toLocaleString()} of ${totalExplorers.toLocaleString()} explorers`}</span>
      </span>
      <div style={{padding:'0 10px'}}><LevelBar xp={state.xp}/></div>
    </div>
    <Gap n={22}/>
    <div style={{padding:'0 20px',display:'flex',gap:8,marginBottom:24}}>
      {stats.map(s=><div key={s.l} style={{flex:1,padding:'13px 0',borderRadius:14,background:T.card,border:`1.5px solid ${T.line}`,boxShadow:SH,textAlign:'center'}}>
        <div style={{color:'var(--ink-deep)',fontSize:fz(19),fontWeight:800,fontFamily:FD}}>{s.v}</div>
        <div style={{color:T.muted,fontSize:fz(11),fontFamily:F,marginTop:2}}>{s.l}</div>
      </div>)}
    </div>
        <div style={{padding:'0 20px',marginBottom:24}}>
      <Card onClick={()=>nav.push('rewards')} padding="14px">
        <div style={{display:'flex',alignItems:'center',gap:12}}>
          <span style={{width:44,height:44,borderRadius:13,background:GRAD,display:'inline-flex',alignItems:'center',justifyContent:'center',fontSize:21,flexShrink:0}}>🏅</span>
          <div style={{flex:1,minWidth:0}}>
            <div style={{color:T.text,fontSize:fz(15),fontWeight:800,fontFamily:F}}>{pick({en:'Rewards & badges',de:'Belohnungen & Abzeichen'},lang)}</div>
            <div style={{color:T.muted,fontSize:fz(12.5),fontFamily:F,marginTop:1}}>{pick({en:'Points, levels & bonuses',de:'Punkte, Level & Boni'},lang)}</div>
          </div>
          <Ic k="chevR" size={18} color={T.muted}/>
        </div>
      </Card>
    </div>
    <SecTitle c={t('myBadges')}/>
    <div style={{padding:'0 20px',display:'grid',gridTemplateColumns:'repeat(4,1fr)',gap:10,marginBottom:26}}>
      {earned.map(b=><div key={b.id} style={{aspectRatio:'1',borderRadius:16,background:tint(9),border:`1.5px solid ${tint(24)}`,display:'flex',flexDirection:'column',alignItems:'center',justifyContent:'center',gap:3}}>
        <span style={{fontSize:24}}>{b.icon}</span><span style={{fontSize:fz(9.5),fontWeight:700,fontFamily:F,color:'var(--ink-deep)',textAlign:'center',lineHeight:1.1,padding:'0 2px'}}>{L(b.name)}</span></div>)}
      {locked.slice(0,8-earned.length).map(b=><div key={b.id} style={{aspectRatio:'1',borderRadius:16,background:T.cardAlt,border:`1.5px dashed ${T.lineMd}`,display:'flex',alignItems:'center',justifyContent:'center',opacity:.5}}><span style={{fontSize:22,filter:'grayscale(1)'}}>{b.icon}</span></div>)}
    </div>
    <SecTitle c={t('myCreated')}/>
    <div style={{padding:'0 20px',marginBottom:24}}>
      {(state.createdQuests||[]).length>0
        ?<div style={{display:'flex',flexDirection:'column',gap:10}}>
          {state.createdQuests.map((c,i)=><Card key={c.code||i} padding="13px">
            <div style={{display:'flex',gap:11,alignItems:'center'}}>
              <span style={{width:44,height:44,borderRadius:13,background:GRAD,display:'inline-flex',alignItems:'center',justifyContent:'center',color:'#fff',flexShrink:0}}><Ic k="sparkle" size={20} fill/></span>
              <div style={{flex:1,minWidth:0}}>
                <div style={{color:T.text,fontSize:fz(14.5),fontWeight:700,fontFamily:F,overflow:'hidden',textOverflow:'ellipsis',whiteSpace:'nowrap'}}>{c.title||'Quest'}</div>
                <div style={{color:T.muted,fontSize:fz(12),fontFamily:F}}>{c.code} · {lang==='de'?'Veröffentlicht':'Published'}</div>
              </div>
              <button type="button" onClick={()=>{actions.deleteCreatedQuest(c.code); showToast(lang==='de'?'Quest gelöscht':'Quest deleted');}} aria-label={lang==='de'?'Löschen':'Delete'} className="cu-press" style={{width:36,height:36,borderRadius:18,border:'none',background:T.cardAlt,cursor:'pointer',display:'flex',alignItems:'center',justifyContent:'center',flexShrink:0}}><Ic k="x" size={16} color={T.muted}/></button>
            </div>
          </Card>)}
        </div>
        :<EmptyState emoji="✨" title={lang==='de'?'Noch keine eigenen Quests':'No quests created yet'} message={t('shareQuestWithTeam')} actionLabel={t('create')} onAction={()=>nav.push('create')}/>}
    </div>
    <SecTitle c={t('myCrews')}/>
    <div style={{padding:'0 20px',marginBottom:24}}>
      {state.crews.length>0
        ?<div style={{display:'flex',flexDirection:'column',gap:10}}>
          {state.crews.map((c,i)=><Card key={i} onClick={()=>nav.push('group-lobby',{code:c.code})} padding="13px">
            <div style={{display:'flex',gap:11,alignItems:'center'}}>
              <AvStack names={(c.members||[]).map(m=>m.n).concat(state.name||'You')} sz={28}/>
              <div style={{flex:1,minWidth:0}}>
                <div style={{color:T.text,fontSize:fz(14.5),fontWeight:700,fontFamily:F,overflow:'hidden',textOverflow:'ellipsis',whiteSpace:'nowrap'}}>{c.name}</div>
                <div style={{color:T.muted,fontSize:fz(12),fontFamily:F,overflow:'hidden',textOverflow:'ellipsis',whiteSpace:'nowrap'}}>{(c.members||[]).length+1} {(c.members||[]).length+1===1?t('member1'):t('members')} · {c.code}</div>
              </div>
              <button type="button" onClick={e=>{e.stopPropagation(); actions.deleteCrew(c.code); showToast(t('teamDeleted'));}} aria-label={lang==='de'?'Löschen':'Delete'} className="cu-press" style={{width:36,height:36,borderRadius:18,border:'none',background:T.cardAlt,cursor:'pointer',display:'flex',alignItems:'center',justifyContent:'center',flexShrink:0}}><Ic k="x" size={16} color={T.muted}/></button>
              <Ic k="chevR" size={18} color={T.muted} style={{flexShrink:0}}/>
            </div></Card>)}
        </div>
        :<EmptyState emoji="👥" title={t('noCrewsYet')} message={t('noCrewsYetSub')} actionLabel={t('startACrew')} onAction={()=>nav.goTab('explore')}/>}
    </div>
    {/* settings */}
    <SecTitle c={t('settings')}/>
    <div style={{padding:'0 20px',display:'flex',flexDirection:'column',gap:10}}>
      {/* meeting people preference */}
      <div style={{borderRadius:16,background:T.card,border:`1.5px solid ${state.meetEnabled?tint(26):'rgba(60,60,67,.12)'}`,boxShadow:SH,overflow:'hidden'}}>
        <div style={{display:'flex',alignItems:'center',gap:12,padding:'14px'}}>
        <span style={{width:42,height:42,borderRadius:12,background:state.meetEnabled?GRAD:T.cardAlt,display:'inline-flex',alignItems:'center',justifyContent:'center',fontSize:20,flexShrink:0}}>👋</span>
        <span style={{flex:1,minWidth:0}}>
          <span style={{display:'block',color:T.text,fontSize:fz(14.5),fontWeight:800,fontFamily:F}}>{t('meetingPeople')}</span>
          <span style={{display:'block',color:T.muted,fontSize:fz(12),fontFamily:F,marginTop:1}}>{t('meetSetting')}</span>
        </span>
        <Switch checked={!!state.meetEnabled} onChange={v=>actions.setMeet({meetEnabled:v})} ariaLabel={t('meetSetting')}/>
        </div>
        {state.meetEnabled&&<div style={{padding:'0 14px 14px'}}>
          <div style={{height:1,background:T.line,margin:'0 0 12px'}}></div>
          <div style={{color:T.muted,fontSize:fz(11.5),fontWeight:800,fontFamily:F,textTransform:'uppercase',letterSpacing:'.5px',marginBottom:9}}>{t('openTo')}</div>
          <div role="radiogroup" style={{display:'flex',gap:8}}>
            {[{id:'friends',e:'🤝',k:'lookFriendsShort'},{id:'date',e:'💘',k:'lookDateShort'},{id:'both',e:'✨',k:'lookBothShort'}].map(o=>{
              const on=state.meetLooking===o.id;
              return <button key={o.id} type="button" role="radio" aria-checked={on} onClick={()=>actions.setMeet({meetLooking:o.id})} className="cu-press" style={{flex:1,minWidth:0,display:'flex',flexDirection:'column',alignItems:'center',gap:6,padding:'13px 4px',borderRadius:13,border:`1.5px solid ${on?tint(40):'#C7C7CC'}`,background:on?tint(8):T.cardAlt,cursor:'pointer'}}>
                <span style={{fontSize:19}}>{o.e}</span>
                <span style={{color:on?'var(--ink-deep)':T.sub,fontSize:fz(12),fontWeight:800,fontFamily:F,textAlign:'center',lineHeight:1.2,whiteSpace:'nowrap'}}>{t(o.k)}</span>
              </button>;
            })}
          </div>
        </div>}
      </div>
      <div style={{display:'flex',alignItems:'center',gap:12,padding:'14px',borderRadius:16,background:T.card,border:`1.5px solid ${T.line}`,boxShadow:SH}}>
        <span style={{width:42,height:42,borderRadius:12,background:T.cardAlt,display:'inline-flex',alignItems:'center',justifyContent:'center',color:T.sub}}><Ic k="globe" size={20}/></span>
        <span style={{flex:1,color:T.text,fontSize:fz(14.5),fontWeight:700,fontFamily:F}}>{t('appLanguage')}</span>
        <div style={{display:'inline-flex',background:T.cardAlt,borderRadius:100,padding:3}}>
          {['en','de'].map(l=><button key={l} type="button" onClick={()=>setLang(l)} className="cu-press" style={{minWidth:42,minHeight:34,borderRadius:100,border:'none',cursor:'pointer',background:lang===l?'var(--ink)':'transparent',color:lang===l?'#fff':T.sub,fontSize:13,fontWeight:700,fontFamily:F,transition:`background .2s ${EASE}`}}>{l.toUpperCase()}</button>)}
        </div>
      </div>
      <ListRow icon={<Ic k="qr" size={20}/>} iconKind="brand" title={t('openOnPhone')} sub={t('openOnPhoneSub')} onClick={()=>setShowShare(true)} trailing={<Ic k="chevR" size={18} color={T.muted}/>}/>
      <ListRow icon={<Ic k="share" size={20}/>} iconKind="neutral" title={t('editProfile')} onClick={()=>nav.push('onboard-edit')} trailing={<Ic k="chevR" size={18} color={T.muted}/>}/>
      <Btn label={t('logOut')} variant="secondary" onClick={()=>actions.logout()} style={{marginTop:6}}/>
    </div>
    {showShare&&<Sheet onClose={()=>setShowShare(false)}>
      <div style={{textAlign:'center',padding:'2px 0 4px'}}>
        <h2 style={{color:T.text,fontSize:fz(20),fontWeight:800,fontFamily:FD,margin:'0 0 4px'}}>{t('openOnPhone')}</h2>
        <p style={{color:T.muted,fontSize:fz(13),fontFamily:F,margin:'0 0 18px'}}>{t('scanToOpen')}</p>
        <div style={{display:'flex',justifyContent:'center',marginBottom:16}}>
          <div style={{padding:16,borderRadius:20,background:'#fff',boxShadow:SHmd,border:`1.5px solid ${T.line}`}}><QR text={joinUrl()} size={196}/></div>
        </div>
        <p style={{color:T.sub,fontSize:fz(13.5),fontWeight:700,fontFamily:F,wordBreak:'break-all',margin:'0 0 16px'}}>{prettyUrl()}</p>
        <Btn label={shareCopied?t('copied'):t('copy')} variant="secondary" icon={<Ic k="share" size={17}/>} onClick={()=>{try{navigator.clipboard&&navigator.clipboard.writeText(joinUrl());}catch(e){} setShareCopied(true); setTimeout(()=>setShareCopied(false),1500);}}/>
      </div>
    </Sheet>}
    <Gap n={36}/>
  </div>;
}

Object.assign(window,{HomeScreen,ExploreScreen,EventDetailScreen,ProfileScreen,QuestCard});
