// sc-screens-core.jsx — Group Detail (V2: comments, scored pending), Activity (cross-mode), Profile

// ─── Group Detail ──────────────────────────────────────────────────────
function GroupDetailScreen({ groupId, viewerId, onBack, onOpenPhoto, onOpenHead, onSettings, onSpot }){
  const s = useStore();
  const g = s.groups.find(x=>x.id===groupId);
  if (!g) return null;
  const item = s.itemById[g.itemId];
  const holder = g.holderId ? s.people[g.holderId] : null;

  // leaderboard
  const lb = g.members.map(mid=>{
    const person = s.people[mid];
    const claims = g.spots.filter(sp=>sp.byId===mid).length;
    return { id:mid, person, claims };
  }).sort((a,b)=>b.claims-a.claims);

  const mine = viewerId===g.holderId;
  const title = g.titleOverride || item.title;

  // Combined timeline: pendingSpots first, then confirmed spots, sorted by time
  const timeline = [
    ...g.pendingSpots.map(p=>({...p, _kind:'pending'})),
    ...g.spots.map(sp=>({...sp, _kind:'confirmed'})),
  ].sort((a,b)=>b.at-a.at);

  return (
    <>
      <NavBar compact title={g.name} onBack={onBack}
        right={<button onClick={onSettings} className="tap" style={{
          border:'none', background:'transparent', padding:6,
        }}><Icon name="dots" size={20} color="var(--ink-2)"/></button>}/>

      <ScrollBody>
        {/* Hero holder card */}
        <Card style={{
          padding:16, marginTop:4, marginBottom:14,
          background:'linear-gradient(180deg, #FFFDF8 0%, #FFF 100%)',
          boxShadow:'0 0 0 1.5px var(--crown-soft), 0 1px 2px rgba(0,0,0,0.04)',
        }}>
          <div style={{display:'flex', alignItems:'center', gap:14}}>
            {holder ? (
              <div style={{position:'relative'}}>
                <Ava person={holder} size={66} ring/>
                <div style={{position:'absolute', top:-12, left:'50%', transform:'translateX(-50%) rotate(-4deg)'}}>
                  <Crown size={26} color="var(--crown)"/>
                </div>
              </div>
            ) : (
              <div style={{width:66,height:66,borderRadius:'50%',border:'2px dashed var(--crown)',
                display:'flex', alignItems:'center', justifyContent:'center', color:'var(--crown-2)'}}>
                <Crown size={26} color="var(--crown)" filled={false}/>
              </div>
            )}
            <div style={{flex:1, minWidth:0}}>
              {holder ? (
                <>
                  <div style={{fontSize:11, letterSpacing:'.08em', fontWeight:600, color:'var(--crown-2)', textTransform:'uppercase'}}>
                    {title}{mine && ' · you'}
                  </div>
                  <div style={{fontSize:20, fontWeight:700, letterSpacing:'-.02em', marginTop:2}}>
                    {mine ? 'You' : holder.name}
                  </div>
                  <div style={{fontSize:13, color:'var(--muted)', marginTop:2}}>
                    Holding · {fmtHeld(g.heldSince)}
                  </div>
                </>
              ) : (
                <>
                  <div style={{fontSize:11, letterSpacing:'.08em', fontWeight:600, color:'var(--crown-2)', textTransform:'uppercase'}}>Vacant</div>
                  <div style={{fontSize:18, fontWeight:600, letterSpacing:'-.01em', marginTop:2}}>No {title.toLowerCase()} yet</div>
                </>
              )}
            </div>
            <ItemTile item={item} size={50} rounded={12}/>
          </div>

          {/* Spot button */}
          <div style={{marginTop:14}}>
            <Btn onClick={onSpot} leading={<Icon name="cam" size={16} color="#fff" stroke={2.2}/>}>
              I spotted a {item.name.toLowerCase()}
            </Btn>
          </div>

          {/* Quick stats */}
          <div style={{
            display:'grid', gridTemplateColumns:'1fr 1fr 1fr', gap:10,
            marginTop:14, padding:'12px 0 0', borderTop:'0.5px solid var(--hair)',
          }}>
            {[
              { v: g.spots.filter(sp=>sp.byId===viewerId).length, l:'Your claims'},
              { v: g.streak, l:'Streak'},
              { v: '#'+(lb.findIndex(x=>x.id===viewerId)+1 || '—'), l:'Rank'},
            ].map((x,i)=>(
              <div key={i} style={{textAlign:'center'}}>
                <div style={{fontSize:22, fontWeight:600, letterSpacing:'-.02em'}}>{x.v}</div>
                <div style={{fontSize:11.5, color:'var(--muted)', marginTop:-1}}>{x.l}</div>
              </div>
            ))}
          </div>
        </Card>

        {/* Members */}
        <div style={{display:'flex', alignItems:'center', gap:10, marginBottom:14, padding:'0 2px'}}>
          <div style={{display:'flex'}}>
            {g.members.slice(0,5).map((mid, i)=>(
              <div key={mid} style={{marginLeft: i===0?0:-10}}>
                <Ava person={s.people[mid]} size={26} ring={mid===g.holderId}/>
              </div>
            ))}
          </div>
          <div style={{fontSize:13, color:'var(--muted)'}}>{g.members.length} members</div>
          <div style={{flex:1}}/>
          <button className="tap" onClick={()=>onOpenHead && holder && onOpenHead(holder.id)} style={{
            border:'none', background:'transparent', color:'var(--crown-2)', fontSize:13, fontWeight:600,
            display:'inline-flex', alignItems:'center', gap:2,
          }}>Stats <Icon name="chev" size={14} color="var(--crown-2)"/></button>
        </div>

        {/* Leaderboard */}
        <div style={{fontSize:12, fontWeight:600, color:'var(--muted)', letterSpacing:'.08em', padding:'0 4px 8px'}}>LEADERBOARD</div>
        <Card style={{padding:0, overflow:'hidden', marginBottom:18}}>
          {lb.map((row, i)=>(
            <div key={row.id} className="tap" onClick={()=>onOpenHead && onOpenHead(row.id)} style={{
              padding:'10px 14px', display:'flex', alignItems:'center', gap:12,
              borderBottom: i<lb.length-1?'0.5px solid var(--hair)':'none',
            }}>
              <div style={{width:18, fontSize:13, color:'var(--muted)', fontWeight:600, textAlign:'right'}}>{i+1}</div>
              <Ava person={row.person} size={36}/>
              <div style={{flex:1, minWidth:0}}>
                <div style={{fontSize:14.5, fontWeight:600, letterSpacing:'-.01em'}}>
                  {row.id===viewerId?'You':row.person.name}
                </div>
                <div style={{fontSize:12, color:'var(--muted)'}}>
                  {row.id===g.holderId ? `Holding · ${fmtHeld(g.heldSince)}` : `${row.claims} claim${row.claims===1?'':'s'}`}
                </div>
              </div>
              <div style={{display:'flex', alignItems:'center', gap:5}}>
                <div style={{fontSize:14, fontWeight:600}}>{row.claims}</div>
                <Crown size={13} color={row.id===g.holderId?'var(--crown)':'var(--muted)'}/>
              </div>
            </div>
          ))}
        </Card>

        {/* Timeline (pending + confirmed) */}
        <div style={{fontSize:12, fontWeight:600, color:'var(--muted)', letterSpacing:'.08em', padding:'0 4px 8px'}}>TIMELINE</div>
        <div style={{display:'flex', flexDirection:'column', gap:10}}>
          {timeline.map(sp=>(
            sp._kind==='pending'
              ? <PendingSpotCard key={sp.id} spot={sp} group={g} viewerId={viewerId}/>
              : <ConfirmedSpotCard key={sp.id} spot={sp} group={g} viewerId={viewerId} onOpenPhoto={onOpenPhoto}/>
          ))}
        </div>
        <div style={{height:16}}/>
      </ScrollBody>
    </>
  );
}

