diff --git a/server/public/home.html b/server/public/home.html
index 51d7f3e..d7f36ed 100644
--- a/server/public/home.html
+++ b/server/public/home.html
@@ -424,6 +424,7 @@
.meet-bar .meet-ic{width:46px;height:46px;padding:0;border-radius:50%;background:#e8edf5;color:var(--blue);display:inline-flex;align-items:center;justify-content:center;}
.meet-bar .meet-ic:hover{background:#dbe4f0;}
.meet-bar .meet-ic.off{background:#fee2e2;color:var(--red);}
+ .meet-bar .meet-ic.on{background:var(--blue);color:#fff;} /* #9: screen-share highlighted while active (record keeps its red pulse via #meetRecBtn.on) */
.meet-bar .meet-ic.leave,.meet-bar .meet-ic.leave.off{background:#dc2626;color:#fff;}
.meet-bar .meet-ic.leave:hover{background:#b91c1c;}
/* Meetings dashboard (full-width, scrollable) */
@@ -826,7 +827,7 @@
-
@@ -1456,6 +1457,8 @@ function convoShellHTML(it){
function senderAvatar(id, name){ const mem=convoMembers.find(x=>x.id===id); const av=mem&&mem.avatar; return ''+(av?'
':'')+pEsc(initials(name||'?'))+''; }
function bubbleHTML(m){
if(m.evt==='call-start') return '📞 '+(m.from===ME.id?'You':pEsc(m.byName||'Someone'))+' started a call
';
+ // Unanswered 1:1: the caller (message sender) sees "Call not answered"; the callee sees "Missed call".
+ if(m.evt==='call-end' && /Missed call|not answered/i.test(m.body||'')) return '📞 '+(m.from===ME.id?'Call not answered':'Missed call')+'
';
if(m.system||m.from==='__system__') return ''+pEsc(m.body)+'
';
const mine=m.from===ME.id;
if(m.deleted) return ''+ic('trash',12)+' This message was deleted'+pEsc(fmtClock(m.created_at))+'
';
@@ -3000,7 +3003,7 @@ function addTile(id, stream, label, muted){
tile.innerHTML=''+pEsc(initials(label||'?'))+(av?'
+')
':'')+'
'+ic('micOff',14)+'
'+pEsc(label||'')+''; grid.appendChild(tile); }
const v=tile.querySelector('video'); if(v && stream && v.srcObject!==stream) v.srcObject=stream;
const hasVid=!!(stream && stream.getVideoTracks && stream.getVideoTracks().some(t=>t.enabled && t.readyState!=='ended'));
- tile.classList.toggle('novid', !hasVid || meetCamOff.get(id)===true); // camOff peer → avatar even if a (disabled) track arrives
+ tile.classList.toggle('novid', !hasVid || (meetCamOff.get(id)===true && !meetSharers.has(id))); // camOff → avatar, UNLESS they're sharing a screen (#9: screen must show even with camera off)
if(meetMuted.has(id)) setTileMute(id, meetMuted.get(id)); // apply any known mute state
}
function setTileMute(id, muted){ meetMuted.set(id, !!muted); const t=document.getElementById('meet-tile-'+id); if(t){ const b=t.querySelector('.meet-mute'); if(b) b.style.display=muted?'grid':'none'; if(muted) t.classList.remove('speaking'); } }
@@ -3226,7 +3229,7 @@ async function onMeetMsg(e){
if(meetScreen) meetSend({type:'meeting-screen', on:true});
refreshMeetPanel(); return;
}
- if(m.type==='meeting-peer-state'){ setTileMute(m.peerId, !!m.muted); meetCamOff.set(m.peerId, !!m.camOff); const _t=document.getElementById('meet-tile-'+m.peerId); if(_t){ const v=_t.querySelector('video'), s=v&&v.srcObject; const hv=!!(s&&s.getVideoTracks&&s.getVideoTracks().some(tr=>tr.enabled&&tr.readyState!=='ended')); _t.classList.toggle('novid', !hv || !!m.camOff); } refreshMeetPanel(); return; } // camOff -> show avatar, not a black tile
+ if(m.type==='meeting-peer-state'){ setTileMute(m.peerId, !!m.muted); meetCamOff.set(m.peerId, !!m.camOff); const _t=document.getElementById('meet-tile-'+m.peerId); if(_t){ const v=_t.querySelector('video'), s=v&&v.srcObject; const hv=!!(s&&s.getVideoTracks&&s.getVideoTracks().some(tr=>tr.enabled&&tr.readyState!=='ended')); _t.classList.toggle('novid', !hv || (!!m.camOff && !meetSharers.has(m.peerId))); } refreshMeetPanel(); return; } // camOff -> avatar, unless sharing a screen (#9)
if(m.type==='meeting-host'){ const was=meetIsHost; meetHostId=m.hostPeerId; meetIsHost=(m.hostPeerId===meetMyId); if(meetIsHost&&!was){ toast('You are now the host'); try{ speak('You are now the host'); }catch(_){} } refreshMeetPanel(); updateHostControls(); return; }
if(m.type==='meeting-transcribe-state'){ applyRoomTx(!!m.active); return; } // ≥1 subscriber → transcribe my mic
if(m.type==='meeting-recording'){ recNotice(!!m.on, m.by); return; } // someone is recording — show + announce