/* ---- design tokens: one source of truth for palette, radius, sizing ---- */
:root {
  --bg: #202124;          /* app background */
  --surface: #23262d;     /* cards, inputs */
  --surface-2: #2b2f37;   /* secondary buttons / panels */
  --surface-3: #3c4043;   /* video tiles, default control */
  --panel: #1b1e24;       /* floating panels / banners */
  --line: #3a3f4a;        /* hairline borders */
  --text: #e8eaed;        /* primary text */
  --text-dim: #9aa0a6;    /* secondary text */
  --accent: #2f7d4f;      /* brand green — primary actions */
  --accent-hi: #4caf7d;
  --info: #1a73e8;        /* join / links (blue) */
  --info-hi: #1765cc;
  --info-soft: #8ab4f8;   /* active toggle state */
  --danger: #ea4335;      /* mute / off / hang up */
  --danger-hi: #d93025;
  --ctl: 56px;            /* in-call / preview control diameter */
  --radius: 10px;
  --radius-pill: 24px;
}

* { box-sizing: border-box; margin: 0; -webkit-tap-highlight-color: transparent; }
[hidden] { display: none !important; }
html, body { height: 100%; }
body {
  font-family: 'Google Sans', Roboto, system-ui, sans-serif;
  background: var(--bg);
  color: var(--text);
}

/* accessibility floor: a clear keyboard focus ring everywhere, and honour a
   reduced-motion preference by stilling the looping pulse animations */
:focus-visible { outline: 2px solid var(--info-soft); outline-offset: 2px; }
@media (prefers-reduced-motion: reduce) {
  * { animation-duration: .001ms !important; animation-iteration-count: 1 !important;
      transition-duration: .001ms !important; }
}

/* lobby */
#lobby {
  height: 100%;
  display: flex; flex-direction: column;
  align-items: center; justify-content: center;
  gap: 14px; padding: 16px;
}
#lobby h1 { font-size: 22px; font-weight: 600; }
#lobby input[type=text], #lobby input[type=password] {
  width: min(320px, 90vw);
  padding: 12px 14px; font-size: 16px;
  background: var(--surface); color: inherit;
  border: 1px solid var(--line); border-radius: 10px;
}
#lobby .opt { font-size: 14px; color: #aab; user-select: none; }
#lobby button {
  width: min(320px, 90vw);
  padding: 12px; font-size: 17px;
  background: var(--accent); color: #fff;
  border: 0; border-radius: 10px; cursor: pointer;
}
#lobby button:disabled { opacity: .5; }
.error { color: #ff7b72; font-size: 14px; max-width: min(400px, 90vw); text-align: center; }

/* post-call screen */
#ended {
  height: 100%;
  display: flex; flex-direction: column;
  align-items: center; justify-content: center;
  gap: 22px; padding: 24px;
}
#ended h1 { font-size: 24px; font-weight: 400; }
#ended button {
  padding: 14px 48px; font-size: 15px; font-weight: 500;
  background: var(--info); color: #fff;
  border: 0; border-radius: 24px; cursor: pointer;
}
#ended button:hover { background: var(--info-hi); }

/* Meet-style lobby: live preview + join pane */
#lobby.meet-lobby {
  height: 100%;
  display: flex; flex-direction: row;
  align-items: center; justify-content: center;
  gap: 48px; padding: 24px;
  flex-wrap: wrap;
}
#lobby.meet-lobby input[type=text] {
  width: 100%;
  background: transparent;
  border: 1px solid #5f6368; border-radius: 4px;
}
#lobby.meet-lobby input[type=text]:focus { outline: none; border-color: var(--info-soft); }
#lobby.meet-lobby button#joinBtn {
  width: auto;
  padding: 14px 48px; font-size: 15px; font-weight: 500;
  background: var(--info); border-radius: 24px;
}
#lobby.meet-lobby button#joinBtn:hover { background: var(--info-hi); }
/* preview toggle buttons: outrank the generic #lobby button styles */
#lobby.meet-lobby .ctl {
  width: 56px; height: 56px; padding: 0;
  background: rgba(60, 64, 67, .9);
  border-radius: 50%;
}
#lobby.meet-lobby .ctl:hover { background: #4a4d51; }
#lobby.meet-lobby .ctl.off { background: var(--danger); }
#lobby.meet-lobby .ctl.off:hover { background: var(--danger-hi); }
#previewWrap {
  position: relative;
  width: min(640px, 92vw);
  aspect-ratio: 16 / 9; /* placeholder until the real camera aspect arrives */
  max-height: 62vh; /* a tall portrait stream must not push the join pane away */
  background: var(--surface-3);
  border-radius: 12px;
  overflow: hidden;
  flex: 0 1 auto;
}
#previewWrap video {
  width: 100%; height: 100%;
  object-fit: cover;
  transform: scaleX(-1);
  background: #000;
}
#previewOff {
  position: absolute; inset: 0;
  display: flex; align-items: center; justify-content: center;
  background: var(--surface-3);
  color: var(--text); font-size: 18px;
}
#previewControls {
  position: absolute;
  left: 0; right: 0; bottom: 14px;
  display: flex; justify-content: center; gap: 16px;
}
#joinPane {
  display: flex; flex-direction: column;
  align-items: center; gap: 16px;
  min-width: 260px;
}
#joinPane h1 { font-size: 24px; font-weight: 400; }
#joinPane input {
  width: 100%;
  padding: 13px 15px; font-size: 16px;
  background: transparent; color: inherit;
  border: 1px solid #5f6368; border-radius: 4px;
}
#joinPane input:focus { outline: none; border-color: var(--info-soft); }
#joinPane button {
  padding: 14px 48px; font-size: 15px; font-weight: 500;
  background: var(--info); color: #fff;
  border: 0; border-radius: 24px; cursor: pointer;
}
#joinPane button:hover { background: var(--info-hi); }
#joinPane button:disabled { opacity: .6; }