function PendingSpotCard({ spot, group, viewerId }){
  const s = useStore();
  const by = s.people[spot.byId];
  const item = s.itemById[group.itemId];
  const score = Object.values(spot.votes||{}).reduce((a,b)=>a+b, 0);
  const myVote = spot.votes[viewerId] || 0;
  const isMine = spot.byId===viewerId;

  function vote(v){
    if (isMine) return; // can't vote on your own
    SC.actions.voteOnPending(group.id, spot.id, viewerId, myVote===v ? 0 : v);
  }
  function postComment(text){
    SC.actions.addComment(group.id, spot.id, viewerId, text);
  }

  const needed = group.policy.minApprovals;
  const pct = Math.max(0, Math.min(100, (score/needed)*100));

  return (
    <Card style={{padding:0, overflow:'hidden',
      boxShadow:'0 0 0 1.5px rgba(214,158,61,0.3), 0 1px 2px rgba(0,0,0,0.04)',
    }}>
      <div style={{padding:'10px 14px', display:'flex', alignItems:'center', gap:10}}>
        <Ava person={by} size={32}/>
        <div style={{flex:1, minWidth:0}}>
          <div style={{fontSize:14, letterSpacing:'-.01em'}}>
            <b>{isMine?'You':by.first}</b> claim<span style={{color:'var(--muted)'}}>{isMine?'':'s'} a fresh {item.name.toLowerCase()}</span>
          </div>
          <div style={{fontSize:12, color:'var(--muted)'}}>
            {fmtDaysAgo(spot.at)} · pending
          </div>
        </div>
        <Chip tone="crown" style={{fontSize:11}}>
          <Icon name="bell" size={10} color="var(--crown-2)"/> Pending
        </Chip>
      </div>

      <PhotoBG emoji={item.emoji} seed={spot.photoSeed}
        style={{margin:'0 14px', height:140, borderRadius:12, fontSize:54}}/>

      {/* Score bar */}
      <div style={{padding:'12px 14px 8px'}}>
        <div style={{display:'flex', justifyContent:'space-between', alignItems:'center', marginBottom:6}}>
          <div style={{fontSize:12.5, fontWeight:600, color:'var(--ink-2)'}}>
            {score>=needed ? 'Confirmed!' : `Score ${score} / ${needed}`}
          </div>
          <div style={{fontSize:11, color:'var(--muted)'}}>auto-confirms in 24h</div>
        </div>
        <div style={{height:6, borderRadius:3, background:'var(--chip)', overflow:'hidden'}}>
          <div style={{
            height:'100%', width:pct+'%',
            background: score<0 ? 'var(--danger)' : 'var(--crown)',
            transition:'width 300ms ease',
          }}/>
        </div>
      </div>

      {/* Vote buttons */}
      {!isMine && (
        <div style={{padding:'4px 14px 12px', display:'flex', gap:8}}>
          <button onClick={()=>vote(-1)} className="tap" style={{
            flex:1, padding:'10px', border:'none', borderRadius:11,
            background: myVote===-1 ? 'var(--danger)' : '#fff',
            color: myVote===-1 ? '#fff' : 'var(--danger)',
            boxShadow: myVote===-1 ? 'none' : '0 0 0 1px var(--hair)',
            fontWeight:600, fontSize:13.5, display:'flex', alignItems:'center', justifyContent:'center', gap:6,
          }}>
            <Icon name="x" size={14} color={myVote===-1?'#fff':'var(--danger)'} stroke={2.4}/>
            Doubt
          </button>
          <button onClick={()=>vote(1)} className="tap" style={{
            flex:1, padding:'10px', border:'none', borderRadius:11,
            background: myVote===1 ? 'var(--ok)' : '#fff',
            color: myVote===1 ? '#fff' : 'var(--ok)',
            boxShadow: myVote===1 ? 'none' : '0 0 0 1px var(--hair)',
            fontWeight:600, fontSize:13.5, display:'flex', alignItems:'center', justifyContent:'center', gap:6,
          }}>
            <Icon name="check" size={14} color={myVote===1?'#fff':'var(--ok)'} stroke={2.4}/>
            Confirm
          </button>
        </div>
      )}

      <CommentThread comments={spot.comments} onPost={postComment} viewerId={viewerId}/>
    </Card>
  );
}

