/* =========================================================================
   Derslik — voice dock + zoom stage (slices 4 and 6)

   Owns: `.dk-voicecard` (the panel dock, v5:388-408) and everything inside
   `.dk-stage` (the zoom view, v5:417-550). The stage is the one surface that
   deliberately ignores the eight palettes — it is a fixed dark room, scoped so
   the `--st-*` variables shadow nothing globally (visual-system C11).

   Loaded after `styles.css`, whose `.voice-stage` / `.voice-tile` /
   `.voice-dock` rules are still live DOM hooks; they are restyled here, never
   renamed.
   ========================================================================= */

/* --- the stage inside the chat pane -------------------------------------- */
.chat-area > .dk-stage {
  /* `--voice-w` is written by the gutter drag in public/voice.js. */
  flex: 0 0 var(--voice-w, 62%);
  min-width: 260px;
  max-width: 82%;
  border-radius: var(--r-2xl) 0 0 var(--r-2xl);
  overflow: hidden;
}
.dk-stage[hidden] { display: none; }
/* The stage and the chat rail sit side by side. That is `.dk-pane--row` in
   `dk/base.css` now (grouped onto `.chat-area.dk-pane` there) rather than a
   `:has()` undo of `.dk-pane`'s column — the chat area is a row whether or not
   a call is up, because the stage and the gutter simply ship `hidden`. */
/* The drag handle belongs to the stage, not to "some tile exists". */
.chat-area:has(> .dk-stage:not([hidden])) > .call-gutter { display: block; }

/* In zoom the chat rail is the design's 262px "Derslik sohbeti" column. */
.dk-workspace[data-stage="zoom"] .chat-area > .dk-stage {
  flex: 1 1 auto;
  max-width: none;
}
.dk-workspace[data-stage="zoom"] .chat-area > .message-panel {
  flex: 0 0 var(--zoomchat-w, 330px);
  min-width: 260px;
  border-left: var(--bw-thin) solid var(--line);
}
/* The chat header shrinks itself: `dk/chat.css` declares `.message-panel` as
   the `chatpane` container and drops the tool labels, then the topic, as the
   pane narrows — so the 330px lesson rail needs nothing extra here. */