/* round control buttons (preview + in-call bar), Meet-style */
.ctl, #bar button {
  width: var(--ctl); height: var(--ctl);
  flex: 0 0 auto;
  display: inline-flex; align-items: center; justify-content: center;
  background: rgba(60, 64, 67, .9);
  border: 1px solid transparent; border-radius: 50%;
  cursor: pointer; color: var(--text);
  transition: background .15s, transform .1s;
  position: relative;
}
.ctl:hover, #bar button:hover { background: #4a4d51; }
/* a tap must animate the ROUND button itself, never paint a square around
   it: the press squeezes the circle, and keyboard focus gets a round ring
   (box-shadow follows border-radius; the global outline stays square) */
.ctl:active, #bar button:active, .more-item:active { transform: scale(.86); }
.ctl:focus, #bar button:focus, .more-item:focus, .drawer-head .x:focus { outline: none; }
.ctl:focus-visible, #bar button:focus-visible, .more-item:focus-visible {
  outline: none;
  box-shadow: 0 0 0 2px var(--info-soft);
}
.ctl svg, #bar button svg { width: 24px; height: 24px; fill: currentColor; }
.ctl .ic-off, #bar button .ic-off { display: none; }
.ctl.off, #bar button.off { background: var(--danger); }
.ctl.off:hover, #bar button.off:hover { background: var(--danger-hi); }
.ctl.off .ic-on, #bar button.off .ic-on { display: none; }
.ctl.off .ic-off, #bar button.off .ic-off { display: block; }

/* pre-call diagnostics (lobby) */
.linklike { background: none; border: 0; color: var(--info-soft); cursor: pointer; font-size: 13px; padding: 6px; }
.linklike:hover { text-decoration: underline; }
#diagPanel { display: flex; flex-direction: column; gap: 10px; margin: 4px 0 8px; padding: 12px;
  background: #2a2d31; border-radius: 10px; }
.diag-row { display: flex; align-items: center; gap: 10px; font-size: 13px; color: var(--text); }
.diag-label { width: 74px; color: var(--text-dim); }
.diag-row .meter { flex: 1; height: 8px; background: var(--surface-3); border-radius: 4px; overflow: hidden; }
.diag-row .meter #micLevel { height: 100%; width: 0; background: #34a853; transition: width .1s linear; }
.diag-row button { background: var(--surface-3); color: var(--text); border: 0; border-radius: 8px;
  padding: 6px 12px; cursor: pointer; font-size: 13px; }
