Files
cinny-desktop/src-tauri/overlay/overlay.css
T
jaredandClaude Opus 5.5 1674fd273f feat(overlay): in-game voice overlay window, Windows (#25)
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
2026-11-09 17:24:01 -05:00

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);
}