function ConfirmedSpotCard({ spot, group, viewerId, onOpenPhoto }){
  const s = useStore();
  const by = s.people[spot.byId];
  const from = spot.takenFrom ? s.people[spot.takenFrom] : null;
  const item = s.itemById[group.itemId];
  const isMine = spot.byId===viewerId;
  const youLost = from && from.id===viewerId;

  function postComment(text){
    SC.actions.addComment(group.id, spot.id, viewerId, text);
  }

  return (
    <Card style={{padding:0, overflow:'hidden',
      boxShadow: youLost ? '0 0 0 1.5px rgba(201,74,58,0.25), 0 1px 2px rgba(0,0,0,0.04)' : undefined,
    }}>
      <div style={{padding:'10px 14px', display:'flex', alignItems:'center', gap:10}}>
        <Ava person={by} size={32}/>
        <div style={{flex:1, minWidth:0, fontSize:14, letterSpacing:'-.01em'}}>
          <span style={{fontWeight:600}}>{isMine?'You':by.first}</span>
          <span style={{color:'var(--muted)'}}> {youLost ? 'took your crown' : 'claimed the crown'}</span>
        </div>
        {from && <Ava person={from} size={22}/>}
        <div style={{fontSize:11.5, color:'var(--muted)'}}>{fmtDaysAgo(spot.at)}</div>
      </div>

      <div onClick={()=>onOpenPhoto && onOpenPhoto(spot, group)} className="tap">
        <PhotoBG emoji={item.emoji} seed={spot.photoSeed}
          style={{margin:'0 14px', height:140, borderRadius:12, fontSize:54}}/>
      </div>

      <CommentThread comments={spot.comments} onPost={postComment} viewerId={viewerId}/>
    </Card>
  );
}