.diag-row button:hover { background: #4a4d51; }

/* speaker/earpiece toggle: speaker icon by default (loud = highlighted via
   .active), earpiece (handset) icon when routed to the ear */
#audioOutBtn .ic-ear { display: none; }
#audioOutBtn.earpiece .ic-spk { display: none; }
#audioOutBtn.earpiece .ic-ear { display: block; }

/* call */
/* during a call the page is locked to exactly the visible viewport: no page
   scroll, no rubber-band, no pinch/double-tap zoom. 100dvh tracks the mobile
   browser UI (unlike 100vh/100%, which overflow behind it and caused scroll). */
body.in-call {
  height: 100vh; height: 100dvh;
  overflow: hidden;
  overscroll-behavior: none;
  touch-action: manipulation; /* kills double-tap zoom; drags set their own */
}
#call { height: 100%; display: flex; flex-direction: column; position: relative; }
#grid {
  flex: 1; min-height: 0;
  overflow: hidden; /* the grid shrinks to fit; tiles never push the bar off */
  display: grid; gap: 8px; padding: 8px;
  grid-template-columns: repeat(auto-fit, minmax(min(100%, 280px), 1fr));
  align-content: center;
}
.tile {
  position: relative;
  background: var(--surface-3);
  border-radius: 8px;
  overflow: hidden;
  aspect-ratio: 4 / 3;
  outline: 2px solid transparent;
  outline-offset: -2px;
  transition: outline-color .15s;
}
.tile.speaking { outline-color: var(--info-soft); }
.tile video {
  width: 100%; height: 100%;
  object-fit: cover; display: block;
  background: #000;
}
.tile.cam-off video, .tile.stalled video { visibility: hidden; }
.tile .avatar {
  position: absolute; inset: 0;
  display: none;
  align-items: center; justify-content: center;
  background: var(--surface-3);
}
.tile.cam-off .avatar, .tile.stalled .avatar { display: flex; }
.tile .avatar-circle {
  width: 38%; max-width: 120px; min-width: 40px;
  aspect-ratio: 1;
  border-radius: 50%;
  display: flex; align-items: center; justify-content: center;
  font-size: clamp(18px, 6vw, 48px); font-weight: 500;
  color: #fff;
  user-select: none;
}
.tile .stall-note {
  display: none;
  position: absolute;
  left: 50%; bottom: 16%;
  transform: translateX(-50%);
  padding: 6px 14px;
  background: rgba(0, 0, 0, .6);
  border-radius: 16px;
  font-size: 13px; color: var(--text);
  z-index: 3;
  animation: stallPulse 1.2s infinite alternate;
  white-space: nowrap;
}
@keyframes stallPulse { from { opacity: .55; } to { opacity: 1; } }
.tile.stalled .stall-note { display: block; }

/* frozen last frame shown (dimmed) while the peer's link recovers */
.tile canvas.freeze {
  display: none;
  position: absolute; inset: 0;
  width: 100%; height: 100%;
  object-fit: cover;
  z-index: 1;
}
.tile.stalled.has-freeze canvas.freeze {
  display: block;
  filter: grayscale(.5) brightness(.65) blur(1.5px);
}
.tile.stalled.has-freeze .avatar { display: none; }
.tile .label {
  position: absolute; left: 10px; bottom: 8px;
  display: inline-flex; align-items: center; gap: 5px;
  font-size: 13px;
  background: rgba(0, 0, 0, .5);
  padding: 3px 9px; border-radius: 4px;
}
.tile .mic-off { display: inline-flex; }
.tile .mic-off svg { width: 14px; height: 14px; fill: var(--danger); }
.tile.local video { transform: scaleX(-1); }
.tile.local video.no-mirror, #previewWrap video.no-mirror { transform: none; }

/* single remote peer: full-screen like Telegram/Zoom 1:1 calls */
#grid.single { display: block; padding: 0; }
#grid.single .tile { aspect-ratio: auto; height: 100%; border-radius: 0; }

/* own video: floating draggable pip; aspect ratio follows the camera
   (set inline from JS), so a portrait phone gets a tall pip, uncropped */
#selfView {
  position: fixed;
  right: 12px; bottom: calc(92px + env(safe-area-inset-bottom));
  width: clamp(96px, 24vw, 170px);
  z-index: 20;
  box-shadow: 0 4px 16px rgba(0,0,0,.55);
  cursor: grab;
  touch-action: none;
  user-select: none;
}
#selfView:active { cursor: grabbing; }
#selfView .label { font-size: 11px; left: 4px; bottom: 3px; }
/* alone in the room: own video takes the stage */
#selfView.solo,
#selfView.stage {
  inset: 0; /* full-screen; the fixed control bar overlays the bottom */
  width: auto;
  aspect-ratio: auto !important; /* beats the inline camera ratio */
  cursor: default;
  touch-action: manipulation; /* taps pass, but pinch stays ours (zoom) */
  box-shadow: none;
  z-index: 5; /* under the peer's miniature and the control bar (z 50) */
}

/* split (tiled) view: own video sits in the grid as an equal cell — the
   fixed-pip styles above are all overridden (id selector, hence the id here) */
#selfView.in-grid {
  position: static;
  width: auto;
  aspect-ratio: 4 / 3 !important; /* beats the inline camera ratio */
  box-shadow: none;
  cursor: default;
  touch-action: auto;
  z-index: auto;
  border-radius: 8px;
}

/* view toggle: grid icon in fullscreen mode (tap -> split), and back */
#viewBtn .ic-full { display: none; }
#viewBtn.grid-mode .ic-grid { display: none; }
#viewBtn.grid-mode .ic-full { display: block; }

/* 1:1 swapped view: the peer becomes the draggable corner miniature */
#grid.single .tile.mini {
  position: fixed;
  right: 12px; bottom: calc(92px + env(safe-area-inset-bottom));
  width: clamp(96px, 24vw, 170px);
  height: auto;
  border-radius: 12px;
  z-index: 20;
  box-shadow: 0 4px 16px rgba(0,0,0,.55);
  cursor: grab;
  touch-action: none;
  user-select: none;
}
#grid.single .tile.mini .label { font-size: 11px; left: 4px; bottom: 3px; }