/* --- stage header (v5:420-427) ------------------------------------------- */
.vstage-head {
  flex: none;
  display: flex;
  align-items: center;
  gap: var(--sp-5);
  flex-wrap: wrap;
  padding: var(--sp-6) var(--sp-8);
  color: var(--st-text);
}
.vstage-live { display: flex; align-items: center; gap: var(--sp-4); font: 800 var(--fs-sm) / 1.2 var(--font); }
.vstage-dot {
  width: 8px;
  height: 8px;
  border-radius: var(--r-full);
  background: var(--st-rec);
  animation: dkPulse 1.6s infinite;
}
.vstage-time,
.vstage-count { font: 700 var(--fs-2xs) / 1.2 var(--font); color: var(--st-mut); }
.vstage-count strong { color: var(--st-text); }
.vstage-flag {
  display: inline-flex;
  align-items: center;
  gap: var(--sp-2);
  padding: var(--sp-2) var(--sp-5);
  border-radius: 7px;
  font: 800 var(--fs-3xs) / 1.3 var(--font);
  letter-spacing: var(--ls-label);
}
.vstage-flag[hidden] { display: none; }
.vstage-flag.is-exam { background: rgba(214, 69, 96, 0.2); color: #e8a0b4; }
.vstage-flag.is-lesson { background: rgba(217, 169, 74, 0.15); color: var(--st-warn); }
.vstage-flag.is-rec { background: rgba(224, 82, 82, 0.2); color: #f0a0a0; }
.vstage-flag.is-rec .i { animation: dkPulse 1.6s infinite; }

/* --- screen area (v5:428-432) -------------------------------------------- */
.vstage-screen {
  position: relative;
  flex: 1;
  min-height: 0;
  margin: 0 var(--sp-7);
  border-radius: var(--r-lg);
  overflow: hidden;
  background: linear-gradient(150deg, var(--st-tile), var(--st-tile2));
}
/* Restyle the legacy media container in place — it keeps its class and its
   `hidden` toggling, both of which public/voice.js drives. */
.vstage-screen > .voice-stage {
  position: absolute;
  inset: 0;
  flex: initial;
  min-width: 0;
  max-width: none;
  margin: 0;
  padding: var(--sp-5);
  border: 0;
  border-radius: 0;
  background: transparent;
  box-shadow: none;
  overflow-y: auto;
}
.vstage-ph {
  position: absolute;
  inset: 0;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: var(--sp-4);
  color: var(--st-mut);
  font: 700 var(--fs-sm) / 1.4 var(--font);
  text-align: center;
  padding: var(--sp-8);
}
.vstage-screen:has(> .voice-stage:not([hidden])) > .vstage-ph { display: none; }

/* Media tiles carry both classes: `.voice-tile` (the JS hook + the 16/9 video
   frame) and `.dk-vtile` (the v5 look). The filmstrip sizing on `.dk-vtile`
   must not apply to them. */
.vstage-screen .voice-tile.dk-vtile {
  flex: initial;
  min-width: 0;
  max-width: none;
  height: auto;
  gap: 0;
  background: var(--st-tile);
  border: var(--bw) solid var(--st-line);
}
.vstage-screen .voice-tile.speaking { border-color: var(--st-speak); box-shadow: 0 0 0 2px var(--st-speak); }
.vstage-screen .voice-tile-label,
.vstage-screen .dk-vtile__name {
  position: absolute;
  left: var(--sp-5);
  bottom: var(--sp-5);
  padding: 2px var(--sp-5);
  border-radius: 7px;
  background: rgba(0, 0, 0, 0.45);
  color: #fff;
  font: 800 var(--fs-3xs) / 1.5 var(--font);
}

/* --- filmstrip roster tiles (v5:433-459) --------------------------------- */
.dk-filmstrip:empty { display: none; }
.dk-filmstrip .dk-vtile { cursor: default; }
.dk-filmstrip .dk-vtile .dk-avatar { --avatar-fg: #fff; }
.vtile-flag {
  position: absolute;
  font-size: var(--fs-md);
  line-height: 1;
}
.vtile-flag.is-hand { top: var(--sp-3); right: var(--sp-4); }
.vtile-flag.is-muted { bottom: var(--sp-4); left: var(--sp-4); font-size: var(--fs-3xs); color: #e86a8a; }
.vtile-flag.is-cam {
  bottom: var(--sp-4);
  right: var(--sp-4);
  padding: 2px var(--sp-4);
  border-radius: 5px;
  background: rgba(46, 158, 107, 0.25);
  color: var(--st-speak);
  font: 800 var(--fs-4xs) / 1.4 var(--font);
}
/* MC-10: "this member may share their screen" — the camera badge's twin, top-left so
   the two never overlap on a 170px tile. */
.vtile-flag.is-screen {
  top: var(--sp-3);
  left: var(--sp-4);
  padding: 2px var(--sp-4);
  border-radius: 5px;
  background: rgba(86, 140, 230, 0.25);
  color: #a9c6f5;
  font: 800 var(--fs-4xs) / 1.4 var(--font);
}
/* The moderator's grant buttons: the screen one sits next to the camera one (base.css
   owns .dk-vtile__act and its --mute/--mic/--cam tints); a granted member shows "on". */
.dk-vtile__act--screen { background: #2c3a52; color: #a9c6f5; }
.dk-vtile__act.is-on { box-shadow: 0 0 0 2px var(--st-speak); }
.member-actions .dk-btn.is-on { background: var(--acc); color: var(--accInk); }
.member-flag--grant {
  padding: 1px var(--sp-3);
  border-radius: 5px;
  background: rgba(46, 158, 107, 0.2);
  font: 800 var(--fs-4xs) / 1.4 var(--font);
}

/* --- control bar (v5:468-479) -------------------------------------------- */
.vstage-ctrl {
  flex: none;
  display: flex;
  align-items: stretch;
  justify-content: center;
  flex-wrap: wrap;
  gap: var(--sp-4);
  padding: var(--sp-5) var(--sp-7) var(--sp-7);
}
.vstage-ctrl .dk-vctrl[hidden] { display: none; }
.vstage-ctrl .dk-vctrl.active,
.vstage-ctrl .dk-vctrl.is-on { background: var(--acc); color: var(--accInk); }
.vstage-ctrl .dk-vctrl.danger-active { background: var(--st-warn); color: #17141f; }
/* MC-11: a locked microphone (Ders modu, a moderator's mute) is inert and its label
   says why ("Öğretmen susturdu"); it must not look like a button that will work. */
.vstage-ctrl .dk-vctrl[disabled],
.dk-voicecard__btn[disabled] { cursor: not-allowed; opacity: 0.78; }
.vstage-ctrl .dk-vctrl[disabled]:hover,
.dk-voicecard__btn[disabled]:hover { filter: none; }
.vstage-ctrl .dk-vctrl[disabled]:active { transform: none; }
.vctrl-devices { position: relative; display: flex; }

/* `.dk-devicebar` (v5:461) is a base primitive now — visual-system §7,
   `dk/base.css`. It stays dark-on-dark through the `--st-*` fallbacks, which
   resolve from whatever scope it is rendered into, so moving the rule between
   files changed nothing. Its anchor `.vctrl-devices` stays here. */

.vctrl-volume {
  display: flex;
  align-items: center;
  gap: var(--sp-4);
  min-width: 88px;
  padding: var(--sp-5) var(--sp-6);
  border-radius: var(--r-lg);
  background: var(--st-tile2);
  color: var(--st-text);
}
.vctrl-volume input[type="range"] { width: 88px; accent-color: var(--acc); }

/* --- the panel dock (v5:389-406) ----------------------------------------- */
.dk-voicecard { margin: var(--sp-5) var(--sp-7) var(--sp-7); }
.dk-voicecard[hidden] { display: none; }
.vcard-head { display: flex; align-items: center; gap: var(--sp-4); }
.vcard-dot {
  flex: none;
  width: 8px;
  height: 8px;
  border-radius: var(--r-full);
  background: #7ff2b8;
  animation: dkPulse 2s infinite;
}
.vcard-name {
  flex: 1;
  min-width: 0;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
  font: 800 var(--fs-sm) / 1.2 var(--font);
}
.vcard-time { font: 700 var(--fs-2xs) / 1.2 var(--font); opacity: 0.8; }
.vcard-state {
  margin: 0;
  font: 700 var(--fs-3xs) / 1.3 var(--font);
  opacity: 0.85;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.vcard-state:empty { display: none; }
.vcard-btns { display: flex; gap: var(--sp-3); }
.dk-voicecard__btn[hidden] { display: none; }
.dk-voicecard__btn.active { background: rgba(255, 255, 255, 0.42); }
.dk-voicecard__btn.danger-active { background: #d9a94a; color: #17141f; }

/* --- live strip in a normal channel (v5:571-581) -------------------------
   The element is rendered by `views/chat.js`; `public/voice.js` fills it, so
   the children below are the class contract that painter emits. The plate and
   its `[hidden]` rule are base.css; the dark-plate badge re-tint is chat.css.
   ------------------------------------------------------------------------- */
.dk-livestrip .ls-dot {
  width: 8px;
  height: 8px;
  border-radius: var(--r-full);
  background: #e05252;
  animation: dkPulse 1.6s infinite;
}
.dk-livestrip .ls-label { font: 800 var(--fs-xs) / 1.2 var(--font); letter-spacing: var(--ls-label); }
/* `flex-basis` rather than 0 so the sentence keeps a readable measure in the
   330px lesson rail and the avatar stack drops to its own line instead. */
.dk-livestrip .ls-text { flex: 1 1 11rem; min-width: 0; font: 700 var(--fs-sm) / 1.3 var(--font); }
.dk-livestrip .ls-stack { display: flex; }
.dk-livestrip .ls-stack .dk-avatar { margin-left: -8px; border: 2px solid #1b1826; }
.dk-livestrip .ls-stack .dk-avatar:first-child { margin-left: 0; }
.dk-livestrip .ls-join { flex: none; }

/* --- narrow screens ------------------------------------------------------ */
@media (max-width: 900px) {
  .chat-area > .dk-stage {
    flex: 1 1 auto;
    max-width: none;
    border-radius: var(--r-2xl);
  }
  .dk-workspace[data-stage="zoom"] .chat-area { flex-direction: column; }
  .dk-workspace[data-stage="zoom"] .chat-area > .message-panel {
    flex: 1 1 auto;
    border-left: 0;
    border-top: var(--bw-thin) solid var(--line);
  }
}

/* --- MC-07: the "how many groups?" dialog ------------------------------------
   Replaces window.prompt (it throws in Electron). base.css owns the primitives
   (.dk-scrim, .dk-dialog, .dk-input, .dk-btn); only the dialog's own parts are here. */
.voice-dialog { gap: var(--sp-5); }
.voice-dialog__input { text-align: center; font: 800 var(--fs-2xl) / 1.2 var(--font); }
.voice-dialog__error {
  margin: 0;
  color: var(--bad);
  font: 700 var(--fs-sm) / 1.3 var(--font);
  text-align: center;
}
.voice-dialog__error[hidden] { display: none; }
.voice-dialog__actions { display: flex; justify-content: flex-end; gap: var(--sp-4); }

/* --- MC-19: audio-only people get a speaking ring too -------------------------
   Camera tiles have always had one (.voice-tile.speaking above). A classroom is mostly
   voices without video, so the filmstrip avatar, the roster chip and the "ODADAKİLER" row
   of whoever LiveKit reports as speaking carry it as well. voice.js re-applies the class
   after every roster repaint, so a rebuilt tile does not lose it. */
.dk-filmstrip .dk-vtile.speaking { border-color: var(--st-speak); box-shadow: 0 0 0 2px var(--st-speak); }
.dk-filmstrip .dk-vtile.speaking .dk-avatar { box-shadow: 0 0 0 3px var(--st-speak); }
.vp-chip.speaking .dk-avatar,
.member-row.speaking .dk-avatar { box-shadow: 0 0 0 2px var(--ok); }
@media (prefers-reduced-motion: no-preference) {
  .dk-filmstrip .dk-vtile .dk-avatar,
  .vp-chip .dk-avatar,
  .member-row .dk-avatar { transition: box-shadow var(--dur-2) var(--ease); }
}

/* =========================================================================
   PHASE 5 fix round
   ========================================================================= */

/* --- #2 ux-filmstrip-actions-keyboard ------------------------------------------
   base.css hides a tile's moderation strip with display:none until :hover, and a display:none button can never
   take focus, so its :focus-within reveal never fired: a keyboard-only teacher had no way to mute / give the word /
   grant camera or screen from the stage (and below 1100 px the members pane that offers the same actions is hidden).
   The strip stays laid out and focusable and is hidden by opacity instead; hover, focus on the tile or on any of its
   buttons reveal it. (Override lives here, after base.css; base.css itself is not touched.) */
.dk-filmstrip .dk-vtile__actions {
  display: flex;
  opacity: 0;
  pointer-events: none;
  transition: opacity var(--dur-2) var(--ease);
}
.dk-filmstrip .dk-vtile:hover .dk-vtile__actions,
.dk-filmstrip .dk-vtile:focus-within .dk-vtile__actions {
  opacity: 1;
  pointer-events: auto;
}

/* --- #4 ux-filmstrip-40-students ------------------------------------------------
   With 40 pupils only ~3 tiles fit and base.css hid the scrollbar (scrollbar-width:none), so nothing said "there is more" and a plain
   wheel did nothing. A thin visible scrollbar tells the teacher the strip scrolls; voice.js maps a vertical wheel over it to a sideways scroll. */
.dk-filmstrip {
  scrollbar-width: thin;
  scrollbar-color: rgba(255, 255, 255, 0.34) transparent;
  padding-bottom: var(--sp-4);
}
.dk-filmstrip::-webkit-scrollbar { display: block; width: 8px; height: 8px; }
.dk-filmstrip::-webkit-scrollbar-track { background: transparent; }
.dk-filmstrip::-webkit-scrollbar-thumb { background: rgba(255, 255, 255, 0.34); border-radius: var(--r-full); }
.dk-filmstrip::-webkit-scrollbar-thumb:hover { background: rgba(255, 255, 255, 0.5); }

/* --- #5 ux-call-stage-contrast ------------------------------------------------------
   (a) The sharer's own tile ("Ekranını paylaşıyorsun") is a dark stage tile, but its label used the legacy page ink (var(--text)), which
   is DARK in the five light themes: 1.05-1.12:1, so the confirmation that she is live was invisible. It uses the stage's own light ink.
   (b) "Ayrıl" is 12px bold white; on the stage's #d64560 that is 4.3:1 (WCAG AA wants 4.5:1) in every theme. The stage token is darkened
   a notch (white on #b8324d = 5.8:1); the stage ignores the theme palettes on purpose, so this holds in all eight. */
.dk-stage { --st-leave: #b8324d; }
.dk-stage .voice-tile-ph { color: var(--st-text); opacity: 1; }

/* --- #6 ux-dialog-role-on-form: the role="dialog" container holds the form; the form lays itself out like the dialog does */
.voice-dialog__form { display: flex; flex-direction: column; gap: var(--sp-5); }

/* --- #9 ux-stage-short-viewport -------------------------------------------------------
   On a laptop (1280x640, 980x600) the stage's fixed parts - header, roster strip (142 px) and the control bar, which wraps into three
   59 px rows (218 px) - left the shared screen only 25-33 % of the stage's height: a letterboxed sliver. Up to 820 px of viewport height
   the fixed parts are compacted instead (not removed: every control keeps its icon AND its label, and the strip keeps avatar + name):
   a tighter control bar (two rows), a lower roster tile, less padding. The screen keeps >= 50 % down to 980x600. */
@media (max-height: 820px) {
  .vstage-head { padding: var(--sp-4) var(--sp-8); }
  .vstage-screen { margin-inline: var(--sp-5); }
  .dk-filmstrip { padding: var(--sp-4) var(--sp-5) var(--sp-3); gap: var(--sp-3); }
  .dk-filmstrip .dk-vtile { height: 80px; min-width: 150px; gap: 2px; }
  .vstage-ctrl { gap: var(--sp-3); padding: var(--sp-3) var(--sp-5) var(--sp-4); }
  .vstage-ctrl .dk-vctrl {
    min-width: 0;
    padding: var(--sp-3) var(--sp-4);
    gap: 1px;
    border-radius: var(--r-md);
    font-size: var(--fs-2xs);
    line-height: 1.15;
    white-space: nowrap;
  }
  .vstage-ctrl .dk-vctrl > svg { width: 16px; height: 16px; }
  .vctrl-volume { min-width: 0; padding: var(--sp-3) var(--sp-5); border-radius: var(--r-md); }
  .vctrl-volume input[type="range"] { width: 72px; }
}

/* --- toasts keep off the call's controls -------------------------------------------------------------
   toast.js anchors its stack (inline style) at the bottom centre of the viewport. During a call that is the control bar:
   a toast ("Kayıt başlatılamadı...", 5 s) sat on the very button the teacher wants to press again (Kaydet, Ayrıl...). While the
   call stage is up the stack moves to the top centre, under the app bar, over the stage header, which has nothing to press. */
body:has(.dk-stage:not([hidden])) .toast-container {
  bottom: auto !important;
  top: 46px !important;
}

/* --- several shares on the stage at once ------------------------------------------------------------------------
   styles.css lays every share out as a full-width row (grid-column: 1 / -1, 16:9). With 4 shares live a viewer saw 2: livekit's
   adaptiveStream pauses a tile that is off screen, so shares 3 and 4 stayed paused until the viewer scrolled (and dynacast stopped
   the publishers' layers nobody watched). voice.js writes how many remote shares are on the stage to data-screens:
     "1"      the focus: one full-width tile, as before
     "2".."4" every share at once, a 2-column grid that fills the stage (2 shares side by side, 3-4 as 2 x 2): all of them on
              screen, so all of them flow; each tile is small, so adaptiveStream asks for the small simulcast layer
     "many"   5+: the 2-column grid keeps 16:9 rows and scrolls (pin one to put it in the spotlight)
   A pinned tile ("Öne çıkar", .has-pinned) is the spotlight whatever the count. Camera tiles and the sharer's own placeholder
   stay below the shares (a row of their own), reached by scrolling, like they always were. */
.vstage-screen > .voice-stage[data-screens="2"]:not(.has-pinned),
.vstage-screen > .voice-stage[data-screens="3"]:not(.has-pinned),
.vstage-screen > .voice-stage[data-screens="4"]:not(.has-pinned) {
  grid-template-columns: repeat(2, minmax(0, 1fr));
  grid-template-rows: repeat(2, minmax(0, 1fr));
  grid-auto-rows: 7rem;
  align-content: stretch;
}
.vstage-screen > .voice-stage[data-screens="2"]:not(.has-pinned) { grid-template-rows: minmax(0, 1fr); }
.vstage-screen > .voice-stage[data-screens="many"]:not(.has-pinned) {
  grid-template-columns: repeat(2, minmax(0, 1fr));
}
.vstage-screen > .voice-stage:is([data-screens="2"], [data-screens="3"], [data-screens="4"], [data-screens="many"]):not(.has-pinned) .voice-tile[data-kind="screen"] {
  grid-column: auto;
}
.vstage-screen > .voice-stage:is([data-screens="2"], [data-screens="3"], [data-screens="4"]):not(.has-pinned) .voice-tile[data-kind="screen"] {
  aspect-ratio: auto; /* the tile fills its cell; the video inside keeps its own ratio (object-fit: contain) */
  min-height: 0;
}
.vstage-screen > .voice-stage:is([data-screens="2"], [data-screens="3"], [data-screens="4"]):not(.has-pinned) .voice-tile:not([data-kind="screen"]) {
  grid-column: 1 / -1;
}

/* --- phase 9: OD-13 DM call note, OD-37 camera offer, OD-11 tile buttons, OD-15 groups popover ------------------------------ */
.dm-call-banner { flex-wrap: wrap; }
.dm-call-note { flex: 1 0 100%; font: 700 var(--fs-2xs) / 1.4 var(--font); }
.dm-camera-offer[hidden] { display: none; }
/* a moderator's buttons on a remote tile (next to the pin / fullscreen ones): shown on hover / focus like them */
.voice-tile-mod {
  position: absolute;
  top: var(--sp-4);
  width: 28px;
  height: 28px;
  display: none;
  align-items: center;
  justify-content: center;
  border: 0;
  border-radius: var(--r-xs);
  background: rgba(0, 0, 0, 0.6);
  color: #fff;
  cursor: pointer;
}
.voice-tile-spot { right: 76px; }
.voice-tile-endshare { right: 108px; }
.voice-tile:hover .voice-tile-mod,
.voice-tile:focus-within .voice-tile-mod,
.voice-tile-mod:focus-visible { display: flex; }
.voice-tile.spotlit { box-shadow: 0 0 0 2px var(--st-warn); }
.dk-vtile__act.is-armed, .member-actions .dk-btn.is-armed { outline: 2px solid var(--st-warn, #d9a94a); }
.voice-groups-pop {
  position: fixed;
  z-index: var(--z-popover, 9000);
  min-width: 230px;
  padding: var(--sp-5);
  border-radius: var(--r-lg);
  background: var(--st-tile2, #2a2438);
  color: var(--st-text, #efeff8);
  box-shadow: 0 8px 24px rgba(0, 0, 0, 0.4);
}
.voice-groups-pop__title { margin: 0 0 var(--sp-3); font: 800 var(--fs-sm) / 1.2 var(--font); }
.voice-groups-pop__list { list-style: none; margin: 0; padding: 0; display: flex; flex-direction: column; gap: var(--sp-3); }
.voice-groups-pop__list li { display: flex; align-items: center; justify-content: space-between; gap: var(--sp-5); font: 700 var(--fs-xs) / 1.3 var(--font); }
.voice-groups-pop__empty { margin: 0; font: 700 var(--fs-xs) / 1.3 var(--font); opacity: 0.8; }

/* --- the sharer's own screen: live preview, with a toggle ---------------------------------------------------------
   The tile shows a muted <video> of her own share; "Önizlemeyi gizle" swaps it for the "Ekranını paylaşıyorsun" card (and detaches
   the video). The button wears its own dark fill and white ink, so it reads the same over a video and over the card in all eight
   themes (white on rgba(0,0,0,.82) is far above 4.5:1 on any backdrop). Top-right: the pin is top-left, the fullscreen bottom-right. */
.voice-tile-preview {
  position: absolute;
  right: 0.5rem;
  top: 0.5rem;
  z-index: 3;
  padding: 0.3rem 0.65rem;
  border: 1px solid rgba(255, 255, 255, 0.4);
  border-radius: var(--r-xs);
  background: rgba(0, 0, 0, 0.82);
  color: #fff;
  font: 700 0.75rem / 1.2 var(--font);
  cursor: pointer;
}
.voice-tile-preview:hover { background: #000; }
.voice-tile-preview:focus-visible { outline: 2px solid #fff; outline-offset: 2px; box-shadow: 0 0 0 4px #000; }
/* a DM call floats her camera bottom-right: her screen preview sits to its left, not on top of it */
.dm-chat.chat-area.call-active .skype-stage .voice-tile-selfscreen { right: calc(1rem + min(28%, 200px) + 0.75rem); }