function CommentThread({ comments=[], onPost, viewerId }){
  const s = useStore();
  const [draft, setDraft] = React.useState('');
  function send(){
    if (!draft.trim()) return;
    onPost(draft);
    setDraft('');
  }
  return (
    <div style={{borderTop: comments.length>0?'0.5px solid var(--hair)':'none'}}>
      {comments.length>0 && (
        <div style={{padding:'8px 14px 4px', display:'flex', flexDirection:'column', gap:8}}>
          {comments.map(c=>{
            const p = s.people[c.byId];
            return (
              <div key={c.id} style={{display:'flex', gap:8, alignItems:'flex-start'}}>
                <Ava person={p} size={22}/>
                <div style={{flex:1, fontSize:13, lineHeight:1.4}}>
                  <span style={{fontWeight:600}}>{c.byId===viewerId?'You':p.first}</span>
                  <span style={{color:'var(--ink-2)'}}> {c.text}</span>
                  <span style={{color:'var(--muted)', fontSize:11, marginLeft:6}}>{fmtDaysAgo(c.at)}</span>
                </div>
              </div>
            );
          })}
        </div>
      )}
      <div style={{padding:'8px 10px', display:'flex', gap:6, alignItems:'center',
        borderTop: comments.length>0 ? '0.5px solid var(--hair)' : 'none'}}>
        <input
          value={draft}
          onChange={e=>setDraft(e.target.value)}
          onKeyDown={e=>e.key==='Enter' && send()}
          placeholder="Add a comment…"
          style={{
            flex:1, border:'none', outline:'none', background:'var(--bg)',
            borderRadius:18, padding:'8px 14px', fontSize:13.5, fontFamily:'inherit',
          }}/>
        {draft.trim() && (
          <button onClick={send} className="tap" style={{
            border:'none', background:'var(--crown)', width:32, height:32, borderRadius:16,
            display:'flex', alignItems:'center', justifyContent:'center',
          }}>
            <Icon name="arrow-r" size={14} color="#fff" stroke={2.4}/>
          </button>
        )}
      </div>
    </div>
  );
}