/* hub (room list) */
#hub {
  max-width: 480px;
  margin: 0 auto;
  padding: 28px 16px calc(28px + env(safe-area-inset-bottom));
  display: flex; flex-direction: column; gap: 14px;
}
#hub h1 { font-size: 22px; font-weight: 600; }
#hub h2 { font-size: 14px; font-weight: 600; color: #99a; margin-top: 10px; text-transform: uppercase; letter-spacing: .05em; }
.room-list { display: flex; flex-direction: column; gap: 8px; }
.room-card {
  display: block;
  padding: 14px 16px;
  background: var(--surface);
  border: 1px solid var(--line); border-radius: 10px;
  color: inherit; text-decoration: none;
  font-size: 16px;
}
.room-card:hover { border-color: var(--accent-hi); }
#hub button, .btn-like {
  padding: 12px 16px; font-size: 16px;
  background: var(--accent); color: #fff;
  border: 0; border-radius: 10px; cursor: pointer;
  text-align: center; text-decoration: none; display: inline-block;
}
#hub .row { display: flex; gap: 8px; margin-top: 8px; }
#hub .row > * { flex: 1; }
#hub .row button, #hub .row .btn-like { background: var(--surface-2); }
#created input, #hub .row input[type=text] {
  width: 100%;
  padding: 12px 14px; font-size: 14px;
  background: var(--surface); color: #aab;
  border: 1px solid var(--line); border-radius: 10px;
}
.hint { font-size: 13px; color: #99a; }
.muted { color: #778; font-size: 14px; }

/* site navigation (hub, room lobby) */
.site-nav {
  display: flex; flex-wrap: wrap;
  gap: 18px;
  justify-content: center;
  margin-top: 14px;
}
.site-nav a {
  color: #99a; font-size: 14px; text-decoration: none;
  padding: 6px 4px;
}
.site-nav a:hover { color: var(--text); }
#hub .site-nav { margin-top: 24px; justify-content: flex-start; }

/* registration captcha */
.captcha-box { display: flex; align-items: center; gap: 8px; }
.captcha-box img { border-radius: 10px; border: 1px solid var(--line); }
.captcha-box button {
  width: 44px; height: 44px; font-size: 20px;
  background: var(--surface-2); color: #fff;
  border: 0; border-radius: 10px; cursor: pointer;
}

/* pending registrations (admin) */
.pending-row {
  display: flex; align-items: center; gap: 8px;
  padding: 10px 14px;
  background: var(--surface);
  border: 1px solid var(--line); border-radius: 10px;
}
.pending-row .name { flex: 1; font-size: 16px; }
.pending-row button {
  padding: 8px 14px; font-size: 14px;
  border: 0; border-radius: 8px; cursor: pointer; color: #fff;
}
.pending-row .ok { background: var(--accent); }
.pending-row .no, #hub .pending-row .no { background: #7d2f2f; }
.pending-row input.acl {
  flex: 1.2; min-width: 90px;
  padding: 8px 10px; font-size: 13px;
  background: #14161a; color: inherit;
  border: 1px solid var(--line); border-radius: 8px;
}

/* incoming call banner (live ringtone) */
.call-banner {
  position: fixed;
  top: calc(10px + env(safe-area-inset-top));
  left: 50%; transform: translateX(-50%);
  width: min(400px, calc(100vw - 24px));
  background: var(--panel);
  border: 1px solid var(--accent); border-radius: 14px;
  padding: 14px;
  z-index: 100;
  display: flex; align-items: center; gap: 10px;
  box-shadow: 0 8px 30px rgba(0,0,0,.7);
  animation: callPulse 1s infinite alternate;
}
@keyframes callPulse {
  from { border-color: var(--accent); }
  to   { border-color: var(--accent-hi); box-shadow: 0 8px 34px rgba(76,175,125,.25); }
}
.call-banner .who { flex: 1; font-size: 15px; }
.call-banner button {
  padding: 10px 14px; font-size: 14px;
  border: 0; border-radius: 10px; cursor: pointer; color: #fff;
}
.call-banner .answer { background: var(--accent); }
.call-banner .decline { background: #7d2f2f; }

/* invite / audio-output panels inside a call: above the control bar (z 50),
   otherwise its buttons overlap the panel's own rows */
#audioPanel,
#flagPanel,
#routePanel,
#invitePanel {
  position: fixed;
  left: 50%; transform: translateX(-50%);
  bottom: calc(96px + env(safe-area-inset-bottom));
  width: min(360px, calc(100vw - 24px));
  max-height: calc(100dvh - 120px - env(safe-area-inset-bottom));
  overflow-y: auto;
  background: var(--panel);
  border: 1px solid var(--line); border-radius: 14px;
  padding: 14px;
  z-index: 55;
  display: flex; flex-direction: column; gap: 10px;
  box-shadow: 0 8px 30px rgba(0,0,0,.6);
}

/* audio output rows: device icon (speaker / earpiece / bluetooth) + name */
/* the audio chooser opens beside its trigger in the TOP bar */
#audioPanel {
  left: auto; right: 12px; transform: none;
  top: calc(64px + env(safe-area-inset-top));
  bottom: auto;
  max-height: calc(100dvh - 180px);
}

.audio-row { cursor: pointer; }
.audio-row .ai { width: 20px; height: 20px; flex: 0 0 auto; fill: var(--text-dim); }
.audio-row.current .ai { fill: var(--info-soft); }
.audio-row .chk { color: var(--info-soft); font-weight: 600; }
.audio-row:hover { border-color: var(--info-soft); }

/* camera zoom: preset chips above the bar, like the phone's camera app;
   the active chip carries the exact factor while pinching */
#zoomCtl {
  position: fixed;
  left: 50%; transform: translateX(-50%);
  bottom: calc(100px + env(safe-area-inset-bottom));
  z-index: 49;
  display: flex; align-items: center; gap: 8px;
  transition: opacity .3s;
}
#call.idle #zoomCtl { opacity: 0; pointer-events: none; }
.zchip {
  min-width: 42px; height: 42px;
  padding: 0 8px;
  background: rgba(0, 0, 0, .5);
  border: 1px solid rgba(255, 255, 255, .12); border-radius: 21px;
  color: var(--text); font-size: 13px;
  cursor: pointer;
  transition: transform .1s, background .15s;
}
.zchip:active { transform: scale(.86); }
.zchip.on {
  background: rgba(0, 0, 0, .75);
  border-color: var(--info-soft);
  color: var(--info-soft); font-weight: 600;
}
#audioPanel h3, #invitePanel h3, #flagPanel h3, #routePanel h3 { font-size: 15px; font-weight: 600; }
#flagPanel .hint { font-size: 12px; color: var(--text-dim); margin: 0; }
#audioPanel > button,
#flagPanel > button,
#routePanel > button,
#invitePanel > button {
  padding: 10px; font-size: 14px;
  background: var(--surface-2); color: #fff;
  border: 0; border-radius: 10px; cursor: pointer;
}

