.lkParticipantTile {
	position: relative;
	display: flex;
	flex-direction: column;
	width: 100%;
	height: 100%;
	aspect-ratio: 16 / 9;
	border-radius: var(--radius-lg, 12px);
	background-color: var(--voice-surface-2);
	overflow: hidden;
}

.video {
	width: 100%;
	height: 100%;
	object-fit: cover;
	border-radius: var(--radius-lg, 12px);
	display: block;
}

.lkParticipantTile[data-source='screen_share'] {
	background-color: var(--voice-surface-0);
}

.lkParticipantTile[data-source='screen_share'] .video {
	object-fit: contain;
}

/* Avatar placeholder when no video */
.lkParticipantPlaceholder {
	position: absolute;
	inset: 0;
	display: flex;
	align-items: center;
	justify-content: center;
	background-color: var(--voice-surface-3);
}

/* Speaking indicator — green border */
.lkParticipantTile::after {
	content: '';
	position: absolute;
	inset: 0;
	border-radius: var(--radius-lg, 12px);
	border: 0px solid var(--voice-status-success);
	transition:
		border-width 0.4s,
		border-color 0.4s;
	transition-delay: 0.5s;
	pointer-events: none;
	box-sizing: border-box;
}

.lkParticipantTile[data-speaking='true']::after {
	border-width: 3.5px;
	transition-delay: 0s;
	transition-duration: 0.2s;
}

/* Bottom metadata strip — name + mute icons */
.lkParticipantMetadata {
	position: absolute;
	right: 0.5rem;
	bottom: 0.5rem;
	left: 0.5rem;
	display: flex;
	flex-direction: row;
	align-items: center;
	justify-content: space-between;
	gap: 0.5rem;
	z-index: 10;
	pointer-events: none;
}

.lkParticipantMetadataItem {
	display: inline-flex;
	align-items: center;
	gap: 4px;
	padding: 0.375rem 0.5rem;
	background-color: color-mix(in srgb, var(--voice-surface-1) 80%, transparent);
	border-radius: var(--radius-md, 8px);
	color: var(--voice-text-strong);
	font-size: 0.875rem;
	font-weight: 500;
	max-width: 100%;
	min-width: 0;
}

.name {
	white-space: nowrap;
	overflow: hidden;
	text-overflow: ellipsis;
	max-width: 240px;
}

.mutedIcon {
	color: var(--voice-status-danger);
}

/* Dim matrix-only participants (users known via MatrixRTC state events but
   not yet visible on our LiveKit room — usually Element/Commet users who
   have announced membership but haven't finished connecting their media). */
.lkParticipantTile[data-connection-source='matrix'] .lkParticipantPlaceholder {
	opacity: 0.55;
}

.joiningLabel {
	font-size: 0.75rem;
	font-weight: 500;
	font-style: italic;
	color: var(--voice-text-muted, var(--voice-text-strong));
	opacity: 0.75;
}

/* ── Stream opt-in placeholder ─────────────────────────────────
   Rendered when a remote peer has published a camera or screen
   track but the local user hasn't clicked Watch yet. Avatar fills
   the tile just like the normal placeholder, with a LIVE pill
   in the top-left and a brand-primary Watch button centered in
   the bottom third. */
.streamPlaceholder {
	position: absolute;
	inset: 0;
	display: flex;
	flex-direction: column;
	align-items: center;
	justify-content: center;
	gap: 16px;
	background-color: var(--voice-surface-3);
}

.liveIndicator {
	position: absolute;
	top: 10px;
	left: 10px;
	display: inline-flex;
	align-items: center;
	gap: 6px;
	padding: 4px 8px;
	background-color: rgba(0, 0, 0, 0.65);
	border-radius: 999px;
	color: #fff;
	font-size: 0.6875rem;
	font-weight: 800;
	letter-spacing: 0.08em;
	text-transform: uppercase;
}

.liveDot {
	width: 8px;
	height: 8px;
	border-radius: 50%;
	background-color: hsl(0, calc(80% * var(--saturation-factor, 1)), 60%);
	box-shadow: 0 0 6px hsl(0, calc(80% * var(--saturation-factor, 1)), 60%);
	animation: voiceLiveDotPulse 1.6s ease-in-out infinite;
}

@keyframes voiceLiveDotPulse {
	0%,
	100% {
		opacity: 1;
	}
	50% {
		opacity: 0.5;
	}
}

.watchStreamButton {
	display: inline-flex;
	align-items: center;
	gap: 8px;
	height: 40px;
	padding: 0 18px;
	background-color: var(--brand-primary);
	border: none;
	border-radius: 999px;
	color: var(--text-on-brand-primary, #fff);
	font: inherit;
	font-size: 0.875rem;
	font-weight: 700;
	cursor: pointer;
	box-shadow: 0 2px 12px rgba(0, 0, 0, 0.35);
	transition: filter 0.12s, transform 0.12s;
	-webkit-tap-highlight-color: transparent;
}

.watchStreamButton:hover {
	filter: brightness(1.08);
}

.watchStreamButton:active {
	filter: brightness(0.92);
	transform: scale(0.98);
}

/* ── Unwatch affordance ────────────────────────────────────────
   Small X pinned to the top-right of an actively subscribed
   remote tile. Hidden by default, fades in on hover / focus so
   it doesn't clutter the tile during normal viewing but is one
   click away when the user wants to drop bandwidth. */
.unwatchButton {
	position: absolute;
	top: 10px;
	right: 10px;
	display: inline-flex;
	align-items: center;
	justify-content: center;
	width: 26px;
	height: 26px;
	padding: 0;
	background-color: rgba(0, 0, 0, 0.65);
	border: none;
	border-radius: 50%;
	color: #fff;
	cursor: pointer;
	opacity: 0;
	visibility: hidden;
	transition: opacity 0.12s ease, visibility 0.12s ease, background-color 0.12s;
	z-index: 20;
	-webkit-tap-highlight-color: transparent;
}

.lkParticipantTile:hover .unwatchButton,
.lkParticipantTile:focus-within .unwatchButton {
	opacity: 1;
	visibility: visible;
}

.unwatchButton:hover {
	background-color: hsl(350, calc(80% * var(--saturation-factor, 1)), 55%);
}