// ─── Activity Feed (cross-mode) ─────────────────────────────────────────
function ActivityScreen({ viewerId, onOpenGroup, onOpenItem, onOpenHead }){
  const s = useStore();
  const myGroupIds = new Set(s.groups.filter(g=>g.members.includes(viewerId)).map(g=>g.id));

  const feed = s.activity.filter(a=>{
    if (a.mode==='chat') return myGroupIds.has(a.groupId);
    if (a.mode==='inperson') return a.pairKey.split('::').includes(viewerId);
    return false;
  });

  // group by day label
  const sections = {};
  feed.forEach(a=>{
    const today = new Date(); today.setHours(0,0,0,0);
    const y = new Date(); y.setDate(y.getDate()-1); y.setHours(0,0,0,0);
    const label = a.at>=today.getTime() ? 'TODAY' : a.at>=y.getTime() ? 'YESTERDAY' : 'EARLIER';
    (sections[label] = sections[label] || []).push(a);
  });

  return (
    <>
      <NavBar title="Activity"/>
      <ScrollBody>
        {feed.length===0 && (
          <Card style={{padding:30, textAlign:'center'}}>
            <div style={{fontSize:14, fontWeight:600}}>Nothing here yet</div>
            <div style={{fontSize:12.5, color:'var(--muted)', marginTop:4}}>
              Spots from your groups and friends will show up.
            </div>
          </Card>
        )}
        {Object.entries(sections).map(([label, rows])=>(
          <div key={label} style={{marginBottom:16}}>
            <div style={{fontSize:12, fontWeight:600, color:'var(--muted)', letterSpacing:'.08em', padding:'0 4px 8px'}}>{label}</div>
            <div style={{display:'flex', flexDirection:'column', gap:10}}>
              {rows.map(a=> a.mode==='chat'
                ? <ChatActivityCard key={a.id} a={a} viewerId={viewerId} onOpenGroup={onOpenGroup}/>
                : <InpersonActivityCard key={a.id} a={a} viewerId={viewerId} onOpenItem={onOpenItem} onOpenHead={onOpenHead}/>
              )}
            </div>
          </div>
        ))}
        <div style={{height:20}}/>
      </ScrollBody>
    </>
  );
}

function ChatActivityCard({ a, viewerId, onOpenGroup }){
  const s = useStore();
  const g = s.groups.find(x=>x.id===a.groupId);
  if (!g) return null;
  const by = s.people[a.byId];
  const from = a.takenFrom ? s.people[a.takenFrom] : null;
  const item = s.itemById[a.itemId];
  const youDid = a.byId===viewerId;
  const youLost = from && from.id===viewerId;

  if (a.kind==='pending'){
    // find the live pending so vote progress is fresh
    const p = g.pendingSpots.find(x=>x.id===a.id.split('-').slice(1).join('-')) || null;
    const score = p ? Object.values(p.votes).reduce((s,v)=>s+v,0) : a.score;
    return (
      <Card>
        <div style={{display:'flex', alignItems:'center', gap:10, marginBottom:8}}>
          <Ava person={by} size={32}/>
          <div style={{flex:1, minWidth:0, fontSize:14, letterSpacing:'-.01em'}}>
            <span style={{fontWeight:600}}>{youDid?'You':by.first}</span>
            <span style={{color:'var(--muted)'}}> claim{youDid?'':'s'} a {item.name.toLowerCase()} in </span>
            <span style={{fontWeight:600}}>{a.groupName}</span>
          </div>
          <Chip tone="crown" style={{fontSize:11}}>{score}/{a.needed}</Chip>
        </div>
        <Btn kind="secondary" onClick={()=>onOpenGroup(a.groupId)}>Open to vote</Btn>
      </Card>
    );
  }

  return (
    <Card onClick={()=>onOpenGroup(a.groupId)} style={{
      padding:0, overflow:'hidden',
      boxShadow: youLost ? '0 0 0 1.5px rgba(201,74,58,0.25), 0 1px 2px rgba(0,0,0,0.04)' : undefined,
    }}>
      <div style={{padding:'10px 14px 8px', display:'flex', alignItems:'center', gap:10}}>
        <Ava person={by} size={32}/>
        <div style={{flex:1, minWidth:0, fontSize:14, letterSpacing:'-.01em'}}>
          <span style={{fontWeight:600}}>{youDid?'You':by.first}</span>
          <span style={{color:'var(--muted)'}}> {youLost ? 'took your crown' : 'claimed the crown'} in </span>
          <span style={{fontWeight:600}}>{a.groupName}</span>
        </div>
        {from && <Ava person={from} size={22}/>}
      </div>
      <div style={{display:'flex', gap:0, padding:'0 14px 12px', alignItems:'center'}}>
        <PhotoBG emoji={item.emoji} seed={a.photoSeed}
          style={{width:50, height:50, borderRadius:10, flexShrink:0, fontSize:22}}/>
        <div style={{flex:1, padding:'0 12px', display:'flex', alignItems:'center', gap:8}}>
          <Crown size={14} color={youLost?'var(--danger)':'var(--crown)'}/>
          <div style={{fontSize:12.5, fontWeight:600, color:youLost?'var(--danger)':'var(--ink-2)'}}>
            {youLost ? 'Crown lost' : 'Crown transferred'}
          </div>
        </div>
        <div style={{fontSize:11.5, color:'var(--muted)'}}>{fmtDaysAgo(a.at)}</div>
      </div>
    </Card>
  );
}