.pending-row select {
  padding: 8px 10px; font-size: 14px;
  background: #14161a; color: inherit;
  border: 1px solid var(--line); border-radius: 8px;
}

/* participants count badge on the bar button */
#peopleBtn .count {
  position: absolute;
  top: -3px; right: -5px;
  min-width: 18px; height: 18px;
  padding: 0 5px;
  border-radius: 9px;
  background: var(--info); color: #fff;
  font-size: 11px; font-weight: 500; line-height: 18px;
  text-align: center;
  pointer-events: none;
}
#peopleBtn.active .count { background: var(--bg); color: var(--info-soft); }

/* participants drawer: Meet-style side sheet sliding in from the right,
   over a dimmed backdrop that dismisses it on tap */
#peopleDrawer { position: fixed; inset: 0; z-index: 70; }
#peopleDrawer .drawer-backdrop {
  position: absolute; inset: 0;
  background: rgba(0, 0, 0, .45);
  animation: backdropIn .2s ease;
}
#peoplePanel {
  position: absolute;
  top: 0; right: 0; bottom: 0;
  width: min(320px, 85vw);
  background: var(--panel);
  border-left: 1px solid var(--line);
  padding: calc(14px + env(safe-area-inset-top)) 14px calc(14px + env(safe-area-inset-bottom)) 14px;
  display: flex; flex-direction: column; gap: 8px;
  box-shadow: -8px 0 30px rgba(0,0,0,.5);
  animation: drawerIn .25s cubic-bezier(.2, .7, .3, 1);
}
@keyframes drawerIn { from { transform: translateX(100%); } to { transform: none; } }
@keyframes backdropIn { from { opacity: 0; } to { opacity: 1; } }
.drawer-head {
  display: flex; align-items: center; justify-content: space-between;
  gap: 8px;
}
.drawer-head h3 { font-size: 16px; font-weight: 600; }
.drawer-head .x {
  width: 38px; height: 38px;
  display: flex; align-items: center; justify-content: center;
  background: transparent; border: 0; border-radius: 50%;
  color: var(--text-dim); font-size: 18px; cursor: pointer;
}
.drawer-head .x:hover { background: var(--surface-2); color: var(--text); }
#peopleList { flex: 1; min-height: 0; overflow-y: auto; }
.person-row {
  display: flex; align-items: center; gap: 12px;
  padding: 9px 4px;
}
/* the tile avatar styles are scoped to .tile — these smaller avatars carry
   their own shape */
