While you're in a call and Lotus isn't the focused window, a small always-on-top, click-through window lists everyone in the call, lights up whoever is speaking, and shows your own mute / deafen / PTT state. - A separate window, nothing injected into the game: no anti-cheat surface. Never takes focus (focusable(false), WS_EX_NOACTIVATE, SW_SHOWNOACTIVATE) and ignores the mouse. - Its page is three static files served by the binary over the `lotusoverlay` custom protocol, with a strict CSP (no network) and no IPC (no capability names the window). Rust pushes state in as a JSON literal; the page renders with textContent only. - New `set_overlay_state` command (main window only) takes the call snapshot from cinny's `useTauriOverlay`. Sanitised: bounded list and names, known corner. Placed in the chosen corner of the foreground window's monitor, DPI-scaled. - Windows only; a no-op elsewhere (Linux has no in-app calls yet, #21). Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01PPmy3tPq869XDW4njjVaKA
118 lines
1.9 KiB
CSS
118 lines
1.9 KiB
CSS
/* Lotus Chat in-game voice overlay (cinny-desktop #25).
|
|
Sizes match native/overlay.rs: width 240, padding 8, header 30, rows 30. */
|
|
|
|
html,
|
|
body {
|
|
margin: 0;
|
|
padding: 0;
|
|
background: transparent;
|
|
overflow: hidden;
|
|
user-select: none;
|
|
cursor: default;
|
|
font: 13px/1.2 "Segoe UI", system-ui, sans-serif;
|
|
color: #f2f2f2;
|
|
}
|
|
|
|
.panel {
|
|
box-sizing: border-box;
|
|
width: 240px;
|
|
padding: 8px;
|
|
}
|
|
|
|
.panel[hidden] {
|
|
display: none;
|
|
}
|
|
|
|
.self {
|
|
display: flex;
|
|
align-items: center;
|
|
gap: 6px;
|
|
height: 30px;
|
|
padding: 0 8px;
|
|
box-sizing: border-box;
|
|
border-radius: 15px;
|
|
background: rgba(18, 18, 24, 0.78);
|
|
font-weight: 600;
|
|
white-space: nowrap;
|
|
}
|
|
|
|
.badge {
|
|
padding: 1px 7px;
|
|
border-radius: 9px;
|
|
font-size: 11px;
|
|
background: rgba(255, 255, 255, 0.14);
|
|
}
|
|
|
|
.badge.off {
|
|
background: rgba(220, 60, 60, 0.85);
|
|
}
|
|
|
|
.people {
|
|
list-style: none;
|
|
margin: 0;
|
|
padding: 0;
|
|
}
|
|
|
|
.person {
|
|
display: flex;
|
|
align-items: center;
|
|
gap: 8px;
|
|
height: 30px;
|
|
padding: 3px 8px 3px 3px;
|
|
box-sizing: border-box;
|
|
}
|
|
|
|
.avatar {
|
|
flex: none;
|
|
display: flex;
|
|
align-items: center;
|
|
justify-content: center;
|
|
width: 24px;
|
|
height: 24px;
|
|
border-radius: 50%;
|
|
font-size: 11px;
|
|
font-weight: 700;
|
|
color: #fff;
|
|
box-shadow: 0 0 0 2px rgba(0, 0, 0, 0.45);
|
|
}
|
|
|
|
.person.speaking .avatar {
|
|
box-shadow: 0 0 0 2px #3ddc84;
|
|
}
|
|
|
|
.name {
|
|
flex: 1;
|
|
overflow: hidden;
|
|
text-overflow: ellipsis;
|
|
white-space: nowrap;
|
|
padding: 2px 8px;
|
|
border-radius: 10px;
|
|
background: rgba(18, 18, 24, 0.7);
|
|
text-shadow: 0 1px 2px rgba(0, 0, 0, 0.8);
|
|
}
|
|
|
|
.person.speaking .name {
|
|
color: #fff;
|
|
background: rgba(18, 18, 24, 0.85);
|
|
}
|
|
|
|
.person.muted .name {
|
|
color: rgba(242, 242, 242, 0.6);
|
|
}
|
|
|
|
.mic {
|
|
flex: none;
|
|
font-size: 11px;
|
|
padding: 1px 6px;
|
|
border-radius: 8px;
|
|
background: rgba(220, 60, 60, 0.85);
|
|
}
|
|
|
|
.more {
|
|
height: 30px;
|
|
line-height: 30px;
|
|
padding-left: 35px;
|
|
color: rgba(242, 242, 242, 0.75);
|
|
text-shadow: 0 1px 2px rgba(0, 0, 0, 0.8);
|
|
}
|