function InpersonActivityCard({ a, viewerId, onOpenItem, onOpenHead }){
  const s = useStore();
  const by = s.people[a.byId];
  const op = s.people[a.withId];
  const item = s.itemById[a.itemId];
  const youDid = a.byId===viewerId;
  const youLost = a.takenFrom===viewerId;

  return (
    <Card style={{padding:0, overflow:'hidden',
      boxShadow: youLost ? '0 0 0 1.5px rgba(201,74,58,0.25), 0 1px 2px rgba(0,0,0,0.04)' : undefined,
    }}>
      <div style={{padding:'10px 14px 8px', display:'flex', alignItems:'center', gap:10}}>
        <div style={{position:'relative'}}>
          <Ava person={by} size={32}/>
          <div style={{position:'absolute', bottom:-3, right:-3, width:16, height:16, borderRadius:'50%',
            background:'var(--rival)', display:'flex', alignItems:'center', justifyContent:'center',
            boxShadow:'0 0 0 1.5px #fff'}}>
            <Icon name="qr" size={9} color="#fff" stroke={2.6}/>
          </div>
        </div>
        <div style={{flex:1, minWidth:0, fontSize:14, letterSpacing:'-.01em'}}>
          <span style={{fontWeight:600}}>{youDid?'You':by.first}</span>
          <span style={{color:'var(--muted)'}}> spotted a {item.name.toLowerCase()} </span>
          <span style={{color:'var(--muted)'}}>with </span>
          <span style={{fontWeight:600}}>{youDid?op.first:'you'}</span>
        </div>
        <Chip style={{fontSize:11}}>In person</Chip>
      </div>
      <div style={{display:'flex', gap:0, padding:'0 14px 12px', alignItems:'center'}}>
        <ItemTile item={item} size={48} rounded={11}/>
        <div style={{flex:1, padding:'0 12px'}}>
          {a.comment ? (
            <div style={{fontSize:13, color:'var(--ink-2)', fontStyle:'italic',
              overflow:'hidden', textOverflow:'ellipsis', whiteSpace:'nowrap'}}>
              "{a.comment}"
            </div>
          ) : (
            <div style={{fontSize:12.5, color:'var(--muted)'}}>
              {youLost ? `${by.first} took the crown from you` : 'Crown claimed in person'}
            </div>
          )}
          <div style={{fontSize:11.5, color:'var(--muted)', marginTop:2}}>{fmtDaysAgo(a.at)}{a.photo?' · 📷':''}</div>
        </div>
        <div onClick={()=>onOpenHead(a.withId)} className="tap" style={{padding:4}}>
          <Icon name="chev" size={16} color="var(--muted)"/>
        </div>
      </div>
    </Card>
  );
}