.person-row .avatar-circle, .toast .avatar-circle {
  border-radius: 50%;
  display: flex; align-items: center; justify-content: center;
  color: #fff; font-weight: 500;
  user-select: none;
  flex: 0 0 auto;
}
.person-row .avatar-circle {
  width: 34px; height: 34px;
  font-size: 16px;
}
.person-info { flex: 1; min-width: 0; }
.person-name {
  font-size: 14px;
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
.person-sub { font-size: 12px; color: var(--text-dim); }
.person-icons { display: flex; align-items: center; gap: 10px; flex: 0 0 auto; }
.person-icons svg { width: 18px; height: 18px; fill: var(--text-dim); }
.person-icons svg.off { fill: var(--danger); }

/* join/leave toasts: bottom-left cards that ease in, hold, and fade out —
   the Google Meet pattern */
#toasts {
  position: fixed;
  left: calc(16px + env(safe-area-inset-left));
  bottom: calc(96px + env(safe-area-inset-bottom));
  z-index: 60;
  display: flex; flex-direction: column; gap: 8px;
  pointer-events: none;
}
.toast {
  display: flex; align-items: center; gap: 10px;
  max-width: min(320px, calc(100vw - 32px));
  padding: 10px 16px 10px 10px;
  background: var(--panel);
  border: 1px solid var(--line); border-radius: 12px;
  font-size: 14px;
  box-shadow: 0 4px 20px rgba(0,0,0,.5);
  animation: toastIn .3s cubic-bezier(.2, .7, .3, 1);
}
.toast.hide { animation: toastOut .35s ease forwards; }
.toast .avatar-circle {
  width: 28px; height: 28px;
  font-size: 14px;
}
.toast b { font-weight: 600; }
.toast span {
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
@keyframes toastIn {
  from { opacity: 0; transform: translateY(14px) scale(.96); }
  to   { opacity: 1; transform: none; }
}
@keyframes toastOut {
  to { opacity: 0; transform: translateY(8px) scale(.97); }
}

/* hidden diagnostics overlay (?stats=1 or a click on the clock) */
#statsPanel {
  position: fixed;
  top: calc(64px + env(safe-area-inset-top)); left: 8px; /* below the top bar */
  z-index: 40;
  background: rgba(0, 0, 0, .65);
  padding: 8px 10px; border-radius: 8px;
  font: 11px/1.5 ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;
  color: var(--text-dim);
  white-space: pre;
  pointer-events: none;
  max-width: calc(100vw - 16px);
  overflow: hidden;
}

/* top bar: clock/room on the left, camera flip + audio route on the right —
   Meet's mobile arrangement, keeps the bottom row to five primary buttons */
#topbar {
  position: fixed; left: 0; right: 0; top: 0; z-index: 50;
  display: flex; align-items: center; justify-content: space-between;
  background: linear-gradient(to bottom, rgba(0,0,0,.55) 30%, rgba(0,0,0,0));
  padding: calc(10px + env(safe-area-inset-top)) calc(12px + env(safe-area-inset-right)) 18px calc(16px + env(safe-area-inset-left));
  transition: opacity .3s, transform .3s;
}
#call.idle #topbar {
  opacity: 0;
  transform: translateY(-16px);
  pointer-events: none;
}
#topbar .top-right { display: flex; gap: 10px; }
#topbar .ctl { width: 44px; height: 44px; background: rgba(32, 33, 36, .55); }
#topbar .ctl svg { width: 20px; height: 20px; }
#topbar .ctl.active { background: var(--info-soft); color: var(--bg); }
#clock { font-size: 14px; color: var(--text); cursor: pointer; user-select: none;
  text-shadow: 0 1px 3px rgba(0,0,0,.7); }

/* control bar: five primary buttons centred, status on the right (desktop) */
#bar {
  position: fixed; left: 0; right: 0; bottom: 0; z-index: 50;
  display: flex; align-items: center; justify-content: center;
  /* legibility over any video behind it, and it can never be covered */
  background: linear-gradient(to top, rgba(0,0,0,.7) 30%, rgba(0,0,0,0));
  padding: 20px calc(16px + env(safe-area-inset-right)) calc(12px + env(safe-area-inset-bottom)) calc(16px + env(safe-area-inset-left));
  transition: opacity .3s, transform .3s;
}
#call.idle #bar {
  opacity: 0;
  transform: translateY(16px);
  pointer-events: none;
}
#bar .bar-center { display: flex; flex-wrap: wrap; justify-content: center; gap: 12px; row-gap: 8px; min-width: 0; }
#status {
  position: absolute;
  right: calc(16px + env(safe-area-inset-right));
  top: 50%; transform: translateY(-50%);
  max-width: 26vw;
  text-align: right; font-size: 13px; color: var(--text-dim);
}
#bar button.hangup {
  width: calc(var(--ctl) + 12px);
  border-radius: var(--radius-pill);
  background: var(--danger);
}
#bar button.hangup:hover { background: var(--danger-hi); }
#bar button.active { background: var(--info-soft); color: var(--bg); }
#bar button.active:hover { background: #aecbfa; }

/* "More" popover: secondary controls (noise, flip, present, invite) with
   labels, floating just above the bar so the primary row stays short */
#morePanel {
  position: fixed; left: 50%; transform: translateX(-50%);
  bottom: calc(88px + env(safe-area-inset-bottom));
  z-index: 51;
  display: flex; flex-wrap: wrap; gap: 6px; justify-content: center;
  max-width: calc(100vw - 24px);
  background: var(--panel);
  border: 1px solid var(--line); border-radius: 16px;
  padding: 10px;
  box-shadow: 0 8px 30px rgba(0,0,0,.6);
}
.more-item {
  width: 76px; height: 66px;
  display: flex; flex-direction: column; align-items: center; justify-content: center; gap: 5px;
  background: transparent; border: 0; border-radius: 12px;
  color: var(--text); cursor: pointer;
  transition: background .15s, transform .1s;
}
.more-item:hover { background: var(--surface-2); }
.more-item svg { width: 24px; height: 24px; fill: currentColor; }
.more-item span { font-size: 11px; color: var(--text-dim); }
.more-item.off svg { fill: var(--danger); }
.more-item.active { color: var(--info-soft); }
.more-item.active span { color: var(--info-soft); }

/* narrow screens: drop the clock/status, shrink the controls, and let the row
   wrap — so every button stays fully on-screen and tappable */
@media (max-width: 640px) {
  :root { --ctl: 48px; }
  #status { display: none; } /* the clock lives in the top bar and stays */
  #bar { padding-left: max(8px, env(safe-area-inset-left)); padding-right: max(8px, env(safe-area-inset-right)); }
  #bar .bar-center { gap: 10px; }
  #bar button svg { width: 22px; height: 22px; }
  /* keep join/leave toasts clear of the zoom chips */
  #toasts { bottom: calc(156px + env(safe-area-inset-bottom)); }
}
@media (max-width: 380px) {
  :root { --ctl: 44px; }
  #bar .bar-center { gap: 8px; }
}

/* call-quality feedback: chips (in-call "problem now" flags + post-call
   rating form) */
.fb-chips { display: flex; flex-wrap: wrap; gap: 8px; justify-content: center; }
.fb-chip {
  padding: 8px 12px; font-size: 13px;
  background: var(--surface-2); color: var(--text);
  border: 1px solid var(--line); border-radius: 18px; cursor: pointer;
}
.fb-chip.on { background: rgba(138, 180, 248, .16); border-color: var(--info-soft); color: var(--info-soft); }
.fb-chip:active { transform: scale(.94); }
#feedback {
  display: flex; flex-direction: column; align-items: center; gap: 14px;
  width: min(440px, 100%); box-sizing: border-box;
  background: var(--panel); border: 1px solid var(--line); border-radius: 16px;
  padding: 18px 16px;
}
#feedback[hidden] { display: none; }
#feedback h2 { font-size: 17px; font-weight: 500; margin: 0; }
.fb-stars { display: flex; gap: 6px; }
#ended .fb-stars button {
  width: 44px; height: 44px; padding: 0;
  font-size: 26px; line-height: 1;
  background: transparent; color: var(--text-dim);
  border: 0; border-radius: 22px; cursor: pointer;
}
#ended .fb-stars button.on { color: #fbbc04; }
#ended .fb-chip { padding: 8px 12px; font-size: 13px; font-weight: 400; background: var(--surface-2); color: var(--text); border: 1px solid var(--line); border-radius: 18px; }
#ended .fb-chip.on { background: rgba(138, 180, 248, .16); border-color: var(--info-soft); color: var(--info-soft); }
#fbComment {
  width: 100%; box-sizing: border-box; resize: vertical;
  padding: 10px 12px; font: inherit; font-size: 14px;
  background: var(--surface); color: inherit;
  border: 1px solid var(--line); border-radius: 10px;
}
#fbComment:focus { outline: none; border-color: var(--info-soft); }
#ended #fbSend:disabled { opacity: .45; cursor: default; }
#ended { overflow-y: auto; }
#ended .fb-chip:hover { background: var(--surface-3); }
#ended .fb-stars button:hover { background: var(--surface-2); }

/* call recording: red pill always on screen while anyone records, the
   More-panel toggle turns red, and a card offers the finished file */