// ─── Profile / You ─────────────────────────────────────────────────────
function ProfileScreen({ viewerId, onSettings, onOpenGroup, onOpenItem }){
  const s = useStore();
  const me = s.people[viewerId];
  const myGroups = s.groups.filter(g=>g.members.includes(viewerId));
  const heldChat = myGroups.filter(g=>g.holderId===viewerId);
  const ipForMe = inpersonForUser(s, viewerId);
  const heldIp = ipForMe.filter(r=>r.holderId===viewerId);
  const lifetimeChat = s.groups.reduce((acc,g)=>acc+g.spots.filter(sp=>sp.byId===viewerId).length, 0);
  const lifetimeIp = ipForMe.reduce((acc,r)=>acc+r.transfers.filter(t=>t.byId===viewerId).length, 0);
  const longest = heldChat.slice().sort((a,b)=>a.heldSince-b.heldSince)[0];

  return (
    <>
      <NavBar title="You" right={
        <button onClick={onSettings} className="tap" style={{
          border:'none', background:'transparent', padding:6,
        }}><Icon name="gear" size={20} color="var(--ink-2)"/></button>
      }/>
      <ScrollBody>
        <Card style={{textAlign:'center', padding:'20px 16px 18px', marginBottom:16}}>
          <Ava person={me} size={88} ring/>
          <div style={{fontSize:22, fontWeight:600, letterSpacing:'-.02em', marginTop:10}}>{me.name}</div>
          <div style={{fontSize:13, color:'var(--muted)'}}>@{me.id}</div>
        </Card>

        <div style={{display:'grid', gridTemplateColumns:'1fr 1fr', gap:10, marginBottom:14}}>
          <Card style={{padding:14}}>
            <div style={{fontSize:11, fontWeight:600, color:'var(--muted)', letterSpacing:'.08em'}}>GROUP CROWNS</div>
            <div style={{display:'flex', alignItems:'baseline', gap:6, marginTop:4}}>
              <div style={{fontSize:26, fontWeight:600, letterSpacing:'-.02em'}}>{heldChat.length}</div>
              <div style={{fontSize:12, color:'var(--muted)'}}>of {myGroups.length}</div>
            </div>
            <div style={{fontSize:12, color:'var(--muted)', marginTop:2}}>{lifetimeChat} lifetime spots</div>
          </Card>
          <Card style={{padding:14}}>
            <div style={{fontSize:11, fontWeight:600, color:'var(--muted)', letterSpacing:'.08em'}}>IN-PERSON</div>
            <div style={{display:'flex', alignItems:'baseline', gap:6, marginTop:4}}>
              <div style={{fontSize:26, fontWeight:600, letterSpacing:'-.02em'}}>{heldIp.length}</div>
              <div style={{fontSize:12, color:'var(--muted)'}}>of {ipForMe.length}</div>
            </div>
            <div style={{fontSize:12, color:'var(--muted)', marginTop:2}}>{lifetimeIp} lifetime spots</div>
          </Card>
        </div>

        {longest && (
          <>
            <div style={{fontSize:12, fontWeight:600, color:'var(--muted)', letterSpacing:'.08em', padding:'0 4px 8px'}}>LONGEST CURRENT REIGN</div>
            <Card style={{marginBottom:14, display:'flex', alignItems:'center', gap:14}} onClick={()=>onOpenGroup(longest.id)}>
              <ItemTile item={s.itemById[longest.itemId]} size={50} rounded={13}/>
              <div style={{flex:1}}>
                <div style={{fontSize:15.5, fontWeight:600, letterSpacing:'-.01em'}}>{longest.name}</div>
                <div style={{fontSize:13, color:'var(--muted)'}}>Holding for <b style={{color:'var(--ink)', fontWeight:600}}>{fmtHeld(longest.heldSince)}</b></div>
              </div>
              <Icon name="chev" size={18} color="var(--muted)"/>
            </Card>
          </>
        )}

        <div style={{fontSize:12, fontWeight:600, color:'var(--muted)', letterSpacing:'.08em', padding:'0 4px 8px'}}>YOUR GROUPS</div>
        <Card style={{padding:0, overflow:'hidden', marginBottom:18}}>
          {myGroups.map((g, i)=>(
            <div key={g.id} onClick={()=>onOpenGroup(g.id)} className="tap" style={{
              padding:'10px 14px', display:'flex', alignItems:'center', gap:12,
              borderBottom: i<myGroups.length-1?'0.5px solid var(--hair)':'none',
            }}>
              <ItemTile item={s.itemById[g.itemId]} size={34} rounded={10}/>
              <div style={{flex:1, minWidth:0}}>
                <div style={{fontSize:14.5, fontWeight:600, letterSpacing:'-.01em'}}>{g.name}</div>
                <div style={{fontSize:12, color:'var(--muted)'}}>
                  {g.holderId===viewerId?'You hold the crown':g.holderId?`${s.people[g.holderId].first} holds`:'Vacant'}
                </div>
              </div>
              <Icon name="chev" size={16} color="var(--muted)"/>
            </div>
          ))}
        </Card>
        <div style={{height:16}}/>
      </ScrollBody>
    </>
  );
}

Object.assign(window, {
  GroupDetailScreen, ActivityScreen, ProfileScreen,
  PendingSpotCard, ConfirmedSpotCard, CommentThread,
});