#recBadge {
  position: fixed; z-index: 52; left: 50%; transform: translateX(-50%);
  top: calc(14px + env(safe-area-inset-top));
  display: flex; align-items: center; gap: 6px;
  max-width: calc(100vw - 140px); overflow: hidden; white-space: nowrap; text-overflow: ellipsis;
  background: rgba(32, 33, 36, .8); color: var(--text);
  border-radius: var(--radius-pill); padding: 5px 12px 5px 10px;
  font-size: 13px; font-variant-numeric: tabular-nums; pointer-events: none;
}
#recBadge::before {
  content: ''; flex: none; width: 9px; height: 9px; border-radius: 50%;
  background: var(--danger); animation: recPulse 1.6s ease-in-out infinite;
}
@keyframes recPulse { 50% { opacity: .35; } }
.more-item.rec-on, .more-item.rec-on span { color: var(--danger); }
#recReady {
  position: fixed; z-index: 60; left: 50%; transform: translateX(-50%);
  bottom: calc(96px + env(safe-area-inset-bottom));
  width: min(360px, calc(100vw - 32px));
  display: flex; flex-direction: column; gap: 8px;
  background: var(--panel); border: 1px solid var(--line); border-radius: 16px;
  padding: 14px 16px; box-shadow: 0 8px 30px rgba(0,0,0,.6);
}
#recReady h3 { font-size: 15px; font-weight: 600; }
#recReady .hint { font-size: 12px; color: var(--text-dim); word-break: break-all; }
#recReady .rec-actions { display: flex; gap: 8px; flex-wrap: wrap; }
#recReady button {
  flex: 1; min-height: 40px; border: 0; border-radius: var(--radius-pill);
  background: var(--surface-2); color: var(--text); font: inherit; cursor: pointer;
}
#recSave { background: var(--info) !important; color: #fff !important; }

/* end-to-end encrypted room: lobby badge + lock in the call's top bar */
.e2ee-badge {
  display: flex; gap: 10px; align-items: flex-start;
  width: 100%; box-sizing: border-box;
  padding: 10px 12px;
  background: rgba(129, 201, 149, .1);
  border: 1px solid rgba(129, 201, 149, .45); border-radius: 12px;
  text-align: left;
}
.e2ee-badge[hidden] { display: none; }
.e2ee-badge .lock { font-size: 20px; line-height: 1.2; }
.e2ee-badge .t { font-size: 14px; font-weight: 600; color: #81c995; }
.e2ee-badge .s { font-size: 12px; color: var(--text-dim); margin-top: 2px; }
.e2ee-badge .s b { color: var(--text); letter-spacing: .06em; font-variant-numeric: tabular-nums; }
.e2ee-badge.bad { background: rgba(242, 139, 130, .1); border-color: rgba(242, 139, 130, .5); }
.e2ee-badge.bad .t { color: #f28b82; }
.e2ee-top {
  margin-left: 8px; padding: 2px 6px;
  font-size: 14px; line-height: 1;
  background: transparent; border: 0; cursor: pointer;
}
.e2ee-top.bad { filter: grayscale(1); opacity: .6; }
#e2eeInvite { display: flex; flex-direction: column; gap: 8px; }
#e2eeInvite[hidden] { display: none; }
#e2eeInvite button {
  padding: 10px; font-size: 14px;
  background: rgba(129, 201, 149, .14); color: #81c995;
  border: 1px solid rgba(129, 201, 149, .45); border-radius: 10px; cursor: pointer;
}

/* hub: admin "create permanent room" form + encrypted one-off button */
#adminCreate { display: flex; flex-direction: column; gap: 10px; }
#adminCreate[hidden] { display: none; }
#adminCreate .row { flex-direction: column; margin-top: 0; }
#adminCreate .row input[type=text] { color: var(--text); font-size: 16px; }
#hub #adminCreate .row button { background: var(--accent); }
.check { display: flex; align-items: center; gap: 8px; font-size: 14px; color: var(--text-dim); cursor: pointer; }
.check input { width: 18px; height: 18px; accent-color: var(--accent); }
#hub button.secondary {
  background: rgba(129, 201, 149, .14); color: #81c995;
  border: 1px solid rgba(129, 201, 149, .45);
}
.created-link { display: flex; flex-direction: column; gap: 6px; }
.created-link[hidden] { display: none; }
.created-link input {
  width: 100%; box-sizing: border-box;
  padding: 12px 14px; font-size: 14px;
  background: var(--surface); color: #aab;
  border: 1px solid var(--line); border-radius: 10px;
}

/* hub room list: card + per-room actions (key link, delete own room) */
.room-row { display: flex; gap: 8px; align-items: stretch; }
.room-row .room-card { flex: 1; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
#hub .room-row .icon-btn {
  flex: 0 0 48px; padding: 0; font-size: 18px;
  background: var(--surface); border: 1px solid var(--line);
}
#hub .room-row .icon-btn.danger { color: #f28b82; }

/* route check panel: which IPs the server and the peers see */
#routeInfo { display: flex; flex-direction: column; gap: 4px; font-size: 13px; line-height: 1.35; }
.route-line { color: var(--text); overflow-wrap: anywhere; }
.route-line.head { font-weight: 600; padding-bottom: 4px; border-bottom: 1px solid var(--line); margin-bottom: 2px; }
.route-line.peer { font-weight: 600; margin-top: 8px; color: var(--info-soft); }
.route-line.dim { color: var(--text-dim); }
.route-line.warn { color: #fdd663; }
