@font-face {
  font-family: 'Work Sans';
  src: url('/fonts/WorkSans-Regular.woff') format('woff');
  font-weight: 400;
  font-style: normal;
  font-display: swap;
}
@font-face {
  font-family: 'Work Sans';
  src: url('/fonts/WorkSans-Bold.woff') format('woff');
  font-weight: 700;
  font-style: normal;
  font-display: swap;
}

:root {
  --ink: #12213B;
  --ink-2: #1A2E4D;
  --bg: #F3F5F9;
  --panel: #FFFFFF;
  --border: #E2E6ED;
  --text: #1B2430;
  --text-dim: #6B7686;
  --accent: #1FAE8E;
  --accent-dark: #178F75;
  --danger: #E5484D;
  --warn: #F5A623;
  --radius: 10px;
  /* Work Sans is self-hosted (no CDN, works fully offline/air-gapped) and only
     covers Latin glyphs - for Bengali characters the browser automatically
     falls back to the next fonts in this stack, which already include solid
     Bengali coverage on every OS (Windows/macOS/Android/iOS/Linux). */
  --font: 'Work Sans', -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif;
}

* { box-sizing: border-box; }
html, body { height: 100%; }
/* Stops the browser's native "pull down to refresh" gesture from firing on
   mobile Chrome/Safari. Without this, swiping down anywhere near the top of
   the page - including on the full-screen call overlay - reloads the whole
   page, which kills any in-progress call. */
html { overscroll-behavior-y: contain; }
body {
  margin: 0;
  font-family: var(--font);
  background: var(--bg);
  color: var(--text);
  -webkit-font-smoothing: antialiased;
  overscroll-behavior-y: contain;
}
button { font-family: inherit; cursor: pointer; }
input, select, textarea { font-family: inherit; }
a { color: var(--accent-dark); }

/* ---------- Login ---------- */
.login-wrap {
  min-height: 100vh;
  min-height: calc(var(--app-vh, 1vh) * 100);
  min-height: 100dvh;
  /* Grid (not flex) on purpose: with flex + justify-content:center, the
     footer's margin-top:auto below soaks up all the free space to glue
     itself to the bottom, leaving nothing for justify-content to center
     the card with - so the card ends up stuck near the top instead of
     the middle. A 1fr/auto grid gives the card its own row that's
     independently centered, and the footer keeps its own auto-height
     row below it, so the two no longer fight over the same free space. */
  display: grid;
  grid-template-rows: 1fr auto;
  align-items: center;
  justify-items: center;
  background: linear-gradient(160deg, var(--ink) 0%, var(--ink-2) 55%, #0E1930 100%);
  padding: 20px;
  overflow-y: auto; /* safety net: on a very short/zoomed-in window, scroll instead of clipping the footer below the fold */
}
.login-card {
  background: var(--panel);
  width: 100%;
  max-width: 380px;
  border-radius: 16px;
  padding: 36px 32px;
  box-shadow: 0 24px 70px rgba(0,0,0,0.4), 0 2px 8px rgba(0,0,0,0.15);
}
.login-brand {
  display: flex;
  align-items: center;
  gap: 10px;
  margin-bottom: 28px;
}
.login-brand .mark {
  width: 38px; height: 38px; border-radius: 9px;
  background: #000E29;
  display: flex; align-items: center; justify-content: center;
  color: white; font-weight: 700; font-size: 18px;
  overflow: hidden; flex: none;
}
.login-brand .mark img,
.sidebar-header .mark img {
  width: 100%; height: 100%; object-fit: cover; display: block; border-radius: inherit;
}
.login-brand .name { font-weight: 700; font-size: 18px; letter-spacing: -0.01em; }
.login-brand .sub { font-size: 12px; color: var(--text-dim); }
.field { margin-bottom: 16px; }
.field label { display: block; font-size: 13px; font-weight: 600; margin-bottom: 6px; color: var(--text-dim); }
.field input {
  width: 100%; padding: 11px 13px; border: 1.5px solid var(--border);
  border-radius: 9px; font-size: 14px; outline: none; transition: border-color .15s;
}
.field input:focus { border-color: var(--accent); }
.btn-primary {
  width: 100%; padding: 12px; border: none; border-radius: 9px;
  background: var(--accent); color: white; font-weight: 700; font-size: 14px;
  transition: background .15s;
}
.btn-primary:hover { background: var(--accent-dark); }
.login-note {
  margin-top: 18px; font-size: 12px; color: var(--text-dim); line-height: 1.5;
  border-top: 1px solid var(--border); padding-top: 14px;
}
.brand-footer {
  text-align: center; font-size: 11px; color: #7C89A6; letter-spacing: 0.2px;
  padding: 12px 10px; margin-top: auto;
}
.brand-footer.on-light { color: var(--text-dim); }
.brand-footer a { color: inherit; text-decoration: none; }
.brand-footer .made-by { opacity: 0.8; }
.brand-footer .company { font-weight: 700; opacity: 0.95; }
.error-msg {
  background: #FDECEC; color: var(--danger); font-size: 13px;
  padding: 9px 12px; border-radius: 8px; margin-bottom: 14px; display: none;
}

/* ---------- App shell ---------- */
.app {
  display: grid;
  grid-template-columns: 280px 1fr;
  height: 100vh;
  height: calc(var(--app-vh, 1vh) * 100);
  height: 100dvh;
  overflow: hidden;
}
.sidebar {
  background: var(--ink);
  color: #E7ECF6;
  display: flex;
  flex-direction: column;
  min-width: 0;
  min-height: 0;
  position: relative;   /* anchors .sidebar-more-menu popup */
  /* iOS PWA/webview status bar is "black-translucent" (see apple-mobile-
     web-app-status-bar-style in app.html), which draws the app's own
     content underneath the real time/battery/signal status bar instead of
     pushing it down automatically. Without this, the sidebar's own header
     row renders directly under - and visually collides with - the phone's
     status bar. env(safe-area-inset-top) is 0 on devices without a notch/
     status-bar overlay, so this is a no-op everywhere else. */
  padding-top: env(safe-area-inset-top, 0px);
}
.sidebar-header {
  padding: 18px 16px 14px;
  display: flex; align-items: center; gap: 10px;
  border-bottom: 1px solid rgba(255,255,255,0.08);
}
.sidebar-header .mark {
  width: 32px; height: 32px; border-radius: 8px;
  background: #000E29;
  display: flex; align-items: center; justify-content: center; font-weight: 700; color: white;
  overflow: hidden; flex: none;
}
.sidebar-header .title { font-weight: 700; font-size: 15px; }
.sidebar-header .subtitle { font-size: 11px; color: #9AA7C2; }

.me-bar {
  padding: 12px 16px;
  display: flex; align-items: center; gap: 10px;
  border-bottom: 1px solid rgba(255,255,255,0.08);
}
.avatar {
  width: 34px; height: 34px; border-radius: 50%;
  display: flex; align-items: center; justify-content: center;
  color: white; font-weight: 700; font-size: 13px; flex-shrink: 0;
}
/* Small green dot on an avatar for someone who's online right now - used in
   the sidebar chat/staff list (see renderConvList in app.js) so who's
   available is visible at a glance without opening each chat. The border
   matches the sidebar background so the dot reads as "cut into" the avatar
   rather than just sitting on top of it. */
.avatar-online-dot {
  position: absolute; right: -1px; bottom: -1px;
  width: 10px; height: 10px; border-radius: 50%;
  background: #2ecc71; border: 2px solid var(--ink);
  box-sizing: content-box;
}
.me-bar .me-name { font-size: 13px; font-weight: 600; }
.me-bar .me-role { font-size: 11px; color: #9AA7C2; }
.me-bar .icon-btn { margin-left: auto; }

.icon-btn {
  background: transparent; border: none; color: #C6CEE0;
  width: 30px; height: 30px; border-radius: 7px; display: flex;
  align-items: center; justify-content: center; font-size: 15px;
}
.icon-btn:hover { background: rgba(255,255,255,0.08); color: white; }

.tabs {
  display: flex; flex-wrap: nowrap; padding: 7px 8px 6px; gap: 3px;
  border-bottom: 1px solid rgba(255,255,255,0.06);
  overflow-x: auto; -webkit-overflow-scrolling: touch; scrollbar-width: none;
  /* Sidebar is a fixed 280px column even on wide desktop windows, so with
     6+ tabs (Chats/Calls/Meetings/Tasks/Email/Notice, +Admin/Monitor for
     some roles) there isn't room for one row at readable size - keep them
     on ONE line and let the row scroll horizontally instead of wrapping
     to a second row and eating into the conversation list below it. */
}
.tabs::-webkit-scrollbar { display: none; }
/* On touch devices swiping IS the scrollbar, so it stays hidden there (see
   above). A mouse has no swipe gesture though, and with 6+ tabs some were
   simply unreachable with no visible way to scroll to them - show a slim
   scrollbar only for fine-pointer (mouse/trackpad) input as a discoverable
   "slider", and mouse-wheel/drag scrolling is wired up in app.js too. */
@media (hover: hover) and (pointer: fine) {
  .tabs { scrollbar-width: thin; scrollbar-color: rgba(255,255,255,0.28) transparent; cursor: grab; }
  .tabs::-webkit-scrollbar { display: block; height: 5px; }
  .tabs::-webkit-scrollbar-track { background: transparent; }
  .tabs::-webkit-scrollbar-thumb { background: rgba(255,255,255,0.28); border-radius: 3px; }
  .tabs::-webkit-scrollbar-thumb:hover { background: rgba(255,255,255,0.45); }
  .tabs.drag-scrolling { cursor: grabbing; }
}
.tab-btn {
  flex: 0 0 auto; min-width: 50px; display: flex; flex-direction: column; align-items: center;
  gap: 2px; background: transparent; border: none; color: #8996b3;
  padding: 5px 3px 6px; font-size: 9.5px; font-weight: 600; border-radius: 8px;
  transition: background 0.15s, color 0.15s;
}
.tab-btn svg { width: 15px; height: 15px; }
.tab-btn span { white-space: nowrap; overflow: hidden; text-overflow: ellipsis; max-width: 100%; }
.tab-btn:hover { background: rgba(255,255,255,0.06); color: #C6CEE0; }

/* Per-tab icon colors - every tab icon used to render in the same flat
   grey (stroke:currentColor at .tab-btn's own muted grey), so the whole
   sidebar read as plain black-and-white and tabs were hard to tell apart
   at a glance. Coloring only the icon (not .tab-btn's own `color`, which
   the label <span> also inherits) keeps the text labels calm/neutral and
   gives each tab a distinct, professional identity instead. Order matches
   the tab list in app.html. */
.tab-btn[data-tab="chats"] svg { stroke: #2563EB; }
.tab-btn[data-tab="calls"] svg { stroke: #16A34A; }
.tab-btn[data-tab="community"] svg { stroke: #7C3AED; }
.tab-btn[data-tab="meetings"] svg { stroke: #D97706; }
.tab-btn[data-tab="tasks"] svg { stroke: #059669; }
.tab-btn[data-tab="approvals"] svg { stroke: #0891B2; }
.tab-btn[data-tab="email"] svg { stroke: #DC2626; }
.tab-btn[data-tab="notices"] svg { stroke: #EA580C; }
.tab-btn[data-tab="brand"] svg { stroke: #DB2777; }
.tab-btn[data-tab="policies"] svg { stroke: #64748B; }
.tab-btn[data-tab="software"] svg { stroke: #4F46E5; }
.tab-btn[data-tab="hr"] svg { stroke: #0D9488; }
.tab-btn[data-tab="card"] svg { stroke: #9333EA; }
.tab-btn[data-tab="tools"] svg { stroke: #CA8A04; }
.tab-btn[data-tab="admin"] svg { stroke: #B91C1C; }
.tab-btn[data-tab="monitoring"] svg { stroke: #0284C7; }
.tab-btn[data-tab="integrations"] svg { stroke: #65A30D; }

/* The active/selected tab still gets one single strong accent-green
   highlight (same as before) so "you are here" stays instantly obvious,
   regardless of that tab's own color above - same specificity as the
   per-tab rules, so it must come after them to win. */
.tab-btn.active { color: white; background: var(--accent); }
.tab-btn.active svg { stroke: white; }
.tab-badge {
  position: absolute; top: 1px; right: 4px; min-width: 15px; height: 15px;
  padding: 0 3px; border-radius: 999px; background: var(--danger); color: white;
  font-size: 9px; font-weight: 700; line-height: 15px; text-align: center;
  box-shadow: 0 0 0 2px var(--ink);
}

.conv-list { flex: 1; overflow-y: auto; padding: 8px; overscroll-behavior: contain; }
/* Without an explicit scrollbar style here, browsers fall back to the OS's
   default scrollbar - on Windows/Chrome that's a solid white track with
   up/down arrow buttons, which looks jarring against this dark sidebar.
   Match the thin, translucent look already used for .tabs above. */
.conv-list { scrollbar-width: thin; scrollbar-color: rgba(255,255,255,0.28) transparent; }
.conv-list::-webkit-scrollbar { width: 7px; }
.conv-list::-webkit-scrollbar-track { background: transparent; }
.conv-list::-webkit-scrollbar-thumb { background: rgba(255,255,255,0.28); border-radius: 6px; }
.conv-list::-webkit-scrollbar-thumb:hover { background: rgba(255,255,255,0.45); }
.conv-item {
  display: flex; align-items: center; gap: 10px;
  padding: 9px 10px; border-radius: 9px; margin-bottom: 2px;
}
.conv-item:hover { background: rgba(255,255,255,0.06); }
.conv-item.active { background: rgba(31,174,142,0.18); }
.conv-item .conv-name {
  font-size: 13.5px; font-weight: 600; color: #EAEFF9;
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis; display: block;
}
.conv-item .conv-preview {
  font-size: 11.5px; color: #93A0BC; white-space: nowrap; overflow: hidden;
  text-overflow: ellipsis; max-width: 170px;
}
.dot-online {
  width: 8px; height: 8px; border-radius: 50%; background: var(--accent);
  position: relative; left: -12px; top: 11px; border: 2px solid var(--ink);
}
.unread-badge {
  background: var(--accent); color: white; font-size: 10.5px; font-weight: 800;
  min-width: 18px; height: 18px; border-radius: 10px; padding: 0 5px;
  display: flex; align-items: center; justify-content: center; flex-shrink: 0;
}
/* ---- Last-message time (WhatsApp-style: time top-right, unread badge/mute
   icon stacked underneath it) ---- */
.conv-meta {
  display: flex; flex-direction: column; align-items: flex-end; gap: 4px;
  flex-shrink: 0; margin-left: 2px;
}
.conv-time {
  font-size: 10.5px; color: var(--text-dim); white-space: nowrap;
}
.conv-time.unread { color: var(--accent); font-weight: 700; }
.conv-meta-bottom { display: flex; align-items: center; gap: 4px; min-height: 18px; }

.new-chat-btn {
  margin: 10px 12px 14px; padding: 10px; border-radius: 9px;
  background: rgba(255,255,255,0.07); border: 1px dashed rgba(255,255,255,0.2);
  color: #C6CEE0; font-size: 12.5px; font-weight: 600;
}
.new-chat-btn:hover { background: rgba(255,255,255,0.12); }

.side-icon-toolbar {
  display: flex; align-items: center; justify-content: flex-start; gap: 6px;
  padding: 10px 10px 14px; flex-wrap: wrap; flex-shrink: 0;
  border-top: 1px solid rgba(255,255,255,0.08); margin-top: 4px;
}
#sidebarMoreBtn { margin-left: auto; } /* "more" always sits at the far right of the row */
.side-icon-btn {
  width: 38px; height: 38px; border-radius: 50%; flex-shrink: 0;
  background: rgba(255,255,255,0.06); border: 1px solid rgba(255,255,255,0.09);
  color: #C6CEE0; display: flex; align-items: center; justify-content: center;
  transition: background 0.15s, transform 0.1s;
}
.side-icon-btn:hover { background: rgba(255,255,255,0.14); transform: translateY(-1px); }
.side-icon-btn.primary { background: var(--accent); border-color: var(--accent); color: white; }
.side-icon-btn.primary:hover { background: var(--accent-dark, var(--accent)); }
.side-icon-btn.danger { background: rgba(229,72,77,0.16); border-color: rgba(229,72,77,0.45); color: #FF9B9E; }
.side-icon-btn.danger:hover { background: rgba(229,72,77,0.3); }

/* "More" popup for the sidebar footer - houses Starred/Broadcast/Community/
   Linked Devices/My Account so the footer bar itself stays 2 icons tall.
   (Camera/Search/Logout live as regular icons in the row above instead -
   see .side-icon-toolbar - not in this popup.) */
.sidebar-more-menu {
  position: absolute; left: 12px; right: 12px; bottom: 64px; z-index: 45;
  background: #1B2740; border: 1px solid rgba(255,255,255,0.08); border-radius: 14px; padding: 6px;
  box-shadow: 0 8px 28px rgba(0,0,0,0.4);
  flex-direction: column; gap: 2px;
  max-height: 70vh; overflow-y: auto;
}
.sidebar-more-menu button {
  display: flex; align-items: center; gap: 12px; width: 100%;
  background: none; border: none; color: #E7ECF6; font-size: 13.5px;
  padding: 11px 10px; border-radius: 8px; text-align: left;
}
.sidebar-more-menu button:hover, .sidebar-more-menu button:active { background: rgba(255,255,255,0.07); }
.sidebar-more-menu button svg { flex-shrink: 0; opacity: 0.85; }
.sidebar-more-menu button.danger-item { color: #FF9B9E; }
.sidebar-more-menu button.danger-item:hover { background: rgba(229,72,77,0.14); }
.sidebar-more-menu-divider { height: 1px; background: rgba(255,255,255,0.08); margin: 5px 6px; }

.emergency-btn {
  margin: 0 12px 14px; padding: 10px; border-radius: 9px;
  background: rgba(229,72,77,0.15); border: 1px solid rgba(229,72,77,0.4);
  color: #FF9B9E; font-size: 12.5px; font-weight: 700;
}
.emergency-btn:hover { background: rgba(229,72,77,0.28); }

.record-box {
  background: var(--bg); border: 1.5px dashed var(--border); border-radius: 10px;
  min-height: 120px; display: flex; align-items: center; justify-content: center;
  flex-direction: column; gap: 8px; padding: 12px; font-size: 12.5px; color: var(--text-dim);
}
.record-box video { max-width: 100%; max-height: 200px; border-radius: 8px; }

.emergency-overlay {
  position: fixed; inset: 0; background: rgba(18,10,10,0.88); z-index: 300; display: none;
  align-items: center; justify-content: center; padding: 20px;
}
.emergency-overlay.show { display: flex; }
.emergency-card {
  background: white; border-radius: 18px; padding: 32px 28px; max-width: 420px; width: 100%;
  text-align: center; box-shadow: 0 30px 80px rgba(0,0,0,0.5);
}
.emergency-siren { font-size: 44px; margin-bottom: 6px; animation: emg-pulse 1s infinite; }
@keyframes emg-pulse { 0%, 100% { transform: scale(1); } 50% { transform: scale(1.15); } }
.emergency-title { font-size: 18px; font-weight: 800; color: var(--danger); margin-bottom: 4px; }
.emergency-sender { font-size: 13px; font-weight: 600; color: var(--text-dim); margin-bottom: 14px; }
.emergency-body { font-size: 14.5px; line-height: 1.6; margin-bottom: 20px; color: var(--text); white-space: pre-wrap; }
.emergency-body video, .emergency-body audio { max-width: 100%; border-radius: 10px; }
.emergency-card .btn-primary { background: var(--danger); }

/* ---------- Main chat panel ---------- */
.main {
  display: flex; flex-direction: column; min-width: 0; min-height: 0; background: var(--bg);
  /* Same iOS status-bar overlap issue as .sidebar above - every "page"
     rendered inside .main (Chats/Calls/Meetings/Tools/Admin/etc, all of
     which share this .main class) gets pushed clear of the status bar
     instead of its own header row sitting underneath it. */
  padding-top: env(safe-area-inset-top, 0px);
}
.chat-header {
  height: 62px; border-bottom: 1px solid var(--border); background: var(--panel);
  display: flex; align-items: center; padding: 0 20px; gap: 12px; flex-shrink: 0;
}
.chat-header .title { font-weight: 700; font-size: 15px; }
.chat-header .status {
  font-size: 11.5px; color: var(--text-dim);
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
/* A long group name had nowhere to stop growing, so it pushed the
   search/mute/call icons on the right straight off the edge of the
   screen (videoCallBtn - last in line - disappearing first). Let the
   title block shrink/truncate with an ellipsis instead, and keep the
   action icons at their natural size so they're never squeezed out. */
#chatTitleBlock { min-width: 0; flex: 1; overflow: hidden; }
.chat-header .title { white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.chat-header .call-actions { flex-shrink: 0; }
.call-actions { margin-left: auto; display: flex; gap: 8px; }
.call-btn {
  width: 38px; height: 38px; border-radius: 50%; border: 1.5px solid var(--border);
  background: white; display: flex; align-items: center; justify-content: center; font-size: 15px;
}
.call-btn:hover { border-color: var(--accent); color: var(--accent-dark); }
.call-btn.hangup { background: var(--danger); border-color: var(--danger); color: white; }

.messages {
  flex: 1; overflow-y: auto; padding: 20px 24px; display: flex; flex-direction: column; gap: 4px;
  /* Without this, a flex child's default min-height is its CONTENT size
     (min-content), not 0 - so once a chat's message history got long
     enough, .messages refused to shrink to fit the space flex:1 gave it
     and instead grew past it, pushing the whole .main column taller than
     the viewport. The header (flex-shrink:0, first in that column) got
     dragged out of view along with it - it wasn't actually hidden, the
     entire chat panel had scrolled past it. Pinning min-height to 0 lets
     .messages correctly stop at its allotted space and scroll its own
     content internally instead, so the header now always stays put. */
  min-height: 0;
}
.empty-state {
  margin: auto; text-align: center; color: var(--text-dim); max-width: 320px;
}
.empty-state .big { font-size: 40px; margin-bottom: 10px; }
/* Only the Chats panel's empty-state gets the wider quick-nav tile grid -
   every other .empty-state usage (calls list, tasks, notices, HR panels,
   etc.) keeps the narrow 320px default above untouched. */
.chats-empty-state {
  max-width: 460px;
  /* .empty-state centers itself with `margin:auto` inside .messages'
     flex column. An auto side-margin makes a flex item size to its own
     content (fit-content) instead of taking a definite width from the
     container - and a `grid-template-columns: repeat(auto-fill, ...)`
     grid needs a DEFINITE container width to know how many tracks fit.
     Without one, auto-fill has no width to divide up and falls back to
     a single 1fr track, which is exactly why the quick-nav tiles were
     collapsing into one full-width column on every screen size instead
     of wrapping responsively. Giving it an explicit width (still capped
     by max-width above, and still centered by the inherited auto side
     margins) restores a definite width for the grid to size against. */
  width: 100%;
}
.chats-empty-state .tools-grid { grid-template-columns: repeat(auto-fill, minmax(92px, 1fr)); }
.chats-empty-state .tools-subtab-btn svg { width: 26px; height: 26px; }

.msg-row { display: flex; gap: 10px; max-width: 62%; margin-bottom: 10px; }
.msg-row.mine { margin-left: auto; flex-direction: row-reverse; }
.msg-row .avatar { width: 28px; height: 28px; font-size: 11px; margin-top: 2px; }
.msg-bubble-wrap { display: flex; flex-direction: column; gap: 2px; }
.msg-sender { font-size: 11.5px; font-weight: 700; color: var(--text-dim); }
.msg-row.mine .msg-sender { text-align: right; }
.msg-bubble {
  background: var(--panel); border: 1px solid var(--border); border-radius: 14px;
  padding: 9px 13px; font-size: 14px; line-height: 1.45; white-space: pre-wrap; word-break: break-word;
}
.msg-row.mine .msg-bubble { background: #D9FDD3; color: #111B21; border-color: #BEEFB2; }
.msg-time { font-size: 10.5px; color: var(--text-dim); margin-top: 1px; }
.msg-row.mine .msg-time { text-align: right; }
.tick-wrap { display: inline-flex; vertical-align: -2px; margin-left: 3px; }

.emergency-msg .msg-bubble {
  border: 1.5px solid var(--danger) !important;
  background: #FDECEC !important;
  color: var(--text) !important;
}
.emergency-msg .msg-sender { color: var(--danger); }
.emergency-msg .msg-sender::before { content: "🚨 "; }

.file-bubble {
  display: flex; align-items: center; gap: 10px; padding: 10px 12px; cursor: pointer;
}
.file-bubble .file-name { font-size: 13px; font-weight: 600; }
.file-bubble .file-size { font-size: 11px; opacity: 0.75; }

.media-bubble { padding: 0; overflow: hidden; }
.media-trigger {
  display: flex; align-items: center; gap: 10px; padding: 10px 12px; cursor: pointer; min-width: 220px;
}
.media-play-btn {
  width: 34px; height: 34px; border-radius: 50%; background: rgba(18,33,59,0.75);
  display: flex; align-items: center; justify-content: center; flex-shrink: 0;
}
.media-meta .file-name { font-size: 13px; font-weight: 600; }
.media-meta .file-size { font-size: 11px; opacity: 0.75; }
.media-loading { font-size: 12.5px; color: var(--text-dim); padding: 4px 0; }

.photo-bubble { padding: 0; overflow: hidden; cursor: pointer; width: 240px; max-width: 100%; }
.photo-bubble img { display: block; width: 100%; max-height: 320px; object-fit: cover; }
.photo-bubble .photo-loading { padding: 60px 12px; text-align: center; color: var(--text-dim); font-size: 12.5px; background: var(--bg); width: 240px; max-width: 100%; box-sizing: border-box; }

/* ---------- Photo viewer ---------- */
.photo-viewer-overlay {
  position: fixed; inset: 0; background: #000; z-index: 160; display: none;
  flex-direction: column;
}
.photo-viewer-overlay.show { display: flex; }
.pv-topbar {
  display: flex; align-items: center; justify-content: space-between; gap: 10px;
  padding: 14px 16px; color: #fff; flex-shrink: 0;
}
.pv-icon-btn {
  width: 34px; height: 34px; border-radius: 50%; border: none; background: rgba(255,255,255,0.12);
  color: #fff; display: flex; align-items: center; justify-content: center; flex-shrink: 0;
}
.pv-icon-btn:hover { background: rgba(255,255,255,0.22); }
.pv-meta { text-align: center; min-width: 0; }
.pv-sender { font-size: 13.5px; font-weight: 700; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.pv-date { font-size: 11.5px; opacity: 0.75; }
.pv-stage {
  flex: 1; overflow: hidden; display: flex; align-items: center; justify-content: center;
  touch-action: none; position: relative; cursor: grab;
}
.pv-stage.grabbing { cursor: grabbing; }
.pv-stage img {
  max-width: 92%; max-height: 88%; object-fit: contain; user-select: none;
  transition: transform 0.08s linear;
  will-change: transform;
}
.pv-actionbar {
  /* justify-content: center (was default stretch) - previously each
     .pv-action grew with flex:1 to fill the whole bar's width, which is
     what spread the icons far apart from each other even though the gap
     value itself was small. Centering + flex: 0 0 auto below lets the
     buttons sit right next to each other instead of being stretched. */
  display: flex; gap: 2px; padding: 10px 8px; overflow-x: auto; flex-shrink: 0;
  background: rgba(255,255,255,0.04); justify-content: center;
}
.pv-action {
  flex: 0 0 auto; min-width: 58px; display: flex; flex-direction: column; align-items: center; gap: 4px;
  background: none; border: none; color: #fff; padding: 8px 6px; border-radius: 10px; font-size: 10.5px;
}
.pv-action:hover { background: rgba(255,255,255,0.12); }
.pv-edit-toolbar {
  display: flex; gap: 8px; align-items: center; justify-content: center; padding: 10px 12px;
  background: rgba(255,255,255,0.06); flex-shrink: 0;
}
.pv-edit-btn {
  border: none; background: rgba(255,255,255,0.12); color: #fff; padding: 9px 14px;
  border-radius: 9px; font-size: 12.5px; font-weight: 600; display: flex; align-items: center; gap: 6px;
}
.pv-edit-btn:hover { background: rgba(255,255,255,0.22); }
.pv-edit-btn.pv-edit-save { background: var(--accent, #1FAE8E); }
.pv-edit-btn.pv-edit-cancel { background: transparent; opacity: 0.8; }
.pv-edit-btn.pv-edit-crop.active { background: var(--accent, #1FAE8E); }

/* Crop box overlay - draggable/resizable rectangle shown over the photo
   while cropping. The oversized box-shadow darkens everything outside the
   box; .pv-stage's overflow:hidden clips it to the stage. */
.pv-crop-box {
  position: absolute; border: 1.5px solid #fff; box-shadow: 0 0 0 9999px rgba(0,0,0,0.55);
  cursor: move; touch-action: none; box-sizing: border-box;
}
.pv-crop-handle {
  position: absolute; width: 18px; height: 18px; background: #fff; border-radius: 50%;
  box-shadow: 0 0 0 2px rgba(0,0,0,0.45); touch-action: none;
}
.pv-crop-handle-nw { top: -9px; left: -9px; cursor: nwse-resize; }
.pv-crop-handle-ne { top: -9px; right: -9px; cursor: nesw-resize; }
.pv-crop-handle-sw { bottom: -9px; left: -9px; cursor: nesw-resize; }
.pv-crop-handle-se { bottom: -9px; right: -9px; cursor: nwse-resize; }

.messages.has-wallpaper { background-size: cover; background-position: center; background-repeat: no-repeat; }

.offline-empty-state {
  margin: auto;
  max-width: 320px;
  text-align: center;
  color: var(--text-secondary, #667781);
  font-size: 14px;
  padding: 16px 20px;
  background: var(--bg-secondary, rgba(255,255,255,0.9));
  border-radius: 10px;
}

.composer {
  border-top: 1px solid var(--border); background: var(--panel);
  padding: 10px 10px; display: flex; align-items: flex-end; gap: 6px; flex-shrink: 0;
  padding-bottom: calc(10px + env(safe-area-inset-bottom, 0px));
}
.composer textarea {
  flex: 1; border: 1.5px solid var(--border); border-radius: 12px; padding: 10px 14px;
  font-size: 14px; resize: none; max-height: 140px; outline: none; min-width: 0;
}
.composer textarea:focus { border-color: var(--accent); }
.composer .send-btn, .composer .attach-btn {
  width: 36px; height: 36px; border-radius: 50%; border: none; flex-shrink: 0;
  display: flex; align-items: center; justify-content: center; font-size: 15px;
}
.composer .send-btn { background: var(--accent); color: white; }
.composer .attach-btn { background: var(--bg); border: 1.5px solid var(--border); color: var(--text-dim); }

/* ---------- Modal ---------- */
.modal-overlay {
  position: fixed; inset: 0; background: rgba(10,16,30,0.55);
  display: none; align-items: center; justify-content: center; z-index: 120; padding: 16px;
  /* Must render above .call-overlay (z-index 100 full-screen / 90 minimized) -
     otherwise any modal opened during an active call (file-send preview,
     guest invite links, task/poll creation, etc.) silently renders behind
     the call and looks like it "didn't open" even though it did. */
}
.modal-overlay.show { display: flex; }
.modal {
  background: white; border-radius: 14px; width: 100%; max-width: 440px;
  max-height: 86vh; overflow-y: auto; padding: 22px;
}
.modal h3 { margin: 0 0 16px; font-size: 16px; }
.modal .close-x {
  float: right; background: none; border: none; color: var(--text-dim);
  display: inline-flex; align-items: center; justify-content: center;
  width: 26px; height: 26px; border-radius: 7px;
}
.modal .close-x:hover { background: var(--bg); color: var(--text); }
.file-badge {
  width: 36px; height: 36px; border-radius: 9px; flex-shrink: 0;
  display: flex; align-items: center; justify-content: center;
  color: white; font-weight: 800; font-size: 9.5px; letter-spacing: 0.3px;
}
.people-list {
  max-height: 320px; overflow-y: auto; border: 1px solid var(--border); border-radius: 9px; margin-bottom: 14px;
  overscroll-behavior: contain; -webkit-overflow-scrolling: touch;
}
.people-row { display: flex; align-items: center; gap: 10px; padding: 9px 12px; border-bottom: 1px solid var(--border); font-size: 13.5px; }
.people-row:last-child { border-bottom: none; }
.people-row input[type=checkbox] { margin-left: auto; width: 16px; height: 16px; }

.modal-tabs { display: flex; gap: 6px; margin-bottom: 16px; background: var(--bg); border-radius: 9px; padding: 4px; }
.modal-tab-btn {
  flex: 1; border: none; background: transparent; padding: 8px; border-radius: 7px;
  font-size: 12.5px; font-weight: 600; color: var(--text-dim);
}
.modal-tab-btn.active { background: white; color: var(--text); box-shadow: 0 1px 3px rgba(0,0,0,0.08); }

.chat-media-modal { max-width: 480px; }
.chat-media-body { max-height: 60vh; overflow-y: auto; overscroll-behavior: contain; -webkit-overflow-scrolling: touch; }
.cm-media-grid { display: grid; grid-template-columns: repeat(3, 1fr); gap: 8px; }
.cm-media-tile {
  display: flex; flex-direction: column; align-items: center; justify-content: center; gap: 6px;
  background: var(--bg); border-radius: 10px; padding: 14px 6px; cursor: pointer; text-align: center;
}
.cm-media-tile:hover { background: var(--border); }
.cm-media-tile .file-badge { width: 34px; height: 34px; font-size: 9px; }
.cm-media-tile .cm-tile-name { font-size: 10.5px; color: var(--text-dim); max-width: 100%; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.cm-list-row {
  display: flex; align-items: center; gap: 10px; padding: 10px 6px; border-bottom: 1px solid var(--border);
  cursor: pointer;
}
.cm-list-row:last-child { border-bottom: none; }
.cm-list-row:hover { background: var(--bg); }
.cm-row-meta { flex: 1; min-width: 0; }
.cm-row-name { font-size: 13px; font-weight: 600; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.cm-row-sub { font-size: 11.5px; color: var(--text-dim); }
.cm-link-icon {
  width: 36px; height: 36px; border-radius: 9px; flex-shrink: 0; background: var(--bg);
  display: flex; align-items: center; justify-content: center; color: var(--primary, #4f6ef7);
}
.cm-empty { padding: 30px 10px; text-align: center; color: var(--text-dim); font-size: 13px; }

.avatar-preview {
  width: 56px; height: 56px; border-radius: 50%; flex-shrink: 0;
  background: var(--bg); border: 1.5px dashed var(--border);
  display: flex; align-items: center; justify-content: center; color: var(--text-dim); overflow: hidden;
}
.avatar-preview img { width: 100%; height: 100%; object-fit: cover; }
/* Same idea as .avatar-preview but a rounded square, not a circle - company
   logos are usually wide/rectangular marks and a circular crop cuts them off. */
.logo-preview {
  width: 56px; height: 56px; border-radius: 10px; flex-shrink: 0;
  background: var(--bg); border: 1.5px dashed var(--border);
  display: flex; align-items: center; justify-content: center; color: var(--text-dim); overflow: hidden;
}
.logo-preview img { width: 100%; height: 100%; object-fit: contain; }
.unit-logo-thumb {
  width: 34px; height: 34px; border-radius: 8px; object-fit: contain;
  background: var(--bg); border: 1px solid var(--border);
}
.btn-secondary-sm {
  display: inline-block; padding: 6px 12px; border-radius: 7px; border: 1.5px solid var(--border);
  background: white; font-size: 12px; font-weight: 600; color: var(--text); cursor: pointer;
}
.btn-secondary-sm:hover { border-color: var(--accent); color: var(--accent-dark); }
.avatar-img { width: 100%; height: 100%; object-fit: cover; border-radius: 50%; }
.people-row .contact-line { font-size: 11px; color: var(--text-dim); }

/* ---------- Company Software directory ---------- */
.software-grid {
  display: grid; grid-template-columns: repeat(auto-fill, minmax(200px, 1fr)); gap: 12px;
}
.software-card {
  position: relative; display: flex; flex-direction: column; align-items: center; text-align: center; gap: 8px;
  padding: 16px 12px; border-radius: 12px; border: 1.5px solid var(--border); background: white; cursor: pointer;
}
.software-card:hover { border-color: var(--accent); }
.software-card .software-logo {
  width: 56px; height: 56px; border-radius: 10px; object-fit: contain;
  background: var(--bg); border: 1px solid var(--border);
}
.software-card .software-name { font-size: 13.5px; font-weight: 600; color: var(--text); }
.software-card .software-units { display: flex; flex-wrap: wrap; gap: 4px; justify-content: center; }
.software-card .software-admin-actions {
  position: absolute; top: 6px; right: 6px; display: flex; gap: 4px;
}

/* ---------- Visiting Card ---------- */
.visiting-card-wrap {
  display: flex; align-items: center; justify-content: center;
  background: var(--bg); border: 1.5px solid var(--border); border-radius: 14px;
  min-height: 220px; padding: 16px;
}
.visiting-card-loading { font-size: 13px; color: var(--text-dim); }
.visiting-card-img { max-width: 100%; border-radius: 10px; box-shadow: 0 4px 18px rgba(18,33,59,0.14); }
.visiting-card-actions { display: flex; gap: 10px; flex-wrap: wrap; margin-top: 14px; }

/* ---------- Call overlay ---------- */
.call-overlay {
  position: fixed; inset: 0; background: #0B1424; z-index: 100; display: none;
  flex-direction: column;
  transition: all 0.2s ease;
  overflow: hidden; /* never let video tiles push the control bar off-screen */
  overscroll-behavior: none; touch-action: pan-x pan-y; /* belt-and-braces against pull-to-refresh while a call is up, on top of the html/body rule above */
  /* height:100dvh (where supported) instead of relying purely on inset:0's
     computed height - on some mobile browsers the address/toolbar chrome
     showing/hiding around a "ringing"/offline call could leave the fixed
     overlay's layout box shorter than the real visible screen, which let
     .call-controls (see below) end up stranded high up with a big empty
     gap underneath it instead of pinned to the true bottom of the screen. */
  height: 100vh; height: 100dvh;
}
.call-overlay.show { display: flex; }
.call-overlay.minimized {
  inset: auto; top: 74px; right: 14px; width: 200px; height: 130px;
  border-radius: 14px; overflow: hidden; z-index: 90;
  box-shadow: 0 8px 28px rgba(0,0,0,0.4); cursor: grab;
  /* Own drag handling (initMinimizedCallDrag in app.js) needs full control
     of touch gestures on this little window - without this, touch drags
     get eaten by the browser's own scroll/pan gesture instead. */
  touch-action: none;
}
.call-overlay.minimized:active { cursor: grabbing; }
.call-overlay.minimized .call-videos { padding: 0; gap: 2px; }
.call-overlay.minimized .video-tile { min-height: 0; border-radius: 0; }
.call-overlay.minimized .call-recording-banner { display: none !important; }
.call-overlay.minimized .call-controls { display: none; }
.call-overlay.minimized .call-more-menu { display: none !important; }
.call-overlay.minimized .mini-hangup {
  display: flex; position: absolute; bottom: 6px; right: 6px; z-index: 2;
}
.mini-hangup {
  display: none;
  width: 30px; height: 30px; border-radius: 50%; border: none; font-size: 13px;
  background: var(--danger); color: white; align-items: center; justify-content: center;
}
.call-add-btn {
  position: absolute; top: 14px; right: 14px; z-index: 6;
  width: 38px; height: 38px; border-radius: 50%; border: none;
  background: rgba(255,255,255,0.14); color: white; display: flex; align-items: center; justify-content: center;
}
.call-add-btn:hover { background: rgba(255,255,255,0.24); }
.call-overlay.minimized .call-add-btn { display: none; } /* only in the full-screen call view, like WhatsApp */
.call-switch-cam-btn {
  position: absolute; top: 62px; right: 14px; z-index: 6;
  width: 38px; height: 38px; border-radius: 50%; border: none;
  background: rgba(255,255,255,0.14); color: white; display: flex; align-items: center; justify-content: center;
}
.call-switch-cam-btn:hover { background: rgba(255,255,255,0.24); }
.call-overlay.minimized .call-switch-cam-btn { display: none !important; } /* only in the full-screen call view */
.call-videos {
  flex: 1; display: grid; grid-template-columns: repeat(auto-fit, minmax(220px, 1fr));
  /* Rows share the available height equally instead of shrink-wrapping to
     each tile's min-height - without this, a call with just 1-3 people left
     the tiles sitting small at their minimum size with dead empty space
     below them instead of growing to fill the screen. */
  grid-auto-rows: 1fr;
  gap: 8px; padding: 12px;
  min-height: 0;     /* allow the grid to shrink instead of forcing the overlay to overflow */
  overflow-y: auto;  /* extra participants scroll here instead of hiding the control bar */
  align-content: stretch;
}
.call-videos video {
  width: 100%; height: 100%; object-fit: cover; border-radius: 12px; background: #10192B;
}
.video-tile { position: relative; min-height: 160px; display: flex; }
.video-tile video { flex: 1; min-height: 0; }
.video-tile.screen-tile { grid-column: 1 / -1; min-height: 320px; background: #10192B; }
.video-tile.screen-tile video { object-fit: contain; }
.video-tile .name-tag {
  position: absolute; bottom: 8px; left: 8px; background: rgba(0,0,0,0.5);
  color: white; font-size: 11px; padding: 3px 8px; border-radius: 6px;
}
.call-controls {
  display: flex; flex-direction: column; align-items: center; gap: 14px; padding: 18px 12px;
  flex-shrink: 0;        /* always keep full size - never get squeezed out by the video grid */
  /* Belt-and-braces WhatsApp-style bottom pinning: even if a sibling above
     (audio-call-info / call-videos) somehow doesn't fill the remaining
     flex space, margin-top:auto still forces this bar all the way down to
     the bottom of the call screen rather than floating up under the
     status banner. */
  margin-top: auto;
  width: 100%;
}
.call-controls-row {
  display: flex; justify-content: center; gap: 22px; flex-wrap: wrap; row-gap: 14px; width: 100%;
}
.call-btn-wrap {
  display: flex; flex-direction: column; align-items: center; gap: 6px; width: 60px;
}
.call-btn-label {
  font-size: 11.5px; color: rgba(255,255,255,0.85); text-align: center; line-height: 1.15;
}
.call-controls button {
  width: 52px; height: 52px; border-radius: 50%; border: none; font-size: 18px;
  background: #1E2A42; color: white; display: flex; align-items: center; justify-content: center;
  flex-shrink: 0;
}
.call-controls button.hangup { background: var(--danger); }
.call-controls button.active-off { background: var(--warn); color: #1B1B1B; }

/* "More" popup - houses message/emoji/record/invite/minimize so the main
   call bar stays a clean, WhatsApp-style 2 rows of 3 labeled buttons. */
.call-more-menu {
  position: absolute; left: 12px; right: 12px; bottom: 110px; z-index: 5;
  background: #17233A; border-radius: 14px; padding: 6px;
  box-shadow: 0 8px 28px rgba(0,0,0,0.4);
  flex-direction: column; gap: 2px;
}
.call-more-menu button {
  display: flex; align-items: center; gap: 12px; width: 100%;
  background: none; border: none; color: white; font-size: 14px;
  padding: 12px 10px; border-radius: 8px; text-align: left;
}
.call-more-menu button:hover, .call-more-menu button:active { background: rgba(255,255,255,0.06); }
.call-more-menu button svg { flex-shrink: 0; }

/* Audio-only call: hide the (empty/black) video grid but keep it in the DOM
   so remote/local <video> elements keep playing audio, and show a
   WhatsApp-style avatar + name + timer instead. */
.call-overlay.audio-mode .call-videos {
  position: absolute; width: 1px; height: 1px; overflow: hidden;
  opacity: 0; pointer-events: none;
}
.audio-call-info {
  display: none; flex: 1; flex-direction: column; align-items: center; justify-content: center; gap: 10px;
  color: white; text-align: center;
}
.call-overlay.audio-mode .audio-call-info { display: flex; }
/* WhatsApp-style: the other person's (bigger) circle and your own (smaller,
   overlapping bottom-right) circle shown together while an audio call is
   ringing/connected, instead of only the other person's avatar alone. */
.audio-call-avatars { position: relative; display: inline-block; }
.audio-call-avatar {
  width: 120px; height: 120px; border-radius: 50%; overflow: hidden;
  display: flex; align-items: center; justify-content: center; background: #1E2A42;
}
.audio-call-avatar img { width: 100%; height: 100%; object-fit: cover; }
.audio-call-avatar .avatar-fallback {
  width: 100%; height: 100%; border-radius: 50%; display: flex; align-items: center;
  justify-content: center; font-size: 34px; color: white;
}
.audio-call-avatar-self {
  position: absolute; right: -8px; bottom: -8px;
  width: 52px; height: 52px; border: 3px solid #0B1424; box-shadow: 0 2px 8px rgba(0,0,0,0.4);
}
.audio-call-avatar-self .avatar-fallback { font-size: 16px; }
.audio-call-name { font-size: 19px; font-weight: 600; }
.audio-call-timer { font-size: 13.5px; color: var(--text-dim); }

/* Video-call duration badge (see #callDurationBadge in app.html) - a video
   call has no avatar-centered timer like audio-mode does (the video grid
   fills that space instead), so this floats a small pill at the top of the
   screen instead. Hidden by default/in audio-mode (that flow already shows
   its own bigger timer via .audio-call-timer above) and whenever the call
   overlay itself isn't showing, so it can't flash stale "00:00" before a
   call actually starts or linger after one ends.
   Gated on .connected (added by startCallTimer(), removed by
   stopCallTimer() - see app.js), NOT just .show, because it shares the
   exact same top-center position as .call-status-banner below - while a
   video call is still dialing/ringing, .call-status-banner is the one
   showing "কল করা হচ্ছে..."/"Ringing...", and this badge rendering at the
   same time (as it did before .connected existed - it only checked
   .show:not(.audio-mode), true from the moment dialing starts) drew a
   "00:00" pill directly on top of that text, both fighting for the same
   spot. */
.call-duration-badge {
  display: none; position: absolute; top: 14px; left: 50%; transform: translateX(-50%);
  background: rgba(0,0,0,0.45); color: #fff; font-size: 12.5px; font-weight: 600;
  letter-spacing: 0.3px; padding: 5px 13px; border-radius: 20px; z-index: 5; pointer-events: none;
}
.call-overlay.show.connected:not(.audio-mode) .call-duration-badge { display: block; }
.call-overlay.minimized .call-duration-badge { top: 4px; font-size: 10px; padding: 3px 8px; }

/* Lock badge shown once the call's E2EE key handshake has completed - see
   #e2eeBadge in app.html and CallEngine.on('e2eeStatus', ...) in app.js.
   Sits just under the duration badge/status banner rather than fighting
   them for the same top-center spot. */
.e2ee-badge {
  position: absolute; top: 46px; left: 50%; transform: translateX(-50%);
  background: rgba(20,120,60,0.55); color: #fff; font-size: 11.5px; font-weight: 600;
  letter-spacing: 0.2px; padding: 4px 12px; border-radius: 20px; z-index: 5; pointer-events: none;
}
.call-overlay.minimized .e2ee-badge { display: none; }

/* Safety-number modal - see #safetyNumberModal in app.html */
.safety-number-digits {
  font-family: 'Courier New', monospace; font-size: 17px; font-weight: 700;
  letter-spacing: 1.5px; text-align: center; line-height: 1.9;
  background: rgba(20,120,60,0.08); border: 1px solid rgba(20,120,60,0.25);
  border-radius: 10px; padding: 14px 10px; word-spacing: 6px;
  white-space: pre-line;
}

/* Minimized (PIP) call bar during an audio call: the full-screen avatar
   sizing (120px) doesn't fit the small 200x130 minimized box - it was
   overflowing and getting clipped by the box's overflow:hidden, so the
   caller/receiver photo effectively never showed while minimized. This
   scales everything down to actually fit, WhatsApp-style compact bar. */
.call-overlay.minimized .audio-call-info { gap: 2px; padding: 4px; }
.call-overlay.minimized .audio-call-avatar { width: 46px; height: 46px; }
.call-overlay.minimized .audio-call-avatar .avatar-fallback { font-size: 15px; }
.call-overlay.minimized .audio-call-avatar-self {
  width: 20px; height: 20px; right: -4px; bottom: -4px; border-width: 2px;
}
.call-overlay.minimized .audio-call-avatar-self .avatar-fallback { font-size: 8px; }
.call-overlay.minimized .audio-call-name { font-size: 11.5px; max-width: 180px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.call-overlay.minimized .audio-call-timer { font-size: 10px; }

/* Quick emoji reactions during a call */
.call-emoji-picker {
  position: fixed; bottom: 96px; left: 50%; transform: translateX(-50%);
  background: var(--panel); border-radius: 14px; padding: 8px 10px;
  box-shadow: 0 8px 28px rgba(0,0,0,0.35); z-index: 101; gap: 6px;
}
.call-emoji-picker button {
  border: none; background: transparent; font-size: 22px; padding: 4px 6px; cursor: pointer;
}
.call-overlay.minimized ~ .call-emoji-picker { display: none !important; }

.incoming-call-toast {
  position: fixed; bottom: 20px; right: 20px; background: var(--panel); border-radius: 14px;
  box-shadow: 0 12px 32px rgba(0,0,0,0.2); padding: 16px; width: 280px; z-index: 90; display: none;
}
.incoming-call-toast.show { display: block; }
.incoming-call-toast .row { display: flex; gap: 10px; }
.incoming-call-toast .actions { display: flex; gap: 8px; margin-top: 12px; }
.incoming-call-toast button {
  flex: 1; padding: 8px; border-radius: 8px; border: none; font-weight: 700; font-size: 13px;
}
.incoming-call-toast .accept { background: var(--accent); color: white; }
.incoming-call-toast .decline { background: #F2F3F6; color: var(--text); }

/* New-message alert toast - same corner/shape language as the incoming-call
   toast, but no action buttons (tapping it just opens the chat) and a
   lower z-index than call UI (90/100/110), since an incoming call should
   still win visually if both happen to land at once. */
.message-alert-toast {
  position: fixed; bottom: 20px; right: 20px; background: var(--panel); border-radius: 14px;
  box-shadow: 0 12px 32px rgba(0,0,0,0.2); padding: 14px; width: 280px; z-index: 80; display: none;
  cursor: pointer; border: 1.5px solid var(--border);
}
.message-alert-toast.show { display: block; }
.message-alert-toast .row { display: flex; gap: 10px; align-items: center; }

/* Call-waiting banner - same visual language as incoming-call-toast but
   smaller/quieter, and z-index 110 so it renders ABOVE .call-overlay
   (z-index 100) since it needs to show up while a call is already active. */
.call-waiting-toast {
  position: fixed; top: 20px; left: 50%; transform: translateX(-50%); background: var(--panel);
  border-radius: 14px; box-shadow: 0 12px 32px rgba(0,0,0,0.28); padding: 12px 14px; width: 260px;
  z-index: 110; display: none; border: 1.5px solid var(--accent);
}
.call-waiting-toast.show { display: block; }
.call-waiting-toast .row { display: flex; gap: 9px; align-items: center; }
.call-waiting-toast .actions { display: flex; gap: 7px; margin-top: 10px; }
.call-waiting-toast button {
  flex: 1; padding: 7px; border-radius: 8px; border: none; font-weight: 700; font-size: 12px;
}
.call-waiting-toast .accept { background: var(--accent); color: white; }
.call-waiting-toast .decline { background: #F2F3F6; color: var(--text); }

/* ---------- Admin panel ---------- */
.admin-view { padding: 24px 28px; overflow-y: auto; flex: 1; }
.admin-header { display: flex; align-items: center; margin-bottom: 18px; gap: 12px; }
.admin-header h2 { margin: 0; font-size: 18px; }
.admin-header .btn-primary { width: auto; padding: 9px 16px; margin-left: auto; }
.admin-search-input {
  width: 100%; max-width: 360px; padding: 9px 14px; margin-bottom: 14px;
  border: 1.5px solid var(--border); border-radius: 9px; font-size: 13px; font-family: inherit;
}
.admin-search-input:focus { outline: none; border-color: var(--accent); }
.calls-section-title { font-size: 12px; font-weight: 700; color: var(--text-dim); text-transform: uppercase; margin: 18px 0 8px; }
table.admin-table { width: 100%; border-collapse: collapse; background: var(--panel); border-radius: 10px; overflow: hidden; }
table.admin-table th, table.admin-table td {
  text-align: left; padding: 10px 14px; font-size: 13px; border-bottom: 1px solid var(--border);
}
table.admin-table th { background: #F7F9FC; color: var(--text-dim); font-weight: 700; font-size: 11.5px; text-transform: uppercase; }
/* Lets a wide table (mainly the staff table's action column, which packs
   in ~11 buttons - see .admin-actions-cell below) scroll horizontally on
   narrower screens instead of squeezing every column to fit, which was
   crushing the action buttons into an unreadable, overlapping pile. */
.table-scroll { overflow-x: auto; -webkit-overflow-scrolling: touch; border-radius: 10px; }
.table-scroll table.admin-table { border-radius: 0; }
/* The staff table's একশন (Action) column - every per-user action
   (edit/unit/enable-disable/reset password/2FA/delete/etc, ~11 buttons)
   lives in this one cell. Was a plain <td> relying only on each button's
   own `margin-right: 4px` for spacing, with no wrap-friendly layout - on
   any but a very wide screen the buttons ran into the next column and
   into each other with no vertical gap between wrapped lines, looking
   cramped/overlapping (worst right after creating a user, since that's
   when this column is first actually seen). flex-wrap here gives every
   button consistent breathing room on both axes and a comfortable minimum
   width for this cell to expand into (the .table-scroll wrapper above lets
   the table grow past the viewport for this rather than squeezing it back
   down again). */
.admin-actions-cell {
  display: flex; flex-wrap: wrap; gap: 6px; align-items: center;
  min-width: 360px; padding-top: 8px; padding-bottom: 8px;
}
.admin-actions-cell .small-btn { margin-right: 0; white-space: nowrap; }
.badge { padding: 3px 9px; border-radius: 20px; font-size: 11px; font-weight: 700; }
.badge.active { background: #E6F7F1; color: var(--accent-dark); }
.badge.inactive { background: #FDECEC; color: var(--danger); }
.badge.admin { background: #EDEBFB; color: #6C4FD9; }
.badge.broadcast { background: #FDECEC; color: var(--danger); }
.badge.stale { background: #F1F2F4; color: var(--text-dim); }

/* ---- Monitoring dashboard ---- */
.mon-stats-grid {
  display: grid; grid-template-columns: repeat(auto-fit, minmax(140px, 1fr)); gap: 12px;
}
.mon-stat-card {
  background: var(--panel); border: 1px solid var(--border); border-radius: 12px; padding: 14px 16px;
}
.mon-stat-card .mon-stat-value { font-size: 22px; font-weight: 800; color: var(--text); }
.mon-stat-card .mon-stat-label { font-size: 11.5px; color: var(--text-dim); margin-top: 2px; }
.mon-active-calls { display: flex; flex-direction: column; gap: 10px; }
.mon-call-card {
  background: var(--panel); border: 1px solid var(--border); border-radius: 12px;
  padding: 12px 16px; display: flex; align-items: center; gap: 12px; flex-wrap: wrap;
}
.mon-live-dot {
  width: 8px; height: 8px; border-radius: 50%; background: var(--danger); flex-shrink: 0;
  box-shadow: 0 0 0 rgba(224,63,63,0.4); animation: monPulse 1.6s infinite;
}
@keyframes monPulse {
  0% { box-shadow: 0 0 0 0 rgba(224,63,63,0.4); }
  70% { box-shadow: 0 0 0 7px rgba(224,63,63,0); }
  100% { box-shadow: 0 0 0 0 rgba(224,63,63,0); }
}
.mon-call-type { font-size: 12px; font-weight: 700; color: var(--text-dim); }
.mon-call-participants { font-size: 13.5px; font-weight: 600; color: var(--text); flex: 1; min-width: 160px; }
.mon-call-time { font-size: 11.5px; color: var(--text-dim); }
.mon-pair-names { font-weight: 600; }

/* ---- Call recording ---- */
.call-recording-banner {
  position: absolute; top: 14px; left: 50%; transform: translateX(-50%);
  background: rgba(229,72,77,0.92); color: #fff; font-size: 12.5px; font-weight: 700;
  padding: 6px 14px; border-radius: 999px; z-index: 5; letter-spacing: 0.2px;
}
/* ---- Live in-call translation (see callTranslateBtn/translatePanel in
   app.html, wireTranslateControls() in app.js) ---- */
.translate-panel {
  position: absolute; left: 12px; right: 12px; bottom: 110px; z-index: 6;
  background: #17233A; border-radius: 14px; padding: 40px 16px 16px;
  box-shadow: 0 8px 28px rgba(0,0,0,0.4); color: #fff;
}
/* Was `top: 10px; right: 10px` with no reserved space above the panel's
   content (padding-top was only 16px) - the button's own box (~26px tall,
   same as .modal .close-x) ended up sitting directly on top of the first
   .translate-toggle-row's checkbox below it. Same top-right corner, same
   stacking context, so the close button visually and functionally covered
   the "Translate my speech & send to others" checkbox - it could never be
   clicked, which looked exactly like "the ON checkbox doesn't show up".
   Fixed two ways together: give this button an explicit box (so it isn't
   however big the browser's default <button> padding happens to be) and
   give the panel enough padding-top (40px) to clear it, matching the
   26px-tall box positioned at top:10px. */
.translate-panel .close-x {
  position: absolute; top: 10px; right: 10px; z-index: 1;
  width: 26px; height: 26px; border-radius: 7px;
  background: none; border: none; color: var(--text-dim);
  display: inline-flex; align-items: center; justify-content: center;
}
.translate-panel .close-x:hover { background: rgba(255,255,255,0.08); color: #fff; }
.translate-panel-section { margin-bottom: 14px; }
.translate-panel-section:last-child { margin-bottom: 0; }
.translate-panel-section > label:not(.translate-toggle-row) {
  display: block; font-size: 12px; color: var(--text-dim); margin-bottom: 6px;
}
.translate-panel-section select {
  width: 100%; padding: 8px 10px; border-radius: 8px; border: 1px solid rgba(255,255,255,0.15);
  background: #0F1B2E; color: #fff; font-size: 13.5px;
}
.translate-toggle-row {
  display: flex; align-items: center; justify-content: space-between;
  font-size: 13.5px; margin-bottom: 10px; cursor: pointer;
}
.translate-save-default-row { margin-top: 10px; margin-bottom: 0; font-size: 12px; color: var(--text-dim); }
.translate-active-badge {
  position: absolute; top: 14px; left: 14px;
  background: rgba(79,110,247,0.92); color: #fff; font-size: 11.5px; font-weight: 700;
  padding: 5px 12px; border-radius: 999px; z-index: 5; letter-spacing: 0.2px;
}
/* When the recording banner is ALSO showing, don't let the two overlap -
   push the translation badge down below it. */
.call-recording-banner ~ .translate-active-badge { top: 46px; }

/* ---- Translator tool (Tools tab) - see toolsPanel-translator in app.html,
   initTranslatorTool() in app.js. Two people sharing one device, not tied
   to a call, so this gets its own plain (non-overlay) styling instead of
   reusing .translate-panel above. ---- */
.translator-mode-tabs { display: flex; gap: 8px; margin: 0 0 14px; flex-wrap: wrap; }
.translator-mode-tab { padding: 7px 14px; border-radius: 999px; border: 1px solid var(--border); background: var(--bg); font-size: 12.5px; cursor: pointer; }
.translator-mode-tab.active { background: var(--accent); color: #fff; border-color: var(--accent); }
.translator-status { text-align: center; font-size: 12.5px; color: var(--text-dim); margin-top: 10px; min-height: 16px; }
.translator-result-box { margin-top: 16px; }
.translator-line { padding: 10px 12px; border-radius: 10px; background: var(--bg-soft, rgba(128,128,128,0.08)); margin-bottom: 10px; }
.translator-line:last-child { margin-bottom: 0; }
.translator-line-label { font-size: 11px; font-weight: 700; color: var(--text-dim); margin-bottom: 4px; text-transform: uppercase; letter-spacing: 0.3px; }
.translator-line-text { font-size: 14.5px; line-height: 1.4; word-break: break-word; }

/* ---- Call status ("রিং হচ্ছে...", "অফলাইনে আছেন", etc.) ---- */
.call-status-banner {
  position: absolute; top: 14px; left: 50%; transform: translateX(-50%);
  background: rgba(0,0,0,0.55); color: #fff; font-size: 12.5px; font-weight: 600;
  padding: 6px 14px; border-radius: 999px; z-index: 5; letter-spacing: 0.2px;
}
.call-status-banner.offline { background: rgba(229,72,77,0.92); }
.call-overlay.minimized .call-status-banner { display: none !important; }
#toggleRecordBtn.active-on { color: var(--danger); }
#toggleRecordBtn.active-on svg { fill: var(--danger); }
#toggleRecordBtn.record-mandatory { opacity: 0.55; cursor: not-allowed; }

/* ---- Chat pin ---- */
.conv-pin-btn {
  background: none; border: none; color: var(--text-dim); cursor: pointer; padding: 4px;
  flex-shrink: 0;
  /* display:none (not just opacity:0) so an inactive button reserves zero
     row width - previously it stayed in the flex row invisible but still
     taking up space, squeezing conv-name and forcing long names to
     truncate even when nothing was actually being shown there. */
  display: none;
}
.conv-item:hover .conv-pin-btn { display: inline-flex; }
.conv-item.pinned .conv-pin-btn { display: inline-flex; color: var(--accent); }
.pin-indicator { margin-right: 3px; }

/* ---- Favorites (WhatsApp-style) ---- */
.conv-fav-btn {
  background: none; border: none; color: var(--text-dim); cursor: pointer; padding: 4px;
  flex-shrink: 0; font-size: 15px;
  display: none; /* same space-saving approach as .conv-pin-btn above */
}
.conv-item:hover .conv-fav-btn { display: inline-flex; }
.conv-fav-btn.active { display: inline-flex; color: #F5B300; }
.conv-search-wrap {
  display: flex; align-items: center; gap: 8px; margin: 10px 12px 4px;
  padding: 8px 12px; background: rgba(255,255,255,0.06); border-radius: 9px;
  color: #8996b3; flex-shrink: 0;
}
.conv-search-wrap input {
  flex: 1; background: none; border: none; outline: none; color: #EAEFF9; font-size: 13px; font-family: inherit;
}
.conv-search-wrap input::placeholder { color: #6E7A99; }

.conv-filter-chips {
  display: flex; flex-wrap: nowrap; overflow-x: auto; gap: 4px; padding: 5px 10px 2px; flex-shrink: 0;
  scrollbar-width: none;
}
.conv-filter-chips::-webkit-scrollbar { display: none; }
.conv-filter-chips .chip {
  border: 1.5px solid var(--border); background: var(--panel); color: var(--text-dim);
  border-radius: 999px; padding: 2px 8px; font-size: 10px; font-weight: 600; cursor: pointer;
  line-height: 1.6; flex-shrink: 0; white-space: nowrap;
}
.conv-filter-chips .chip.active { background: var(--accent); border-color: var(--accent); color: white; }

/* ---- Message pin banner ---- */
.pinned-msg-bar {
  display: flex; align-items: center; gap: 8px; padding: 8px 16px;
  background: var(--panel); border-bottom: 1px solid var(--border); cursor: pointer; font-size: 12.5px;
}
.pinned-msg-bar .pin-icon { flex-shrink: 0; }
.pinned-msg-bar .pinned-text { flex: 1; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; color: var(--text); }
.pinned-msg-bar .pinned-count { color: var(--text-dim); font-size: 11px; }

/* ---- Attach menu ---- */
.attach-menu-wrap { position: relative; }
.attach-menu {
  position: absolute; bottom: 46px; left: 0; background: var(--panel); border: 1px solid var(--border);
  border-radius: 12px; box-shadow: 0 8px 24px rgba(0,0,0,0.35); overflow: hidden; z-index: 20; min-width: 150px;
}
.attach-menu button {
  display: block; width: 100%; text-align: left; padding: 10px 14px; background: none; border: none;
  color: var(--text); font-size: 13px; cursor: pointer;
}
.attach-menu button:hover { background: rgba(255,255,255,0.06); }

/* ---- Stickers ---- */
.sticker-picker {
  position: absolute; bottom: 56px; right: 60px; background: var(--panel); border: 1px solid var(--border);
  border-radius: 12px; padding: 10px; box-shadow: 0 8px 24px rgba(0,0,0,0.35); z-index: 20;
  display: grid; grid-template-columns: repeat(4, 1fr); gap: 8px; width: 220px;
}
.sticker-picker img { width: 44px; height: 44px; cursor: pointer; border-radius: 8px; }
.sticker-picker img:hover { background: rgba(255,255,255,0.08); }
.sticker-msg-bubble { background: none !important; padding: 4px !important; box-shadow: none !important; }
.sticker-msg-bubble img { width: 96px; height: 96px; display: block; }

/* ---- Poll bubble ---- */
.poll-bubble { min-width: 220px; }
.poll-question { font-weight: 700; margin-bottom: 8px; }
.poll-option-row {
  position: relative; border: 1px solid var(--border); border-radius: 8px; padding: 7px 10px;
  margin-bottom: 6px; cursor: pointer; overflow: hidden; font-size: 12.5px;
}
.poll-option-row .poll-fill {
  position: absolute; left: 0; top: 0; bottom: 0; background: rgba(79,110,247,0.18); z-index: 0;
}
.poll-option-row .poll-option-label { position: relative; z-index: 1; display: flex; justify-content: space-between; gap: 8px; }
.poll-option-row.voted { border-color: var(--accent); }
.poll-meta { font-size: 11px; color: var(--text-dim); margin-top: 4px; }

/* ---- Location / contact share cards ---- */
.share-card {
  display: flex; align-items: center; gap: 10px; min-width: 200px; cursor: pointer;
}
.share-card .share-icon {
  width: 38px; height: 38px; border-radius: 50%; background: rgba(79,110,247,0.18);
  display: flex; align-items: center; justify-content: center; font-size: 18px; flex-shrink: 0;
}
.share-card .share-title { font-weight: 700; font-size: 13px; }
.share-card .share-sub { font-size: 11.5px; color: var(--text-dim); }
.call-log-bubble.missed .share-title { color: var(--danger); }
.call-log-bubble.missed .share-icon { background: rgba(220,53,69,0.15); }

/* ---- Live location bubble ---- */
.live-location-bubble { min-width: 220px; cursor: default; }
.live-location-bubble .share-icon { background: rgba(229,72,77,0.15); position: relative; }
.live-location-bubble.ended .share-icon { background: rgba(107,118,134,0.15); }
.live-location-bubble .live-dot {
  width: 9px; height: 9px; border-radius: 50%; background: var(--danger); flex-shrink: 0;
  animation: live-dot-pulse 1.4s infinite;
}
.live-location-bubble.ended .live-dot { animation: none; background: var(--text-dim); }
@keyframes live-dot-pulse {
  0% { box-shadow: 0 0 0 0 rgba(229,72,77,0.5); }
  70% { box-shadow: 0 0 0 7px rgba(229,72,77,0); }
  100% { box-shadow: 0 0 0 0 rgba(229,72,77,0); }
}
.live-location-bubble .share-title { display: flex; align-items: center; gap: 6px; color: var(--danger); }
.live-location-bubble.ended .share-title { color: inherit; }
.live-location-bubble .share-open-link { cursor: pointer; }
.live-location-bubble .live-stop-btn {
  margin-top: 8px; width: 100%; border: 1px solid var(--danger); color: var(--danger); background: none;
  border-radius: 8px; padding: 6px; font-size: 12px; font-weight: 600; cursor: pointer;
}
.live-location-bubble .live-stop-btn:hover { background: rgba(229,72,77,0.08); }

/* ---- Live location duration picker ---- */
.live-loc-duration-list { display: flex; flex-direction: column; gap: 8px; margin: 6px 0 14px; }
.live-loc-duration-opt {
  display: flex; justify-content: space-between; align-items: center; border: 1.5px solid var(--border);
  border-radius: 9px; padding: 11px 14px; cursor: pointer; font-size: 13.5px;
}
.live-loc-duration-opt:hover { border-color: var(--accent); }
.live-loc-duration-opt.active { border-color: var(--accent); background: rgba(31,174,142,0.08); }

/* ---- Chat header avatar / group icon ---- */
.chat-header-avatar {
  width: 34px; height: 34px; border-radius: 50%; position: relative; flex-shrink: 0; margin-right: 6px; cursor: default;
}
.chat-header-avatar.editable { cursor: pointer; }
.chat-header-avatar.clickable-profile { cursor: pointer; }
/* The circular clip lives on this inner wrapper, not on .chat-header-avatar
   itself, so the online dot (positioned against .chat-header-avatar) can
   sit at the edge of the circle without being clipped off. */
.chat-header-avatar .chat-header-avatar-inner { width: 100%; height: 100%; border-radius: 50%; overflow: hidden; }
.chat-header-avatar img { width: 100%; height: 100%; object-fit: cover; }
.chat-header-avatar .avatar-fallback {
  width: 100%; height: 100%; display: flex; align-items: center; justify-content: center;
  color: #fff; font-weight: 700; font-size: 14px;
}
/* Online dot on the chat header avatar - header background is lighter than
   the sidebar's, so its border is set separately from the sidebar dot. */
.chat-header-avatar .avatar-online-dot { border-color: var(--panel, #fff); }

/* ---- Calls tab ---- */
.calls-list { display: flex; flex-direction: column; gap: 8px; }
.call-history-row {
  display: flex; align-items: center; gap: 12px; padding: 10px 14px; background: var(--panel);
  border: 1px solid var(--border); border-radius: 10px;
}
.call-history-row .chr-info { flex: 1; min-width: 0; }
.call-history-row .chr-name { font-weight: 700; font-size: 13.5px; }
.call-history-row .chr-meta { font-size: 11.5px; color: var(--text-dim); }
.call-history-row .chr-actions { display: flex; gap: 6px; }

/* The "সহকর্মীরা" (colleagues) quick-call list gets its own compact,
   fixed-height panel with a visible scrollbar - instead of every row at
   full size pushing "সাম্প্রতিক কল" further down the page, the whole
   colleague roster now scrolls inside its own small "slider" area that
   fits the screen regardless of staff count. */
#callsColleaguesList {
  max-height: 46vh; overflow-y: auto; padding-right: 6px; margin-bottom: 4px;
  scrollbar-width: thin; scrollbar-color: var(--border) transparent;
}
#callsColleaguesList::-webkit-scrollbar { width: 7px; }
#callsColleaguesList::-webkit-scrollbar-track { background: transparent; }
#callsColleaguesList::-webkit-scrollbar-thumb { background: var(--border); border-radius: 6px; }
#callsColleaguesList::-webkit-scrollbar-thumb:hover { background: var(--text-dim); }
#callsColleaguesList .call-history-row { padding: 7px 10px; gap: 9px; border-radius: 8px; }
#callsColleaguesList .chr-name { font-size: 12.5px; }
#callsColleaguesList .chr-meta { font-size: 10.5px; }
#callsColleaguesList .chr-actions { gap: 4px; }
#callsColleaguesList .call-btn { width: 30px; height: 30px; }
#callsColleaguesList .call-btn svg { width: 12px; height: 12px; }

/* ---- Generic list-in-modal rows (broadcast lists, communities, sessions) ---- */
.simple-list-row {
  display: flex; align-items: center; justify-content: space-between; gap: 10px;
  padding: 10px 12px; border: 1px solid var(--border); border-radius: 10px; margin-bottom: 8px;
}
.simple-list-row .slr-title { font-weight: 700; font-size: 13.5px; }
.simple-list-row .slr-sub { font-size: 11.5px; color: var(--text-dim); }
.community-group-chip {
  display: inline-block; padding: 4px 10px; margin: 3px 4px 0 0; border-radius: 999px;
  background: rgba(79,110,247,0.15); font-size: 11.5px; cursor: pointer;
}

/* ---- Meetings ---- */
.section-title-sm { font-size: 12.5px; font-weight: 700; color: var(--text-dim); text-transform: uppercase; letter-spacing: 0.5px; margin-bottom: 8px; }
.meeting-row {
  display: flex; align-items: center; gap: 12px; padding: 12px 14px; background: var(--panel);
  border: 1px solid var(--border); border-radius: 10px; margin-bottom: 8px; flex-wrap: wrap;
}
.meeting-row .mr-info { flex: 1; min-width: 180px; }
.meeting-row .mr-title { font-weight: 700; font-size: 13.5px; }
.meeting-row .mr-meta { font-size: 11.5px; color: var(--text-dim); margin-top: 2px; }
.meeting-row .mr-agenda { font-size: 11.5px; color: var(--text); margin-top: 4px; background: rgba(79,110,247,0.08); padding: 5px 8px; border-radius: 7px; white-space: pre-wrap; }
.meeting-row .mr-actions { display: flex; gap: 6px; flex-wrap: wrap; }
.resp-badge { font-size: 10.5px; font-weight: 700; padding: 3px 9px; border-radius: 999px; }
.resp-badge.accepted { background: rgba(31,174,142,0.18); color: var(--signal); }
.resp-badge.declined { background: rgba(229,72,77,0.15); color: var(--danger); }
.resp-badge.pending { background: rgba(148,163,184,0.18); color: var(--text-dim); }
.resp-badge.cancelled { background: rgba(229,72,77,0.15); color: var(--danger); }
.resp-badge.completed { background: rgba(148,163,184,0.18); color: var(--text-dim); }

/* ---- Global search ---- */
.gsr-row { padding: 10px 4px; border-bottom: 1px solid var(--border); cursor: pointer; }
.gsr-row:hover { background: rgba(255,255,255,0.04); }
.gsr-row .gsr-top { display: flex; justify-content: space-between; font-size: 11.5px; color: var(--text-dim); margin-bottom: 3px; }
.gsr-row .gsr-snippet { font-size: 13px; }
.gsr-row mark { background: rgba(245,165,36,0.4); color: inherit; border-radius: 3px; }

/* ---- Meeting calendar ---- */
.cal-header { display: flex; align-items: center; justify-content: space-between; margin-bottom: 10px; }
.cal-month-label { font-weight: 700; font-size: 14.5px; }
.cal-grid { display: grid; grid-template-columns: repeat(7, 1fr); gap: 4px; }
.cal-weekday { text-align: center; font-size: 10.5px; color: var(--text-dim); font-weight: 700; padding: 4px 0; }
.cal-day {
  aspect-ratio: 1; border: 1px solid var(--border); border-radius: 8px; padding: 4px 5px;
  font-size: 11px; cursor: pointer; position: relative; background: var(--panel);
}
.cal-day.other-month { opacity: 0.35; }
.cal-day.today { border-color: var(--accent); }
.cal-day.selected { background: rgba(79,110,247,0.18); border-color: var(--accent); }
.cal-day .cal-day-num { font-weight: 700; }
.cal-day .cal-dot-row { display: flex; gap: 2px; margin-top: 3px; flex-wrap: wrap; }
.cal-day .cal-dot { width: 5px; height: 5px; border-radius: 50%; background: var(--accent); }

/* ---- System health ---- */
.health-workers-list { display: flex; flex-wrap: wrap; gap: 8px; }
.health-worker-chip {
  font-size: 11px; padding: 5px 10px; border-radius: 999px; font-weight: 600;
  background: rgba(31,174,142,0.15); color: var(--signal);
}
.health-worker-chip.dead { background: rgba(229,72,77,0.15); color: var(--danger); }
.health-bar-track { height: 6px; border-radius: 999px; background: var(--border); overflow: hidden; margin-top: 4px; }
.health-bar-fill { height: 100%; background: var(--accent); }
.health-bar-fill.warn { background: var(--amber); }
.health-bar-fill.danger { background: var(--danger); }

/* ---- Tasks ---- */
.task-filter-row { display: flex; gap: 8px; margin-bottom: 14px; }

/* Tools tab used to be a left-to-right horizontal slider of pill buttons,
   which pushed later items (like জরুরি নোট) off-screen on narrow/mobile
   screens with no obvious way to reach them. Replaced with a wrapping
   icon-tile grid (icon on top, label underneath) - the same card look as
   .software-grid/.software-card - so every tool is visible up front and
   nothing needs to be scrolled through sideways. */
.tools-grid {
  display: grid;
  /* Fixed repeat(4, 1fr) forced every tile into a narrow column on phones,
     and with a fixed 40px icon + two-line label inside that narrow width
     the tile ended up much taller than it was wide. auto-fill + minmax lets
     the browser fit as many square-ish tiles per row as actually fit the
     screen, and aspect-ratio below keeps each tile close to 1:1 instead of
     stretching tall. */
  grid-template-columns: repeat(auto-fill, minmax(92px, 1fr));
  gap: 10px;
  margin-bottom: 14px;
}
.tools-subtab-btn {
  display: flex; flex-direction: column; align-items: center; justify-content: center; text-align: center; gap: 6px;
  aspect-ratio: 1 / 1;
  /* Belt-and-suspenders against any grid leftover-space quirk (e.g. a lone
     item alone on the grid's last row) ever stretching one tile bigger
     than the rest - caps every tile at a sane size regardless of how much
     free space its row/column ends up with. */
  max-width: 120px;
  padding: 10px 6px; border-radius: 12px; border: 1.5px solid var(--border); background: white; cursor: pointer;
  font-family: inherit;
}
.tools-subtab-btn:hover { border-color: var(--accent); }
.tools-subtab-btn .tools-card-icon {
  width: 46px; height: 46px; border-radius: 12px; background: var(--bg);
  display: flex; align-items: center; justify-content: center; font-size: 23px; line-height: 1;
}
.tools-subtab-btn .tools-card-label { font-size: 11px; font-weight: 600; color: var(--text); line-height: 1.25; }

/* ---------- Tools page header (shown once a tool is opened) ----------
   Clicking a tile now opens that tool as its own "page" - the grid hides
   and this bar (title + close, and minimize for tools that must keep
   running in the background) sits above the tool's panel. Closing returns
   to the tile grid above. */
.tools-panel-topbar {
  display: flex; align-items: center; gap: 8px; margin-bottom: 14px;
}
.tools-panel-topbar-title { font-size: 15px; font-weight: 700; color: var(--text); flex: 1; }
.tools-panel-back-btn, .tools-panel-minimize-btn {
  display: inline-flex; align-items: center; gap: 5px;
  padding: 7px 12px; border-radius: 9px; border: 1.5px solid var(--border); background: white;
  font-size: 12.5px; font-weight: 600; color: var(--text); cursor: pointer; font-family: inherit;
}
.tools-panel-back-btn:hover { border-color: #d64545; color: #d64545; }
.tools-panel-minimize-btn:hover { border-color: var(--accent); color: var(--accent-dark, var(--accent)); }

@media (max-width: 820px) {
  .tools-grid { grid-template-columns: repeat(auto-fill, minmax(80px, 1fr)); gap: 8px; }
  .tools-subtab-btn { padding: 8px 4px; }
  .tools-subtab-btn .tools-card-icon { width: 40px; height: 40px; font-size: 20px; }
  .tools-subtab-btn .tools-card-label { font-size: 10.5px; }
  /* On the Chats empty-state, .empty-state's `margin:auto` vertically
     centers the whole block (title + quick-nav grid) inside .messages,
     which on a tall phone screen shoves the tile grid down into the
     middle and leaves a big blank gap above it. Pin the chats variant
     to the top instead so the cards start right under the header. */
  .chats-empty-state { margin: 0 auto; padding-top: 12px; }
}
.task-filter-btn.active { background: var(--accent); color: #fff; border-color: var(--accent); }
.approval-filter-btn.active { background: var(--accent); color: #fff; border-color: var(--accent); }
.task-row {
  display: flex; align-items: flex-start; gap: 12px; padding: 12px 14px; background: var(--panel);
  border: 1px solid var(--border); border-radius: 10px; margin-bottom: 8px;
}
.task-row.done { opacity: 0.6; }
.task-row .task-check {
  width: 20px; height: 20px; border-radius: 6px; border: 2px solid var(--border); flex-shrink: 0;
  cursor: pointer; margin-top: 2px; display: flex; align-items: center; justify-content: center; font-size: 12px;
}
.task-row.done .task-check { background: var(--signal); border-color: var(--signal); color: #fff; }
.task-row .tr-info { flex: 1; min-width: 0; }
.task-row .tr-title { font-weight: 700; font-size: 13.5px; }
.task-row.done .tr-title { text-decoration: line-through; }
.task-row .tr-desc { font-size: 11.5px; color: var(--text-dim); margin-top: 2px; }
.task-row .tr-meta { font-size: 11px; color: var(--text-dim); margin-top: 5px; display: flex; gap: 6px; flex-wrap: wrap; align-items: center; }
.task-row .tr-actions { display: flex; gap: 6px; flex-shrink: 0; }
.priority-badge { font-size: 10px; font-weight: 700; padding: 2px 8px; border-radius: 999px; }
.priority-badge.low { background: rgba(148,163,184,0.18); color: var(--text-dim); }
.priority-badge.normal { background: rgba(79,110,247,0.15); color: var(--accent); }
.priority-badge.high { background: rgba(229,72,77,0.15); color: var(--danger); }
.due-badge { font-size: 11px; }
.due-badge.overdue { color: var(--danger); font-weight: 700; }
.staff-task-row { display: flex; justify-content: space-between; align-items: center; padding: 8px 4px; border-bottom: 1px solid var(--border); font-size: 12.5px; }

/* ---- Approvals (external integrations) ---- */
.approval-status { font-size: 10px; font-weight: 700; padding: 2px 8px; border-radius: 999px; }
.approval-status.pending { background: rgba(245,166,35,0.18); color: #B7791F; }
.approval-status.approved { background: #E6F7F1; color: var(--accent-dark); }
.approval-status.rejected { background: rgba(229,72,77,0.15); color: var(--danger); }
.approval-status.cancelled { background: #F1F2F4; color: var(--text-dim); }
.approval-app-tag { font-size: 10.5px; font-weight: 700; padding: 2px 8px; border-radius: 999px; background: #EDEBFB; color: #6C4FD9; }
.approval-note-box { font-size: 11.5px; color: var(--text-dim); background: var(--bg2, #F7F8FA); border-radius: 8px; padding: 6px 9px; margin-top: 6px; }

/* ---- Integration apps (admin) ---- */
.integration-app-row {
  display: flex; align-items: flex-start; gap: 12px; padding: 12px 14px; background: var(--panel);
  border: 1px solid var(--border); border-radius: 10px; margin-bottom: 8px;
}
.integration-app-row .ia-info { flex: 1; min-width: 0; }
.integration-app-row .ia-name { font-weight: 700; font-size: 13.5px; }
.integration-app-row .ia-desc { font-size: 11.5px; color: var(--text-dim); margin-top: 2px; }
.integration-app-row .ia-meta { font-size: 11px; color: var(--text-dim); margin-top: 5px; display: flex; gap: 10px; flex-wrap: wrap; align-items: center; }
.integration-app-row .ia-key { font-family: monospace; background: #F1F2F4; padding: 1px 6px; border-radius: 5px; }
.integration-app-row .ia-actions { display: flex; gap: 6px; flex-shrink: 0; flex-wrap: wrap; }
.key-reveal-box {
  background: #F1F2F4; border: 1.5px dashed var(--border); border-radius: 9px; padding: 10px 12px;
  font-family: monospace; font-size: 12.5px; word-break: break-all; margin: 8px 0; user-select: all;
}
.key-reveal-warn { font-size: 11.5px; color: var(--danger); font-weight: 700; margin-bottom: 4px; }

/* ---- Ringtone picker ---- */
.ringtone-row {
  display: flex; align-items: center; gap: 10px; padding: 8px 10px; border: 1.5px solid var(--border);
  border-radius: 9px; margin-bottom: 6px; cursor: pointer;
}
.ringtone-row.selected { border-color: var(--accent); background: rgba(79,110,247,0.08); }
.ringtone-row .rt-label { flex: 1; font-size: 13px; font-weight: 600; }
.ringtone-row .rt-preview-btn {
  width: 28px; height: 28px; border-radius: 50%; border: none; background: var(--accent);
  color: #fff; font-size: 12px; cursor: pointer; flex-shrink: 0;
}
.ringtone-upload-row {
  display: flex; align-items: center; gap: 8px; padding: 10px; border: 1.5px dashed var(--border);
  border-radius: 9px; cursor: pointer; font-size: 12.5px; color: var(--text-dim); font-weight: 600;
}
.ringtone-upload-row:hover { border-color: var(--accent); color: var(--accent); }
.ringtone-upload-row svg { flex-shrink: 0; }

/* ---- Login greeting ---- */
.greeting-toast {
  position: fixed; top: 22px; left: 50%; transform: translateX(-50%) translateY(-16px);
  background: var(--ink, #0B1424); color: #fff; padding: 12px 22px; border-radius: 999px;
  display: flex; align-items: center; gap: 10px; font-size: 14.5px; font-weight: 600;
  box-shadow: 0 10px 30px rgba(0,0,0,0.35); z-index: 500;
  opacity: 0; pointer-events: none; transition: opacity 0.35s ease, transform 0.35s ease;
}
.greeting-toast.show { opacity: 1; transform: translateX(-50%) translateY(0); }
.greeting-wave { display: inline-block; font-size: 20px; transform-origin: 70% 70%; animation: greetingWave 0.7s ease-in-out 2; }
@keyframes greetingWave {
  0% { transform: rotate(0deg); }
  15% { transform: rotate(18deg); }
  30% { transform: rotate(-12deg); }
  45% { transform: rotate(18deg); }
  60% { transform: rotate(-8deg); }
  75% { transform: rotate(10deg); }
  100% { transform: rotate(0deg); }
}
.small-btn { border: 1px solid var(--border); background: white; padding: 5px 10px; border-radius: 7px; font-size: 12px; margin-right: 4px; }
.small-btn:hover { border-color: var(--accent); }
.small-btn.danger { border-color: var(--danger); color: var(--danger); }
.small-btn.danger:hover { background: var(--danger); color: white; }
#emailRefreshBtn { display: inline-flex; align-items: center; }
#emailRefreshBtn:disabled { opacity: 0.65; cursor: default; }
#emailRefreshIcon.spin { animation: email-spin 0.8s linear infinite; }
@keyframes email-spin { from { transform: rotate(0deg); } to { transform: rotate(360deg); } }
.email-auto-refresh-note { font-size: 10.5px; color: var(--text-dim); padding: 0 16px 6px; }

.toast {
  position: fixed; bottom: 20px; left: 50%; transform: translateX(-50%);
  background: var(--ink); color: white; padding: 10px 18px; border-radius: 10px; font-size: 13px;
  z-index: 200; opacity: 0; transition: opacity .2s;
}
.toast.show { opacity: 1; }

/* ---------- Email ---------- */
.email-connect-pane { flex: 1; display: flex; align-items: center; justify-content: center; padding: 20px; }
.email-connect-card {
  background: var(--panel); border-radius: 16px; padding: 32px; max-width: 380px; width: 100%;
  text-align: center; box-shadow: 0 12px 40px rgba(0,0,0,0.08);
}
.email-connect-card h3 { margin: 12px 0 6px; font-size: 16px; }
.email-connect-card p { font-size: 12.5px; color: var(--text-dim); margin-bottom: 18px; line-height: 1.5; }
.email-connect-card .field { text-align: left; }
.email-connect-note { font-size: 11px; color: var(--text-dim); margin-top: 12px; }

.email-body { flex: 1; display: flex; min-height: 0; }
.email-folders {
  width: 190px; border-right: 1px solid var(--border); background: var(--panel);
  padding: 14px 10px; overflow-y: auto; flex-shrink: 0;
}
/* Moved out of an inline style="margin-bottom:14px" on the button itself -
   an inline style always wins over the mobile media query below trying to
   reset it to 0, which was pushing the button out of vertical alignment
   with the folder tabs on phones. Desktop (vertical sidebar) still wants
   the gap below the button, before the folder list starts. */
.email-folders #emailComposeBtn { margin-bottom: 14px; }
.email-folder-item {
  display: flex; align-items: center; gap: 8px; padding: 8px 10px; border-radius: 8px;
  font-size: 13px; cursor: pointer; color: var(--text-dim); margin-bottom: 2px;
}
.email-folder-item:hover { background: var(--bg); }
.email-folder-item.active { background: var(--accent); color: white; font-weight: 600; }
.email-list-pane { width: 320px; border-right: 1px solid var(--border); flex-shrink: 0; display: flex; flex-direction: column; min-height: 0; background: var(--panel); }
.email-search-wrap {
  display: flex; align-items: center; gap: 8px; margin: 10px; padding: 7px 12px;
  background: var(--bg); border: 1px solid var(--border); border-radius: 9px; color: var(--text-dim); flex-shrink: 0;
}
.email-search-wrap input { flex: 1; background: none; border: none; outline: none; font-size: 13px; font-family: inherit; color: var(--text); }
.email-list { flex: 1; overflow-y: auto; min-height: 0; }
.email-item { padding: 12px 32px 12px 16px; border-bottom: 1px solid var(--border); cursor: pointer; position: relative; }
/* Outlook-style "Follow up" flag - sits top-right of the list row, greyed
   out (unflagged) until clicked; red once flagged, like Outlook's own.
   .email-item's extra right padding above keeps the from/date/subject text
   from running underneath it. */
.email-item-flag-btn {
  position: absolute; top: 10px; right: 8px; z-index: 1;
  border: none; background: none; padding: 2px; font-size: 13px; line-height: 1;
  opacity: 0.35; filter: grayscale(1); cursor: pointer;
}
.email-item-flag-btn:hover { opacity: 0.7; }
.email-item-flag-btn.flagged { opacity: 1; filter: none; }
/* Same icon reused as a labeled action button in the reader header toolbar -
   .small-btn.email-item-flag-btn (two classes) beats the plain list-row
   .email-item-flag-btn rule above on specificity, so it isn't absolutely
   positioned or greyed out here the way the bare list-row icon is. */
.small-btn.email-item-flag-btn { position: static; opacity: 1; filter: none; color: var(--text-dim); font-size: 12.5px; }
.small-btn.email-item-flag-btn.flagged { color: #d64545; font-weight: 700; }
.email-item:hover { background: var(--bg); }
.email-item.active { background: rgba(31,174,142,0.1); }
.email-item.unread .email-item-from, .email-item.unread .email-item-subject { font-weight: 700; }
.email-item-top { display: flex; justify-content: space-between; font-size: 12px; margin-bottom: 3px; }
.email-item-from { color: var(--text); }
.email-item-date { color: var(--text-dim); flex-shrink: 0; margin-left: 8px; }
.email-item-attach-icon { font-size: 11px; opacity: 0.8; }
.email-item-subject { font-size: 13px; color: var(--text-dim); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.email-loading { padding: 20px; text-align: center; font-size: 12.5px; color: var(--text-dim); }

.email-reader { flex: 1; overflow-y: auto; padding: 24px; background: var(--bg); }
.email-reader-actions {
  display: flex; gap: 8px; flex-wrap: wrap; align-items: center;
  margin-bottom: 18px; padding-bottom: 14px; border-bottom: 1px solid var(--border);
}
.email-reader-header { margin-bottom: 16px; padding-bottom: 16px; border-bottom: 1px solid var(--border); }
.email-reader-header h3 { margin: 0 0 8px; font-size: 17px; }
.email-reader-meta { font-size: 12.5px; color: var(--text-dim); margin-bottom: 2px; }
.email-reader-body { font-size: 14px; line-height: 1.6; color: var(--text); word-break: break-word; }
.email-reader-body img { max-width: 100%; }
.email-attachments { margin-top: 16px; display: flex; flex-wrap: wrap; gap: 8px; }
.email-editor-toolbar {
  display: flex; align-items: center; gap: 4px; padding: 6px 8px;
  border: 1.5px solid var(--border); border-bottom: none; border-radius: 9px 9px 0 0; background: var(--panel);
}
.email-editor-toolbar button {
  width: 26px; height: 26px; border-radius: 5px; border: 1px solid transparent; background: none;
  font-size: 12.5px; display: flex; align-items: center; justify-content: center; color: var(--text-dim);
}
.email-editor-toolbar button:hover { background: var(--bg); border-color: var(--border); color: var(--text); }
.email-editor-toolbar select { font-size: 11px; border: 1px solid var(--border); border-radius: 5px; padding: 3px; background: white; }
.email-editor-toolbar input[type="color"] { width: 26px; height: 26px; border: 1px solid var(--border); border-radius: 5px; padding: 1px; cursor: pointer; }
.email-attachment-chip {
  border: 1.5px solid var(--border); background: var(--panel); color: var(--text-dim);
  border-radius: 8px; padding: 6px 12px; font-size: 12px; cursor: pointer;
}
.email-attachment-chip:hover { border-color: var(--accent); color: var(--accent-dark); }
.email-attachment-chip:disabled { opacity: 0.6; cursor: wait; }
.email-attachment-chip-removable { display: inline-flex; align-items: center; gap: 8px; cursor: default; }
.email-attachment-chip-removable button {
  border: none; background: none; color: var(--text-dim); cursor: pointer; font-size: 13px; line-height: 1; padding: 0;
}
.email-attachment-chip-removable button:hover { color: #d64545; }

@media (max-width: 820px) {
  .email-body { flex-direction: column; }
  .email-folders {
    width: 100%; display: flex; flex-direction: row; align-items: center;
    overflow-x: auto; overflow-y: hidden; padding: 8px 10px; gap: 6px;
    border-right: none; border-bottom: 1px solid var(--border); flex-shrink: 0;
    scrollbar-width: none;
  }
  .email-folders::-webkit-scrollbar { display: none; }
  .email-folders #emailComposeBtn {
    flex-shrink: 0; width: auto; height: 32px; padding: 0 14px; margin-bottom: 0;
    border-radius: 999px; font-size: 12.5px; white-space: nowrap;
  }
  #emailFolderList { display: flex; flex-direction: row; gap: 6px; flex-wrap: nowrap; }
  .email-folder-item {
    flex-shrink: 0; white-space: nowrap; height: 32px; padding: 0 12px;
    border-radius: 999px; background: var(--bg); margin-bottom: 0; font-size: 12.5px;
  }
  .email-folder-item.active { background: var(--accent); color: white; }
  .email-list-pane { width: 100%; max-height: 40vh; border-right: none; border-bottom: 1px solid var(--border); }

  /* The inbox header (email address + Send/Receive/Rules/Disconnect) was
     cramped into one unwrapped row next to the floating hamburger button,
     pushing "Disconnect" off the edge of the screen with no way to reach
     it on narrow phones. Let it wrap onto its own full-width row instead. */
  #emailInboxPane .chat-header { flex-wrap: wrap; height: auto; padding: 10px 16px 10px 54px; row-gap: 8px; }
  #emailInboxPane .call-actions {
    margin-left: 0; width: 100%; overflow-x: auto; flex-wrap: nowrap; scrollbar-width: none;
  }
  #emailInboxPane .call-actions::-webkit-scrollbar { display: none; }
  #emailInboxPane .call-actions .small-btn { flex-shrink: 0; white-space: nowrap; }
}
/* ---------- Message actions, reply, reactions, voice ---------- */
.msg-row { position: relative; }
.msg-actions-btn {
  position: absolute; top: 0; opacity: 0; transition: opacity .12s;
  width: 26px; height: 26px; border-radius: 50%; border: none; background: var(--panel);
  box-shadow: 0 1px 4px rgba(0,0,0,0.15); display: flex; align-items: center; justify-content: center; color: var(--text-dim);
}
.msg-row:not(.mine) .msg-actions-btn { right: -30px; }
.msg-row.mine .msg-actions-btn { left: -30px; }
.msg-row:hover .msg-actions-btn { opacity: 1; }

.msg-action-menu {
  position: fixed; z-index: 150; background: white; border-radius: 12px; box-shadow: 0 8px 30px rgba(0,0,0,0.2);
  padding: 8px; display: none; min-width: 170px; max-height: 80vh; overflow-y: auto;
}
.msg-action-menu.show { display: block; }
.quick-reacts { display: flex; gap: 4px; padding: 4px 4px 8px; border-bottom: 1px solid var(--border); margin-bottom: 6px; }
.quick-reacts button { background: none; border: none; font-size: 19px; padding: 4px; border-radius: 8px; }
.quick-reacts button:hover { background: var(--bg); }
.msg-action-item {
  display: block; width: 100%; text-align: left; background: none; border: none;
  padding: 8px 10px; border-radius: 8px; font-size: 13px; color: var(--text);
}
.msg-action-item:hover { background: var(--bg); }
.msg-action-item.danger { color: var(--danger); }

/* WhatsApp-style bottom sheet for choosing how to delete your own message */
.delete-choice-sheet {
  position: fixed; inset: 0; z-index: 170; display: none;
  align-items: flex-end; justify-content: center;
}
.delete-choice-sheet.show { display: flex; }
.delete-choice-backdrop { position: absolute; inset: 0; background: rgba(0,0,0,0.45); }
.delete-choice-box {
  position: relative; width: 100%; max-width: 480px; background: var(--panel, #fff);
  border-radius: 14px 14px 0 0; padding: 8px 0 calc(8px + env(safe-area-inset-bottom, 0px));
  box-shadow: 0 -4px 24px rgba(0,0,0,0.2);
}
.delete-choice-item {
  display: block; width: 100%; text-align: center; background: none; border: none;
  border-bottom: 1px solid var(--border); padding: 15px 14px; font-size: 14.5px; font-weight: 600; color: var(--text);
}
.delete-choice-item:last-child { border-bottom: none; }
.delete-choice-item.danger { color: var(--danger); }
.delete-choice-item.cancel { font-weight: 700; }
.delete-choice-item:active { background: var(--bg); }

.reply-quote {
  border-left: 3px solid var(--accent); background: rgba(31,174,142,0.08);
  border-radius: 6px; padding: 5px 9px; margin-bottom: 5px; font-size: 12px; cursor: pointer;
}
.msg-row.mine .reply-quote { background: rgba(0,0,0,0.06); border-left-color: var(--accent-dark); }
.reply-quote .reply-quote-sender { font-weight: 700; }
.reply-quote .reply-quote-text { opacity: 0.85; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; max-width: 260px; }

.forwarded-label { font-size: 11px; color: var(--text-dim); font-style: italic; margin-bottom: 2px; display: flex; align-items: center; gap: 4px; }
.msg-row.mine .forwarded-label { justify-content: flex-end; }

.reactions-row { display: flex; gap: 3px; margin-top: 3px; flex-wrap: wrap; }
.reaction-pill {
  background: var(--panel); border: 1px solid var(--border); border-radius: 12px;
  padding: 1px 7px; font-size: 12px; display: flex; align-items: center; gap: 3px; cursor: pointer;
}
.reaction-pill.mine-reacted { border-color: var(--accent); background: rgba(31,174,142,0.1); }

.deleted-msg { font-style: italic; color: var(--text-dim); display: flex; align-items: center; gap: 6px; }

.voice-msg-bubble { display: flex; align-items: center; gap: 10px; padding: 8px 12px; min-width: 190px; }
.voice-msg-bubble audio { max-width: 220px; height: 32px; }

.reply-preview-bar {
  display: flex; align-items: center; gap: 10px; padding: 8px 16px;
  background: var(--bg); border-top: 1px solid var(--border);
}
.reply-preview-content { flex: 1; border-left: 3px solid var(--accent); padding-left: 8px; min-width: 0; }
.reply-preview-sender { font-size: 12px; font-weight: 700; color: var(--accent-dark); }
.reply-preview-text { font-size: 12.5px; color: var(--text-dim); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.reply-preview-bar button { background: none; border: none; color: var(--text-dim); flex-shrink: 0; }

.voice-record-bar {
  display: flex; align-items: center; gap: 10px; padding: 10px 16px;
  background: var(--bg); border-top: 1px solid var(--border);
}
.rec-dot { width: 10px; height: 10px; border-radius: 50%; background: var(--danger); animation: emg-pulse 1s infinite; }
.voice-record-bar .send-btn { width: 34px; height: 34px; }

.emoji-picker {
  position: fixed; z-index: 150; background: white; border-radius: 14px; box-shadow: 0 8px 30px rgba(0,0,0,0.2);
  padding: 10px; display: none; grid-template-columns: repeat(8, 1fr); gap: 2px; width: 300px; max-height: 220px; overflow-y: auto;
}
.emoji-picker.show { display: grid; }
.emoji-picker button { background: none; border: none; font-size: 20px; padding: 5px; border-radius: 8px; }
.emoji-picker button:hover { background: var(--bg); }

.date-divider { text-align: center; margin: 14px 0; }
.date-divider span {
  background: var(--panel); border: 1px solid var(--border); color: var(--text-dim);
  font-size: 11px; font-weight: 600; padding: 4px 12px; border-radius: 20px;
}
/* ---------- Search in chat ---------- */
.search-in-chat-bar {
  display: flex; align-items: center; gap: 8px; padding: 8px 16px;
  background: var(--panel); border-bottom: 1px solid var(--border); color: var(--text-dim);
}
.search-in-chat-bar input {
  flex: 1; border: none; outline: none; font-size: 13.5px; background: transparent; color: var(--text);
}
.search-in-chat-bar button { background: none; border: none; color: var(--text-dim); padding: 4px; border-radius: 6px; }
.search-in-chat-bar button:hover { background: var(--bg); }
.search-in-chat-bar #searchInChatCount { font-size: 11.5px; white-space: nowrap; }
.msg-row.search-match .msg-bubble { outline: 2px solid var(--warn); }
.msg-row.search-match-active .msg-bubble { outline: 2px solid var(--accent); }

/* ---------- Mute ---------- */
.call-btn.muted-active { color: var(--danger); border-color: var(--danger); }
.conv-item .mute-indicator { color: var(--text-dim); flex-shrink: 0; opacity: 0.7; }

/* ---------- File preview before send ---------- */
.file-preview-list { display: flex; flex-direction: column; gap: 8px; max-height: 260px; overflow-y: auto; margin-bottom: 4px; }
.file-preview-item { display: flex; align-items: center; gap: 10px; padding: 8px; border: 1px solid var(--border); border-radius: 9px; }
.file-preview-item img { width: 48px; height: 48px; object-fit: cover; border-radius: 7px; }
.file-preview-item .fp-name { font-size: 12.5px; font-weight: 600; }
.file-preview-item .fp-size { font-size: 11px; color: var(--text-dim); }
.file-preview-item .fp-remove { margin-left: auto; background: none; border: none; color: var(--text-dim); }

/* ---------- @mention ---------- */
.mention-dropdown {
  position: fixed; z-index: 150; background: white; border-radius: 12px; box-shadow: 0 8px 30px rgba(0,0,0,0.2);
  padding: 6px; display: none; min-width: 220px; max-height: 220px; overflow-y: auto;
}
.mention-dropdown.show { display: block; }
.mention-dropdown .people-row { padding: 7px 8px; border-radius: 8px; cursor: pointer; }
.mention-dropdown .people-row:hover, .mention-dropdown .people-row.highlighted { background: var(--bg); }
.mention-tag { color: var(--accent-dark); font-weight: 700; background: rgba(31,174,142,0.12); border-radius: 4px; padding: 0 2px; }

/* ---------- Link preview ---------- */
.link-preview-card {
  display: block; margin-top: 6px; border: 1px solid var(--border); border-radius: 10px;
  overflow: hidden; text-decoration: none; color: inherit; max-width: 280px; background: var(--panel);
}
.msg-row.mine .link-preview-card { background: rgba(0,0,0,0.05); border-color: rgba(0,0,0,0.12); }
.link-preview-card img { width: 100%; max-height: 130px; object-fit: cover; display: block; }
.link-preview-card .lp-body { padding: 8px 10px; }
.link-preview-card .lp-title { font-size: 12.5px; font-weight: 700; margin-bottom: 2px; }
.link-preview-card .lp-desc { font-size: 11.5px; opacity: 0.8; display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical; overflow: hidden; }

/* ---------- Edited / starred indicators ---------- */
.edited-label { font-size: 10px; opacity: 0.7; margin-left: 4px; }
.star-indicator { color: var(--warn); margin-right: 3px; }

/* ---------- Tools tab: sub-tabs, Calculator, Alarm, Namaz/Azan ---------- */
.tools-subtab-btn.active { border-color: var(--accent); background: rgba(31,174,142,0.06); }
.tools-subtab-btn.active .tools-card-icon { background: var(--accent); color: #fff; }
.tools-subtab-btn.active .tools-card-label { color: var(--accent-dark, var(--accent)); }
.tools-sub-panel { max-width: 420px; }
@media (min-width: 900px) {
  /* On desktop the tools panel sits inside a wide .main column, so a
     420px cap left most of the screen blank and squeezed every label
     into a narrow strip on the left. Let it breathe on larger screens
     while leaving the mobile width above untouched. */
  .tools-sub-panel { max-width: 760px; }
}

.calculator-wrap { max-width: 320px; }
.calculator-wrap.calc-sci-mode { max-width: 420px; }
.calculator-display-wrap { margin-bottom: 10px; }
.calculator-expr-line {
  min-height: 18px; text-align: right; font-size: 13px; font-weight: 500;
  color: var(--text-dim); padding: 0 14px; overflow-x: auto; white-space: nowrap;
}
.calculator-display {
  width: 100%; box-sizing: border-box; text-align: right; font-size: 30px; font-weight: 600;
  padding: 16px 14px; border-radius: 12px; border: 1.5px solid var(--border);
  background: var(--panel-2, #F4F6FB); color: var(--text); margin: 0;
  overflow-x: auto; white-space: nowrap;
}
.calculator-grid { display: grid; grid-template-columns: repeat(4, 1fr); gap: 8px; }
.calc-btn {
  padding: 16px 0; font-size: 17px; font-weight: 600; border-radius: 10px; border: 1px solid var(--border);
  background: var(--panel); color: var(--text); cursor: pointer;
}
.calc-btn:hover { border-color: var(--accent); }
.calc-btn:active { transform: scale(0.96); }
.calc-btn-op { background: var(--panel-2, #F4F6FB); color: var(--accent); }
.calc-btn-eq { background: var(--accent); color: #fff; border-color: var(--accent); }

.calculator-sci-grid { display: grid; grid-template-columns: repeat(5, 1fr); gap: 6px; margin-bottom: 8px; }
.calc-btn-sci { padding: 11px 0; font-size: 13px; font-weight: 600; background: var(--panel-2, #F4F6FB); color: var(--text-dim); }
.calc-btn-sci.calc-toggle-on { background: var(--accent); color: #fff; border-color: var(--accent); }

.alarm-add-form { display: flex; flex-wrap: wrap; gap: 8px; margin-bottom: 14px; }
.alarm-add-form input[type="time"] { padding: 9px 10px; border-radius: 8px; border: 1.5px solid var(--border); font-size: 13px; }
.alarm-add-form input[type="text"] { flex: 1; min-width: 160px; padding: 9px 10px; border-radius: 8px; border: 1.5px solid var(--border); font-size: 13px; }

.alarm-list { display: flex; flex-direction: column; gap: 8px; max-width: 440px; }
@media (min-width: 900px) {
  .alarm-list { max-width: 720px; }
}

/* First Aid tool: emergency number grid + accordion guide */
.firstaid-emergency-box { border: 1.5px solid var(--danger); background: rgba(229,72,77,0.06); border-radius: 12px; padding: 12px 14px; max-width: 520px; }
.firstaid-emergency-grid { display: grid; grid-template-columns: repeat(2, minmax(140px, 1fr)); gap: 8px; }
.firstaid-emergency-item {
  display: flex; flex-direction: column; gap: 2px; padding: 8px 10px; border-radius: 9px;
  background: var(--panel); border: 1px solid var(--border); text-decoration: none; color: var(--text);
}
.firstaid-emergency-item:hover { border-color: var(--danger); }
.firstaid-emergency-item span { font-size: 11px; color: var(--text-dim); }
.firstaid-emergency-item b { font-size: 15px; color: var(--danger); letter-spacing: 0.3px; }

.firstaid-accordion { display: flex; flex-direction: column; gap: 8px; max-width: 620px; }
.firstaid-item { border: 1px solid var(--border); border-radius: 10px; background: var(--panel); overflow: hidden; }
.firstaid-item summary {
  cursor: pointer; padding: 11px 14px; font-size: 13.5px; font-weight: 700; list-style: none;
  display: flex; align-items: center; justify-content: space-between;
}
.firstaid-item summary::-webkit-details-marker { display: none; }
.firstaid-item summary::after { content: '+'; color: var(--text-dim); font-size: 16px; font-weight: 400; }
.firstaid-item[open] summary::after { content: '−'; }
.firstaid-item[open] summary { border-bottom: 1px solid var(--border); }
.firstaid-item ol { margin: 0; padding: 12px 14px 12px 30px; font-size: 12.5px; line-height: 1.7; color: var(--text); }
.firstaid-item ol li { margin-bottom: 4px; }
.firstaid-item ol li:last-child { margin-bottom: 0; }

/* Respiratory Rate tool - timer + tap counter (inside First Aid) */
.rr-dur-btn.active { background: var(--accent); color: #fff; border-color: var(--accent); }
.rr-tap-btn {
  width: 150px; height: 150px; border-radius: 50%; border: none;
  background: var(--accent); color: #fff; font-size: 15px; font-weight: 600;
  line-height: 1.5; cursor: pointer; user-select: none; touch-action: manipulation;
  box-shadow: 0 4px 14px rgba(0,0,0,0.18); transition: transform 0.08s ease;
}
.rr-tap-btn:active { transform: scale(0.93); }
.rr-result-badge {
  display: inline-flex; flex-direction: column; align-items: center; justify-content: center;
  width: 150px; height: 150px; border-radius: 50%; margin: 0 auto;
  border: 4px solid var(--border); background: var(--panel);
}
.rr-result-badge.status-normal { border-color: var(--success, #2e9e5b); color: var(--success, #2e9e5b); }
.rr-result-badge.status-low,
.rr-result-badge.status-high { border-color: var(--danger); color: var(--danger); }
.rr-history-row {
  display: flex; justify-content: space-between; align-items: center;
  padding: 8px 10px; border: 1px solid var(--border); border-radius: 9px; margin-bottom: 6px;
}
.rr-history-row b { color: var(--text); font-size: 13px; }
.rr-history-badge { font-size: 10.5px; font-weight: 600; padding: 2px 8px; border-radius: 20px; }
.rr-history-badge.status-normal { background: rgba(46,158,91,0.12); color: var(--success, #2e9e5b); }
.rr-history-badge.status-low,
.rr-history-badge.status-high { background: rgba(229,72,77,0.1); color: var(--danger); }
.rr-history-badge.status-elevated { background: rgba(230,159,0,0.12); color: #b5790a; }
.rr-history-badge.status-crisis { background: var(--danger); color: #fff; }

/* Blood Pressure tool - manual log (inside First Aid) */
.bp-field-row { display: flex; gap: 8px; margin-bottom: 10px; }
.bp-field-row .field { flex: 1; margin: 0; }
.bp-field-row input {
  width: 100%; padding: 9px; border-radius: 9px; border: 1.5px solid var(--border); font-size: 14px;
}
.bp-field-row label { font-size: 11px; color: var(--text-dim); display: block; margin-bottom: 4px; }
.bp-result-box {
  border-radius: 12px; padding: 14px; text-align: center; margin-top: 4px;
  border: 1.5px solid var(--border); background: var(--panel);
}
.bp-result-box.status-normal { border-color: var(--success, #2e9e5b); }
.bp-result-box.status-elevated { border-color: #e69f00; }
.bp-result-box.status-low,
.bp-result-box.status-high { border-color: var(--danger); }
.bp-result-box.status-crisis { border-color: var(--danger); background: rgba(229,72,77,0.08); }
#bpResultReading { font-size: 22px; font-weight: 700; color: var(--text); }
#bpResultLabel { font-size: 13px; font-weight: 600; margin-top: 2px; }
.status-normal #bpResultLabel { color: var(--success, #2e9e5b); }
.status-elevated #bpResultLabel { color: #b5790a; }
.status-low #bpResultLabel,
.status-high #bpResultLabel,
.status-crisis #bpResultLabel { color: var(--danger); }

/* Stopwatch */
.stopwatch-display {
  font-size: 46px; font-weight: 700; text-align: center; letter-spacing: 1px;
  font-variant-numeric: tabular-nums; margin: 18px 0 22px; color: var(--text);
}
.stopwatch-btn-row { display: flex; justify-content: center; align-items: center; gap: 12px; }
.stopwatch-lap-row {
  display: flex; justify-content: space-between; padding: 8px 10px;
  border: 1px solid var(--border); border-radius: 9px; margin-bottom: 6px; font-size: 13px;
}
.stopwatch-lap-row .lap-num { color: var(--text-dim); }
.stopwatch-lap-row .lap-time { font-variant-numeric: tabular-nums; color: var(--text); font-weight: 600; }
.stopwatch-lap-row .lap-split { color: var(--text-dim); font-size: 11.5px; }

/* ঘড়ি / ওয়ার্ল্ড ক্লক */
.clock-local-wrap { text-align: center; padding: 10px 0; }
.clock-local-date { font-size: 14.5px; font-weight: 600; color: var(--text); margin-top: -8px; }
.clock-local-tz { font-size: 12px; color: var(--text-dim); margin-top: 4px; }
.world-clock-cards {
  display: flex; gap: 14px; flex-wrap: wrap; justify-content: center; margin-bottom: 16px;
}
.world-clock-card {
  flex: 1 1 220px; max-width: 280px; border: 1px solid var(--border); border-radius: 12px;
  background: var(--panel); padding: 14px 16px; text-align: center;
}
.world-clock-card-label { font-size: 12px; font-weight: 700; color: var(--text-dim); margin-bottom: 6px; }
.world-clock-card-time {
  font-size: 30px; font-weight: 700; font-variant-numeric: tabular-nums; color: var(--text); letter-spacing: 0.5px;
}
.world-clock-card-date { font-size: 12.5px; color: var(--text); margin-top: 4px; }
.world-clock-card-tz { font-size: 11px; color: var(--text-dim); margin-top: 2px; }
.world-clock-diff {
  text-align: center; font-size: 14.5px; color: var(--text); background: var(--bg);
  border: 1px dashed var(--border); border-radius: 9px; padding: 10px 14px; max-width: 480px; margin: 0 auto;
}
.world-clock-diff b { color: var(--accent-dark, var(--accent)); font-size: 16px; }

/* Unit Converter */
.uc-convert-box { max-width: 480px; }
.uc-result-value {
  flex: 1; padding: 9px 12px; border-radius: 9px; border: 1.5px solid var(--border);
  background: var(--panel); font-size: 16px; font-weight: 700; color: var(--accent);
  font-variant-numeric: tabular-nums; overflow-wrap: anywhere;
}

.alarm-row {
  display: flex; align-items: center; gap: 10px; padding: 10px 12px; border-radius: 10px;
  border: 1px solid var(--border); background: var(--panel);
}
.alarm-row.disabled { opacity: 0.55; }
.alarm-row .alarm-row-time { font-size: 18px; font-weight: 700; min-width: 68px; color: var(--text); }
.alarm-row .alarm-row-info { flex: 1; min-width: 0; }
/* Labels were 12.5px in the plain body-text color and the sub-line a washed-
   out 10.5px grey - fine on a cramped mobile card, but next to all the
   spare width on desktop it read as small and low-contrast rather than
   professional. Bump both up a step and darken the sub-line so it's still
   clearly secondary text but no longer feels faint. */
.alarm-row .alarm-row-label { font-size: 14.5px; font-weight: 700; color: var(--text); }
.alarm-row .alarm-row-sub { font-size: 12px; color: #566072; }
.alarm-row .alarm-row-del {
  background: none; border: none; color: var(--danger); font-size: 15px; cursor: pointer; padding: 4px 6px;
}

/* Important notes tool */
.note-add-form { display: flex; flex-direction: column; gap: 8px; max-width: 440px; margin-bottom: 4px; }
.note-add-form input[type="text"] { padding: 9px 10px; border-radius: 8px; border: 1.5px solid var(--border); font-size: 13px; }
.note-add-form textarea {
  padding: 9px 10px; border-radius: 8px; border: 1.5px solid var(--border); font-size: 13px; resize: vertical;
  font-family: inherit;
}
.note-row {
  display: flex; align-items: flex-start; gap: 10px; padding: 10px 12px; border-radius: 10px;
  border: 1px solid var(--border); background: var(--panel);
}
.note-row .note-row-info { flex: 1; min-width: 0; }
.note-row .note-row-title { font-size: 13px; font-weight: 700; color: var(--text); word-break: break-word; }
.note-row .note-row-body { font-size: 12px; color: var(--text-dim); white-space: pre-wrap; word-break: break-word; margin-top: 3px; }
.note-row .note-row-time { font-size: 10px; color: var(--text-dim); margin-top: 5px; }
.note-row .note-row-actions { display: flex; flex-direction: column; gap: 4px; flex-shrink: 0; }
.note-row .note-row-actions button {
  background: none; border: none; font-size: 14px; cursor: pointer; padding: 3px 6px;
}
.note-row .note-row-edit { color: var(--accent); }
.note-row .note-row-del { color: var(--danger); }

/* Meeting/voice recording tool - records to a local Blob and downloads it
   straight to the device; nothing here ever touches the server. */
.rec-mode-row { display: flex; gap: 8px; margin-bottom: 12px; }
.rec-mode-btn.active { background: var(--accent); border-color: var(--accent); color: #fff; }
.rec-video-preview {
  width: 100%; max-width: 360px; border-radius: 10px; background: #000; margin-bottom: 12px; display: block;
}
.rec-controls { display: flex; align-items: center; gap: 10px; flex-wrap: wrap; }
.rec-timer { font-size: 15px; font-weight: 700; color: var(--danger); font-variant-numeric: tabular-nums; }
.rec-status { font-size: 12px; color: var(--text-dim); margin-top: 8px; min-height: 16px; }
.rec-list { display: flex; flex-direction: column; gap: 8px; max-width: 440px; margin-top: 14px; }
.rec-row {
  display: flex; flex-direction: column; gap: 6px; padding: 10px 12px; border-radius: 10px;
  border: 1px solid var(--border); background: var(--panel);
}
.rec-row .rec-row-top { display: flex; justify-content: space-between; align-items: center; gap: 8px; font-size: 12px; color: var(--text-dim); }
.rec-row audio, .rec-row video { width: 100%; max-height: 220px; }
.rec-row .rec-row-actions { display: flex; gap: 10px; flex-wrap: wrap; }
.rec-row .rec-row-actions a, .rec-row .rec-row-actions button {
  font-size: 12px; color: var(--accent); background: none; border: none; cursor: pointer; text-decoration: none; padding: 0;
}

/* Document scanner tool - camera capture -> draggable-corner perspective
   crop -> scan filter -> multi-page stack -> PDF/image export. */
.scan-entry-row { display: flex; gap: 10px; flex-wrap: wrap; }
.scan-camera-wrap { max-width: 420px; margin: 0 auto; }
.scan-video { width: 100%; border-radius: 10px; background: #000; display: block; }
.scan-camera-controls { display: flex; align-items: center; justify-content: center; gap: 10px; flex-wrap: wrap; margin-top: 14px; }
.scan-shutter-btn { border-radius: 999px !important; }

.scan-crop-wrap {
  position: relative; max-width: 420px; margin: 0 auto; user-select: none; touch-action: none;
  background: #000; border-radius: 8px; overflow: hidden;
}
.scan-crop-img { width: 100%; display: block; pointer-events: none; }
.scan-crop-svg { position: absolute; inset: 0; width: 100%; height: 100%; pointer-events: none; }
.scan-crop-svg polygon { fill: rgba(60, 150, 255, 0.22); stroke: var(--accent); stroke-width: 2; }
.scan-handle {
  position: absolute; width: 26px; height: 26px; margin-left: -13px; margin-top: -13px;
  border-radius: 50%; background: var(--accent); border: 3px solid #fff;
  box-shadow: 0 1px 4px rgba(0,0,0,.4); cursor: grab; touch-action: none;
}
.scan-handle:active { cursor: grabbing; }

.scan-filter-preview-wrap { max-width: 420px; margin: 0 auto; background: repeating-conic-gradient(#e8e8e8 0% 25%, #fff 0% 50%) 50% / 16px 16px; border-radius: 8px; overflow: hidden; }
.scan-filter-canvas { width: 100%; display: block; }
.scan-filter-row { display: flex; gap: 8px; flex-wrap: wrap; justify-content: center; margin-top: 12px; }
.scan-filter-btn.active { background: var(--accent); border-color: var(--accent); color: #fff; }

.scan-adjust-row { display: flex; flex-direction: column; gap: 4px; max-width: 420px; margin: 14px auto 0; }
.scan-adjust-row label { font-size: 11.5px; color: var(--text-dim); }
.scan-adjust-row input[type="range"] { width: 100%; margin-bottom: 6px; }

.scan-filmstrip { display: flex; gap: 10px; flex-wrap: wrap; margin-top: 14px; }
.scan-page-thumb { position: relative; width: 92px; transition: opacity .15s ease; }
.scan-page-thumb img {
  width: 92px; height: 122px; object-fit: cover; border-radius: 7px;
  border: 1.5px solid var(--border); cursor: pointer; display: block; background: #fff;
}
.scan-page-thumb .scan-page-num {
  position: absolute; top: 4px; left: 4px; background: rgba(0,0,0,.6); color: #fff;
  font-size: 10.5px; padding: 1px 6px; border-radius: 999px;
}
.scan-page-thumb .scan-page-move { position: absolute; bottom: 4px; display: flex; gap: 3px; width: 100%; justify-content: center; }
.scan-page-thumb .scan-page-move button {
  font-size: 10px; padding: 1px 5px; border-radius: 5px; border: none; background: rgba(0,0,0,.6); color: #fff; cursor: pointer;
}
.scan-page-drag-handle {
  position: absolute; top: 4px; right: 4px; width: 20px; height: 18px; border-radius: 5px;
  background: rgba(0,0,0,.6); color: #fff; font-size: 12px; line-height: 18px; text-align: center;
  cursor: grab; touch-action: none; user-select: none; z-index: 2;
}
.scan-page-drag-handle:active { cursor: grabbing; }
.scan-page-thumb.dragging { opacity: 0.45; }
.scan-page-thumb.drag-target img { outline: 2px dashed var(--accent); outline-offset: 2px; }
.scan-actions-row { display: flex; gap: 8px; flex-wrap: wrap; margin-top: 16px; }

/* Barcode Scanner tool - live camera detection via the browser's native
   BarcodeDetector API (QR + common 1D/2D formats). */
.bcode-scan-flash {
  position: absolute; inset: 0; border-radius: 10px; pointer-events: none;
  border: 3px solid var(--accent); opacity: 0; transition: opacity .15s ease;
}
.bcode-scan-flash.hit { opacity: 1; border-color: #2ecc71; }
.scan-camera-wrap { position: relative; }
.bcode-result-box {
  max-width: 420px; margin: 16px auto 0; padding: 12px 14px; border-radius: 10px;
  border: 1.5px solid var(--accent); background: var(--panel);
}
.bcode-result-type { font-size: 11px; color: var(--text-dim); text-transform: uppercase; letter-spacing: .04em; margin-bottom: 4px; }
.bcode-result-value { font-size: 14px; word-break: break-all; }
.bcode-history-list { display: flex; flex-direction: column; gap: 8px; margin-top: 10px; max-width: 520px; }
.bcode-history-item {
  display: flex; align-items: center; justify-content: space-between; gap: 10px;
  padding: 9px 12px; border-radius: 9px; border: 1px solid var(--border); background: var(--panel);
}
.bcode-history-item .bcode-hist-main { min-width: 0; }
.bcode-history-item .bcode-hist-value { font-size: 13px; word-break: break-all; }
.bcode-history-item .bcode-hist-meta { font-size: 10.5px; color: var(--text-dim); margin-top: 2px; }
.bcode-history-item .bcode-hist-actions { display: flex; gap: 6px; flex-shrink: 0; }
.bcode-history-item .bcode-hist-actions button {
  font-size: 11px; padding: 4px 8px; border-radius: 6px; border: 1px solid var(--border);
  background: none; color: var(--accent); cursor: pointer;
}

/* Compass tool - a static ring of N/E/S/W labels that rotates under a fixed
   pointer, so the pointer always shows the direction the device is
   currently facing (same convention as most phone compass apps). */
.compass-dial-outer { position: relative; width: 220px; height: 220px; margin: 0 auto 16px; }
.compass-pointer {
  position: absolute; top: -8px; left: 50%; transform: translateX(-50%);
  font-size: 20px; line-height: 1; color: var(--accent); z-index: 2;
}
.compass-dial {
  width: 100%; height: 100%; border-radius: 50%; border: 3px solid var(--border);
  background: var(--panel-2, #F4F6FB); position: relative;
  transition: transform 0.15s ease-out;
}
.compass-label { position: absolute; font-weight: 700; font-size: 14px; color: var(--text); }
.compass-n { top: 10px; left: 50%; transform: translateX(-50%); color: var(--danger); }
.compass-e { right: 12px; top: 50%; transform: translateY(-50%); }
.compass-s { bottom: 10px; left: 50%; transform: translateX(-50%); }
.compass-w { left: 12px; top: 50%; transform: translateY(-50%); }
.compass-reading { font-size: 26px; font-weight: 700; color: var(--text); }
.compass-direction { font-size: 14px; font-weight: 600; color: #4A5568; margin-top: 2px; }

/* Namaz & Azan tool - auto-calculated times, Hijri/Ramadan/Jumma info,
   next-waqt countdown, and a Qibla direction finder that reuses the same
   device-orientation dial styling as the plain Compass tool above. */
.alarm-row.namaz-active { border-color: var(--accent); background: rgba(60, 150, 255, 0.08); }
.alarm-row .alarm-row-offset {
  font-size: 11.5px; border: 1px solid var(--border); border-radius: 7px; padding: 4px 6px;
  background: var(--panel); color: #4A5568; font-weight: 600; flex-shrink: 0;
}
.namaz-meta-card {
  display: flex; flex-wrap: wrap; gap: 8px; align-items: center; padding: 10px 12px; border-radius: 10px;
  border: 1px solid var(--border); background: var(--panel); margin-bottom: 10px; font-size: 13px; font-weight: 500; color: #4A5568;
}
.namaz-meta-card .namaz-hijri-date { font-weight: 700; color: var(--text); }
.namaz-meta-card .namaz-jumma-badge {
  background: var(--accent); color: #fff; font-size: 10.5px; font-weight: 700; padding: 2px 8px; border-radius: 999px;
}
.namaz-ramadan-card {
  display: flex; gap: 18px; padding: 12px 14px; border-radius: 10px; margin-bottom: 10px; flex-wrap: wrap;
  background: #FFF8E1; border: 1px solid #FFD54F; max-width: 460px;
}
@media (min-width: 900px) {
  .namaz-ramadan-card, .namaz-meta-card { max-width: 720px; }
}
.namaz-ramadan-card .namaz-ramadan-item { font-size: 12.5px; color: #7A5B00; }
.namaz-ramadan-card .namaz-ramadan-item b { display: block; font-size: 15px; }
.ramadan-cal-list { display: flex; flex-direction: column; gap: 6px; max-height: 360px; overflow-y: auto; }
.ramadan-cal-row {
  display: flex; align-items: center; gap: 10px; padding: 8px 10px; border-radius: 8px;
  border: 1px solid var(--border); background: var(--panel); font-size: 12.5px;
}
.ramadan-cal-row.ramadan-cal-row-today { border-color: var(--accent); background: rgba(60, 150, 255, 0.08); }
.ramadan-cal-row .ramadan-cal-day { flex: 0 0 auto; min-width: 78px; color: var(--text-dim); }
.ramadan-cal-row .ramadan-cal-day b { color: var(--text); font-weight: 700; }
.ramadan-cal-row .ramadan-cal-times { flex: 1; display: flex; gap: 14px; justify-content: flex-end; flex-wrap: wrap; }
.ramadan-cal-row .ramadan-cal-time-item { text-align: right; }
.ramadan-cal-row .ramadan-cal-time-label { font-size: 10.5px; color: var(--text-dim); }
.ramadan-cal-row .ramadan-cal-time-value { font-weight: 700; color: var(--text); font-variant-numeric: tabular-nums; }
.namaz-countdown-box {
  text-align: center; padding: 12px; border-radius: 10px; margin-bottom: 12px;
  background: var(--panel); border: 1px solid var(--border); max-width: 460px;
}
.namaz-countdown-box .namaz-countdown-label { font-size: 11.5px; color: var(--text-dim); }
.namaz-countdown-box .namaz-countdown-time { font-size: 22px; font-weight: 700; color: var(--accent); font-variant-numeric: tabular-nums; }
.qibla-kaaba-icon {
  position: absolute; top: 8px; left: 50%; font-size: 30px; line-height: 1;
  transform: translateX(-50%); transform-origin: 50% 82px;
  /* Smooths out the raw, jittery device-orientation readings the same
     way .compass-dial already does for the plain Compass tool - without
     this the icon snapped instantly to every noisy sensor sample. */
  transition: transform 0.15s ease-out;
}

/* Digital Tasbih (dhikr counter) tool */
.tasbih-dhikr-label { font-size: 15px; font-weight: 700; color: var(--text); margin-bottom: 10px; }
.tasbih-tap-btn {
  display: flex; flex-direction: column; align-items: center; justify-content: center;
  width: 160px; height: 160px; margin: 0 auto; border-radius: 50%; border: none; cursor: pointer;
  background: linear-gradient(180deg, var(--accent), #2E7DD6); color: #fff;
  box-shadow: 0 6px 18px rgba(46, 125, 214, 0.35); user-select: none; -webkit-tap-highlight-color: transparent;
  transition: transform 0.08s ease;
}
.tasbih-tap-btn:active { transform: scale(0.94); }
.tasbih-tap-btn #tasbihCount { font-size: 44px; font-weight: 800; line-height: 1; font-variant-numeric: tabular-nums; }
.tasbih-tap-btn .tasbih-tap-hint { font-size: 11.5px; opacity: 0.85; margin-top: 4px; }
/* Same fix as the other ইসলামী জীবন tools: round-target/total labels were
   12px in the faint var(--text-dim) grey - fine tucked into a narrow mobile
   card, weak next to the tap button's huge 44px counter on desktop. */
.tasbih-meta-row { font-size: 13px; font-weight: 600; color: #4A5568; margin-top: 10px; display: flex; justify-content: center; gap: 16px; flex-wrap: wrap; }
/* .small-btn (used by these two) has no :active/transition of its own,
   so unlike .tasbih-tap-btn above they gave zero tap feedback - felt
   unresponsive/"not smooth" especially on mobile, where there's no
   :hover to fall back on. Give them the same quick press feedback. */
#tasbihUndoBtn, #tasbihResetBtn {
  transition: transform 0.08s ease, opacity 0.08s ease;
  -webkit-tap-highlight-color: transparent;
}
#tasbihUndoBtn:active, #tasbihResetBtn:active { transform: scale(0.93); opacity: 0.8; }

/* Proyojonio Dua (essential daily duas) tool, inside Namaz o Azan */
/* Category row (সকল/দৈনন্দিন কাজ/ঘর/...) is a plain .task-filter-row, which
   has no wrap or scroll of its own - on narrow phones the buttons just ran
   off the right edge with no way to reach them (see uploaded screenshot).
   Turn just this row into a left-right swipeable slider instead of touching
   the shared .task-filter-row rule other tabs rely on. */
#duaCatRow {
  flex-wrap: nowrap; overflow-x: auto; -webkit-overflow-scrolling: touch;
  scrollbar-width: none; justify-content: flex-start !important;
  padding-bottom: 2px; scroll-snap-type: x proximity;
}
#duaCatRow::-webkit-scrollbar { display: none; }
#duaCatRow [data-duacat] { flex-shrink: 0; white-space: nowrap; scroll-snap-align: start; }
.dua-list { display: flex; flex-direction: column; gap: 10px; max-width: 620px; margin: 0 auto; }
@media (min-width: 900px) {
  .dua-list { max-width: 720px; }
}
.dua-card { border: 1px solid var(--border); border-radius: 12px; background: var(--panel); padding: 12px 14px; }
.dua-card-head { display: flex; align-items: baseline; justify-content: space-between; gap: 8px; margin-bottom: 8px; flex-wrap: wrap; }
.dua-card-title { font-size: 14.5px; font-weight: 700; color: var(--text); }
.dua-card-ref { font-size: 12px; font-weight: 600; color: #566072; white-space: nowrap; }
.dua-arabic-row { display: flex; align-items: center; gap: 8px; margin-bottom: 8px; }
.dua-arabic { flex: 1; }
.dua-audio-btn {
  flex-shrink: 0; width: 30px; height: 30px; border-radius: 50%;
  border: 1.5px solid var(--border); background: var(--bg); cursor: pointer;
  font-size: 14px; display: flex; align-items: center; justify-content: center;
  padding: 0; line-height: 1; -webkit-tap-highlight-color: transparent;
  transition: transform 0.08s ease, background 0.15s ease, border-color 0.15s ease;
}
.dua-audio-btn:hover { border-color: var(--accent); }
.dua-audio-btn:active { transform: scale(0.92); }
.dua-audio-btn.speaking { background: var(--accent); border-color: var(--accent); animation: dua-audio-pulse 1s ease-in-out infinite; }
@keyframes dua-audio-pulse { 0%, 100% { opacity: 1; } 50% { opacity: 0.6; } }
.dua-arabic {
  font-family: 'Amiri', 'Traditional Arabic', 'Scheherazade New', serif;
  direction: rtl; text-align: right; font-size: 21px; line-height: 2;
  color: var(--text); unicode-bidi: plaintext;
}
/* Same fix as namaz/Quran: transliteration/meaning/ref lines were 10.5-12.5px
   in a faint grey, cramped inside the old 420px panel cap. Sized and
   darkened to match, and widened the card list above on desktop. */
.dua-translit { font-size: 13px; color: var(--accent-dark); font-style: italic; margin-bottom: 6px; line-height: 1.6; }
.dua-translit-bn { font-style: normal; opacity: 0.85; margin-top: -4px; }
.dua-meaning { font-size: 13.5px; color: var(--text); line-height: 1.7; }
.dua-cat-empty { font-size: 12.5px; color: #566072; text-align: center; padding: 14px 0; }
.dua-audio-note { font-size: 11.5px; color: #566072; margin-top: 6px; font-style: italic; }

/* কুরআন মাজীদ (full Qur'an reader) */
.quran-surah-list { display: flex; flex-direction: column; gap: 6px; max-width: 620px; margin: 0 auto; }
@media (min-width: 900px) {
  .quran-surah-list { max-width: 720px; }
}
.quran-surah-row {
  display: flex; align-items: center; gap: 12px; border: 1px solid var(--border); border-radius: 10px;
  background: var(--panel); padding: 10px 12px; cursor: pointer; font-family: inherit; text-align: left; width: 100%;
  transition: border-color 0.15s ease, background 0.15s ease;
}
.quran-surah-row:hover { border-color: var(--accent); }
.quran-surah-num {
  flex-shrink: 0; width: 28px; height: 28px; border-radius: 50%; background: var(--bg);
  border: 1.5px solid var(--border); display: flex; align-items: center; justify-content: center;
  font-size: 12.5px; font-weight: 700; color: #4A5568;
}
.quran-surah-mid { flex: 1; min-width: 0; }
.quran-surah-name-ar { font-family: 'Amiri', 'Traditional Arabic', 'Scheherazade New', serif; font-size: 16px; direction: rtl; text-align: right; color: var(--text); }
/* Same fix as the namaz list: the Bangla name, ayah/page count, and reader
   subtitle were 10.5-12px in the faint var(--text-dim) grey - cramped and
   washed out on a wide desktop screen. Sized and darkened to match. */
.quran-surah-name-bn { font-size: 13px; font-weight: 600; color: var(--text); margin-top: 2px; }
.quran-surah-meta { flex-shrink: 0; font-size: 12px; color: #566072; white-space: nowrap; }
.quran-reader-head { text-align: center; margin-bottom: 14px; padding-bottom: 12px; border-bottom: 1px dashed var(--border); }
.quran-reader-title-ar { font-family: 'Amiri', 'Traditional Arabic', 'Scheherazade New', serif; font-size: 22px; color: var(--text); }
.quran-reader-title-bn { font-size: 13.5px; font-weight: 600; color: #566072; margin-top: 4px; }
.quran-voice-gender-row {
  display: flex; align-items: center; justify-content: center; gap: 8px; margin-top: 10px;
  font-size: 12px; color: #566072;
}
.quran-voice-gender-row select {
  padding: 5px 8px; border-radius: 7px; border: 1.5px solid var(--border); font-size: 12px;
}
.quran-play-surah-btn {
  margin-top: 10px; font-size: 12.5px; font-weight: 600; padding: 8px 16px; border-radius: 20px;
  border: 1.5px solid var(--accent); background: var(--bg); color: var(--accent-dark, var(--accent));
  cursor: pointer; -webkit-tap-highlight-color: transparent; transition: background 0.15s ease, color 0.15s ease;
}
.quran-play-surah-btn:hover { background: var(--accent); color: #fff; }
.quran-play-surah-btn.active { background: var(--accent); color: #fff; animation: dua-audio-pulse 1s ease-in-out infinite; }
.quran-ayah-card.quran-ayah-playing { border-color: var(--accent); box-shadow: 0 0 0 2px var(--accent) inset; }
.quran-bismillah {
  font-family: 'Amiri', 'Traditional Arabic', 'Scheherazade New', serif; direction: rtl; text-align: center;
  font-size: 22px; color: var(--text); margin-bottom: 16px;
}
.quran-ayah-card .dua-arabic { display: inline; }
.quran-ayah-num { font-family: inherit; color: var(--accent-dark, var(--accent)); font-size: 15px; }
.quran-offline-note {
  font-size: 12px; color: #566072; text-align: center; background: var(--panel);
  border: 1px dashed var(--border); border-radius: 8px; padding: 8px 10px; margin-bottom: 14px; line-height: 1.5;
}

/* Weather tool */
.weather-warning-box {
  display: flex; flex-direction: column; gap: 4px; padding: 12px 14px; border-radius: 10px; margin-bottom: 14px;
  background: #FFF3E0; border: 1px solid #FFB74D; max-width: 460px;
}
.weather-warning-box .weather-warning-title { font-weight: 700; font-size: 14px; color: #B45309; }
.weather-warning-box .weather-warning-msg { font-size: 12.5px; color: var(--text); }
.weather-warning-box .weather-warning-temp { font-size: 12px; color: var(--text-dim); }
.weather-current-card {
  display: flex; align-items: center; gap: 16px; padding: 16px 18px; border-radius: 12px; margin-bottom: 14px;
  background: var(--panel); border: 1px solid var(--border); max-width: 460px;
}
.weather-current-card .weather-current-icon { font-size: 46px; line-height: 1; }
.weather-current-card .weather-current-temp { font-size: 30px; font-weight: 700; color: var(--text); }
.weather-current-card .weather-current-desc { font-size: 13px; color: var(--text-dim); }
.weather-current-card .weather-current-meta { font-size: 11.5px; color: var(--text-dim); margin-top: 4px; display: flex; gap: 10px; flex-wrap: wrap; }
.weather-daily-row { display: flex; gap: 10px; overflow-x: auto; padding-bottom: 4px; max-width: 460px; }
.weather-day-chip {
  flex: 0 0 auto; min-width: 78px; text-align: center; padding: 10px 8px; border-radius: 10px;
  border: 1px solid var(--border); background: var(--panel);
}
.weather-day-chip .weather-day-label { font-size: 11.5px; color: var(--text-dim); margin-bottom: 4px; }
.weather-day-chip .weather-day-icon { font-size: 22px; }
.weather-day-chip .weather-day-temps { font-size: 12.5px; font-weight: 600; margin-top: 4px; }
.weather-day-chip .weather-day-precip { font-size: 10.5px; color: var(--accent); margin-top: 2px; }

/* Nearby places tool */
.nearby-category-row { display: flex; gap: 8px; flex-wrap: wrap; margin-bottom: 12px; }
.nearby-cat-btn.active { background: var(--accent); color: #fff; border-color: var(--accent); }
.nearby-map { width: 100%; max-width: 620px; height: 280px; border-radius: 10px; border: 1px solid var(--border); margin-bottom: 12px; }
.nearby-list { display: flex; flex-direction: column; gap: 8px; max-width: 620px; }
.nearby-place-row {
  display: flex; justify-content: space-between; align-items: center; gap: 10px; padding: 10px 12px;
  border-radius: 10px; border: 1px solid var(--border); background: var(--panel); cursor: pointer;
}
.nearby-place-row:hover { border-color: var(--accent); }
.nearby-place-name { font-size: 13px; font-weight: 600; color: var(--text); }
.nearby-place-address { font-size: 11.5px; color: var(--text-dim); margin-top: 2px; }
.nearby-place-distance { font-size: 12px; color: var(--accent); font-weight: 700; white-space: nowrap; }
.nearby-place-dir-link { font-size: 11px; color: var(--text-dim); text-decoration: none; margin-top: 4px; display: inline-block; }
.nearby-place-phone, .nearby-place-website { font-size: 11.5px; color: var(--accent-dark); text-decoration: none; margin-top: 3px; display: block; }
.nearby-schedule-banner {
  display: flex; flex-wrap: wrap; align-items: center; gap: 8px;
  font-size: 12px; color: var(--text);
  background: rgba(31, 174, 142, 0.08);
  border: 1.5px solid var(--accent);
  border-radius: var(--radius);
  padding: 10px 12px;
  margin: 10px 0;
}
.nearby-schedule-banner a.small-btn { text-decoration: none; white-space: nowrap; }

/* Road Traffic / Route Planner tool */
.traffic-dest-suggestions {
  position: absolute; left: 0; right: 0; top: 100%; z-index: 5;
  background: var(--bg); border: 1px solid var(--border); border-radius: 10px;
  margin-top: 4px; max-height: 220px; overflow-y: auto;
  box-shadow: 0 4px 14px rgba(0,0,0,0.12);
}
.traffic-dest-suggestion-row { padding: 9px 12px; font-size: 12.5px; cursor: pointer; border-bottom: 1px solid var(--border); }
.traffic-dest-suggestion-row:last-child { border-bottom: none; }
.traffic-dest-suggestion-row:hover { background: var(--hover-bg, rgba(0,0,0,0.04)); }
.traffic-mode-tabs { display: flex; gap: 8px; margin: 12px 0 10px; flex-wrap: wrap; }
.traffic-mode-tab { padding: 7px 14px; border-radius: 999px; border: 1px solid var(--border); background: var(--bg); font-size: 12.5px; cursor: pointer; }
.traffic-mode-tab.active { background: var(--accent); color: #fff; border-color: var(--accent); }
.traffic-route-row {
  display: flex; justify-content: space-between; align-items: center; gap: 10px;
  border: 1px solid var(--border); border-radius: 10px; padding: 10px 12px; margin-bottom: 8px;
}
.traffic-route-row.best { border-color: var(--accent); background: rgba(31, 174, 142, 0.08); }
.traffic-route-time { font-size: 16px; font-weight: 700; color: var(--text); }
.traffic-route-dist { font-size: 11.5px; color: var(--text-dim); margin-top: 2px; }
.traffic-route-best-tag { font-size: 10.5px; color: var(--accent); font-weight: 700; margin-top: 2px; }
.traffic-disclaimer { font-size: 11px; color: var(--text-dim); margin-top: 6px; }

/* Ticket Search tool (Bus/Air/Launch/Train) */
.ticket-cat-row { display: flex; gap: 8px; flex-wrap: wrap; margin-bottom: 10px; }
.ticket-cat-btn.active { background: var(--accent); color: #fff; border-color: var(--accent); }
.ticket-search-form {
  display: flex; flex-wrap: wrap; gap: 8px; align-items: flex-end;
  border: 1px solid var(--border); border-radius: 10px; background: var(--panel);
  padding: 12px; margin-bottom: 12px; max-width: 620px;
}
.ticket-search-form .ticket-field { display: flex; flex-direction: column; gap: 3px; flex: 1 1 130px; min-width: 110px; }
.ticket-search-form .ticket-field label { font-size: 10.5px; color: var(--text-dim); }
.ticket-search-form input { padding: 8px 9px; border-radius: 8px; border: 1px solid var(--border); background: var(--bg); font-size: 12.5px; }
.ticket-disclaimer {
  font-size: 11px; color: var(--text-dim); background: rgba(31, 174, 142, 0.08);
  border: 1px solid var(--border); border-radius: 8px; padding: 8px 10px; margin-bottom: 12px; max-width: 620px;
}
.ticket-quicklink-row { display: flex; flex-wrap: wrap; gap: 8px; margin-bottom: 14px; max-width: 620px; }
.ticket-quicklink-card {
  flex: 1 1 160px; border: 1px solid var(--border); border-radius: 10px; background: var(--panel);
  padding: 10px 12px; text-decoration: none; color: var(--text); font-size: 12.5px;
}
.ticket-quicklink-card:hover { border-color: var(--accent); }
.ticket-quicklink-card .ticket-quicklink-title { font-weight: 700; margin-bottom: 2px; }
.ticket-quicklink-card .ticket-quicklink-sub { font-size: 11px; color: var(--text-dim); }
.ticket-op-list { display: flex; flex-direction: column; gap: 8px; max-width: 620px; }
.ticket-op-row {
  padding: 10px 12px; border-radius: 10px; border: 1px solid var(--border); background: var(--panel);
}
.ticket-op-row.route-matched { border-color: var(--accent); }
.ticket-op-name { font-size: 13px; font-weight: 600; color: var(--text); }
.ticket-op-meta { font-size: 11.5px; color: var(--text-dim); margin-top: 2px; }
.ticket-op-price { font-size: 12px; color: var(--accent); font-weight: 700; margin-top: 3px; }
.ticket-op-actions { display: flex; gap: 10px; flex-wrap: wrap; margin-top: 5px; }
.ticket-op-actions a, .ticket-op-actions button { font-size: 11.5px; color: var(--accent-dark); text-decoration: none; }
.link-btn { background: none; border: none; padding: 0; font: inherit; cursor: pointer; }
.ticket-admin-form {
  display: flex; flex-wrap: wrap; gap: 8px; border: 1px dashed var(--border); border-radius: 10px;
  padding: 12px; margin-top: 14px; max-width: 620px;
}
.ticket-admin-form .ticket-field { display: flex; flex-direction: column; gap: 3px; flex: 1 1 150px; }
.ticket-admin-form .ticket-field label { font-size: 10.5px; color: var(--text-dim); }
.ticket-admin-form input, .ticket-admin-form select { padding: 8px 9px; border-radius: 8px; border: 1px solid var(--border); background: var(--bg); font-size: 12.5px; }

/* Group Live Location Share (PIN) tool */
.locshare-pin-banner {
  display: flex; justify-content: space-between; align-items: center; flex-wrap: wrap; gap: 8px;
  background: rgba(31, 174, 142, 0.1); border: 1px solid var(--accent); border-radius: 10px;
  padding: 10px 14px; margin-bottom: 12px; max-width: 620px;
}
.locshare-pin-banner .locshare-pin-value { font-size: 20px; font-weight: 800; letter-spacing: 2px; color: var(--accent); }
.locshare-pin-banner .locshare-pin-label { font-size: 11px; color: var(--text-dim); }
.locshare-pin-banner .locshare-expiry { font-size: 12px; color: var(--text-dim); }
.locshare-member-row {
  display: flex; justify-content: space-between; align-items: center; gap: 10px; padding: 10px 12px;
  border-radius: 10px; border: 1px solid var(--border); background: var(--panel);
}
.locshare-member-row .locshare-member-name { font-size: 13px; font-weight: 600; color: var(--text); }
.locshare-member-row .locshare-member-meta { font-size: 11.5px; color: var(--text-dim); margin-top: 2px; }
.locshare-member-row .locshare-member-distance { font-size: 12px; color: var(--accent); font-weight: 700; white-space: nowrap; }

/* Toggle switch reused for both "on/off" alarms and namaz azan rows */
.tool-switch { position: relative; width: 40px; height: 22px; flex-shrink: 0; }
.tool-switch input { opacity: 0; width: 0; height: 0; }
.tool-switch .tool-switch-track {
  position: absolute; inset: 0; background: #CBD3E3; border-radius: 999px; cursor: pointer; transition: background 0.15s;
}
.tool-switch .tool-switch-track::before {
  content: ""; position: absolute; width: 18px; height: 18px; left: 2px; top: 2px; background: #fff;
  border-radius: 50%; transition: transform 0.15s; box-shadow: 0 1px 3px rgba(0,0,0,0.25);
}
.tool-switch input:checked + .tool-switch-track { background: var(--accent); }
.tool-switch input:checked + .tool-switch-track::before { transform: translateX(18px); }

/* Ringing popup for both alarms and azan */
.alarm-ring-modal { text-align: center; max-width: 320px; }
.alarm-ring-icon { font-size: 46px; margin-bottom: 4px; animation: alarmShake 0.6s infinite; }
.alarm-ring-time { font-size: 28px; font-weight: 700; margin: 6px 0 18px; }
.alarm-ring-actions { display: flex; gap: 10px; justify-content: center; }
@keyframes alarmShake {
  0%, 100% { transform: rotate(0deg); }
  25% { transform: rotate(-8deg); }
  75% { transform: rotate(8deg); }
}

/* ---------- Responsive ---------- */
.hamburger { display: none; }
.back-to-chats-btn { display: none; }
.sidebar-backdrop { display: none; }
@media (max-width: 820px) {
  .app { grid-template-columns: 1fr; }
  /* Mirrors .hamburger's fixed circular-button look, mirrored to the
     top-right corner so it never overlaps the hamburger (top-left) or
     the left-padding every mobile header already reserves for it. JS
     only ever toggles the .show class (see the '.tab-btn' handler),
     never inline display - keeping the actual show/hide rule here,
     inside the mobile-only media query, is what keeps this button from
     ever appearing on desktop (where the sidebar tabs already cover
     this) even while .show is applied on a wide window. */
  .back-to-chats-btn.show {
    /* calc(12px + safe-area-inset-top) instead of a bare 12px keeps this
       clear of the iPhone status bar/notch area on standalone/PWA installs
       (see .sidebar's comment above) - previously it sat underneath the
       status bar there, which is why tapping the X to leave a tile/tab
       appeared to do nothing. */
    position: fixed; top: calc(12px + env(safe-area-inset-top, 0px)); right: 12px; z-index: 50;
    display: flex; width: 38px; height: 38px; border-radius: 50%;
    /* background was var(--panel) (white) with color:white for the icon -
       a white "X" on a white circle, invisible. The border/shadow below
       were always styled for a dark button, so var(--ink) (same dark navy
       as the sidebar) is the intended background, not white. */
    background: var(--ink); color: white; border: 1px solid rgba(255,255,255,0.12);
    box-shadow: 0 2px 10px rgba(0,0,0,0.35);
    align-items: center; justify-content: center;
    cursor: pointer;
  }
  .sidebar {
    position: fixed; top: 0; left: 0; bottom: 0; z-index: 40; transform: translateX(-100%);
    transition: transform .2s; width: 80%; max-width: 300px;
  }
  .sidebar.open { transform: translateX(0); }
  .sidebar-backdrop.show {
    display: block; position: fixed; inset: 0; z-index: 39;
    background: rgba(0,0,0,0.4);
  }
  .hamburger { display: flex; }
  .hamburger {
    /* Same status-bar fix as .back-to-chats-btn.show above. */
    position: fixed; top: calc(12px + env(safe-area-inset-top, 0px)); left: 12px; z-index: 50;
    width: 38px; height: 38px; border-radius: 50%;
    /* Same white-icon-on-white-background bug as .back-to-chats-btn.show
       above - this is what made the hamburger look like a blank white
       circle on mobile. var(--ink) restores the dark button the border/
       shadow were already designed for. */
    background: var(--ink); color: white; border: 1px solid rgba(255,255,255,0.12);
    box-shadow: 0 2px 10px rgba(0,0,0,0.35);
    align-items: center; justify-content: center;
    transition: left 0.2s, right 0.2s;
  }
  /* When the sidebar is open, its own logo/title sits in this same
     top-left corner - move the button clear of it instead of overlapping. */
  .hamburger.sidebar-open { left: auto; right: 12px; }
  /* Every view (.main) reserves space up top so its own header content
     (title, tabs, buttons - whatever that view's markup is) never sits
     underneath the floating button above. This is what makes the button
     act as a consistent "back to menu" control across Chats/Calls/
     Meetings/Tasks/Email/Admin alike, not just the chat screen. */
  /* Reserve room for the floating back/menu button without changing
     .main's total content height (which risked pushing the composer
     below the visible viewport) - shrink the header row itself instead. */
  .chat-header { padding-left: 54px; min-height: 62px; }
  .admin-header { padding-left: 46px; }
  .msg-row { max-width: 85%; }
  .modal { max-width: 94vw; }
  /* iOS Safari auto-zooms the whole page when a focused input's font-size
     is under 16px - combined with maximum-scale=1 in the viewport meta tag
     this is what makes the screen look "stuck"/not fitting after tapping
     the message box. Keeping inputs at >=16px avoids that zoom entirely. */
  .composer textarea, input, select, textarea { font-size: 16px; }

  /* Filter chips (All/Unread/...) stay on ONE line and swipe horizontally
     instead of wrapping to a second row - saves vertical space on small
     screens. (.tabs gets the same treatment globally now, see base rule.) */
  .conv-filter-chips { flex-wrap: nowrap; overflow-x: auto; -webkit-overflow-scrolling: touch; scrollbar-width: none; }
  .conv-filter-chips::-webkit-scrollbar { display: none; }
  .conv-filter-chips .chip { flex: 0 0 auto; white-space: nowrap; }

  /* Smaller phones need a shorter colleagues panel so "সাম্প্রতিক কল" below
     it is never pushed fully off-screen. */
  #callsColleaguesList { max-height: 38vh; }
}

/* ---- Workout / exercise tracker (Tools tab) ---- */
.workout-type-grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(150px, 1fr));
  gap: 8px;
  margin-top: 8px;
}
.workout-type-btn {
  padding: 10px 8px;
  border-radius: var(--radius);
  border: 1.5px solid var(--border);
  background: var(--panel);
  color: var(--text);
  font-size: 12.5px;
  cursor: pointer;
  text-align: center;
}
.workout-type-btn.active {
  border-color: var(--accent);
  background: rgba(31, 174, 142, 0.1);
  color: var(--accent-dark);
  font-weight: 600;
}
.workout-active-card {
  border: 1.5px solid var(--border);
  border-radius: var(--radius);
  padding: 16px;
  background: var(--panel);
}
.workout-active-type { font-weight: 700; font-size: 15px; margin-bottom: 10px; }
.workout-stat-row { display: flex; gap: 10px; }
.workout-stat { flex: 1; text-align: center; }
.workout-stat-val { font-size: 20px; font-weight: 700; color: var(--ink); font-variant-numeric: tabular-nums; }
.workout-stat-lbl { font-size: 11px; color: var(--text-dim); margin-top: 2px; }
.workout-gps-status { font-size: 11.5px; color: var(--text-dim); margin-top: 10px; }

.workout-corner-widget {
  position: fixed;
  right: 12px;
  bottom: 86px;
  z-index: 500;
  display: flex;
  align-items: center;
  gap: 6px;
  padding: 7px 12px;
  border-radius: 999px;
  background: var(--ink);
  color: #fff;
  font-size: 12px;
  font-variant-numeric: tabular-nums;
  box-shadow: 0 4px 14px rgba(0,0,0,0.25);
  cursor: pointer;
}
@media (min-width: 769px) { .workout-corner-widget { bottom: 20px; } }

/* ---------- Office file viewer & editor (Tools tab) ---------- */
.office-panel .office-drop-area {
  border: 2px dashed var(--border); border-radius: 14px; padding: 34px 16px;
  text-align: center; cursor: pointer; transition: border-color 0.15s ease, background 0.15s ease;
}
.office-panel .office-drop-area:hover,
.office-panel .office-drop-area.dragover { border-color: var(--accent); background: rgba(0,0,0,0.02); }
.office-toolbar {
  display: flex; align-items: center; justify-content: space-between; gap: 10px; flex-wrap: wrap;
  padding: 10px 12px; margin-bottom: 12px; border: 1px solid var(--border); border-radius: 10px; background: var(--panel);
}
.office-filename { font-weight: 700; font-size: 13px; word-break: break-all; }
.office-note { font-size: 11.5px; color: var(--text-dim); margin-bottom: 12px; }
.office-mode-toggle { display: flex; gap: 8px; flex-wrap: wrap; }
.office-mode-btn.active { background: var(--accent); border-color: var(--accent); color: #fff; }

/* Word */
.docx-viewer { max-height: 60vh; overflow-y: auto; border: 1px solid var(--border); border-radius: 10px; padding: 18px 20px; background: #fff; color: #111; }
.docx-para { line-height: 1.8; font-size: 14px; margin-bottom: 4px; min-height: 1.6em; }
.docx-run { outline: none; border-radius: 3px; }
.docx-run:focus { background: rgba(255, 214, 0, 0.28); box-shadow: 0 0 0 1px rgba(0,0,0,0.15); }
.docx-run:hover { background: rgba(0,0,0,0.04); }

/* PowerPoint */
.pptx-viewer { display: flex; flex-direction: column; gap: 14px; max-height: 65vh; overflow-y: auto; }
.pptx-slide-card { border: 1px solid var(--border); border-radius: 12px; padding: 12px 14px; background: var(--panel); }
.pptx-slide-label { font-size: 11.5px; font-weight: 700; color: var(--accent); margin-bottom: 8px; }
.pptx-run-box {
  width: 100%; box-sizing: border-box; resize: none; overflow: hidden; margin-bottom: 6px;
  padding: 8px 10px; border-radius: 8px; border: 1.5px solid var(--border); font-size: 13.5px;
  font-family: inherit; background: var(--panel-2, #F4F6FB); color: var(--text);
}
.pptx-run-box:focus { border-color: var(--accent); outline: none; }

/* Excel / CSV */
.xlsx-sheet-tabs { display: flex; gap: 6px; flex-wrap: wrap; margin-bottom: 10px; }
.xlsx-table-wrap { max-width: 100%; max-height: 55vh; overflow: auto; border: 1px solid var(--border); border-radius: 10px; }
.xlsx-table { border-collapse: collapse; font-size: 12.5px; }
.xlsx-table td {
  border: 1px solid var(--border); padding: 6px 9px; min-width: 70px; white-space: pre-wrap;
  outline: none;
}
.xlsx-table td:focus { background: rgba(255, 214, 0, 0.22); box-shadow: inset 0 0 0 1.5px var(--accent); }
.xlsx-controls { display: flex; gap: 8px; margin-top: 10px; }

/* PDF */
.pdf-viewer { display: flex; flex-direction: column; align-items: center; gap: 16px; max-height: 65vh; overflow-y: auto; }
.pdf-page-wrap { position: relative; box-shadow: 0 2px 10px rgba(0,0,0,0.18); cursor: text; }
.pdf-page-wrap canvas { display: block; }
.pdf-overlay-layer { position: absolute; inset: 0; pointer-events: none; }
.pdf-overlay-box {
  position: absolute; pointer-events: auto; display: flex; align-items: flex-start; gap: 3px;
  background: rgba(255,255,255,0.85); border: 1px dashed var(--accent); border-radius: 3px; padding: 1px 3px;
}
.pdf-overlay-text { min-width: 14px; outline: none; white-space: pre-wrap; }
.pdf-overlay-del {
  border: none; background: var(--danger); color: #fff; border-radius: 50%; width: 15px; height: 15px;
  line-height: 15px; font-size: 9px; padding: 0; cursor: pointer; flex-shrink: 0;
}

/* ---------- Ludo (লুডু) mini-game ---------- */
.ludo-setup .section-title-sm { font-weight: 700; font-size: 12.5px; color: var(--text); margin-bottom: 8px; }
.ludo-status-bar {
  display: flex; align-items: center; flex-wrap: wrap; gap: 10px; margin-bottom: 12px;
}
.ludo-turn-badge {
  color: #fff; font-weight: 700; font-size: 12px; padding: 6px 14px; border-radius: 999px;
  box-shadow: 0 2px 4px rgba(0,0,0,.3), inset 0 1px 0 rgba(255,255,255,.35);
}
/* Dice rendered as a little raised cube with its own highlight/shadow so
   it reads as a physical die rather than a flat unicode glyph. */
.ludo-dice-face {
  font-size: 26px; line-height: 1; min-width: 38px; height: 38px; text-align: center;
  display: inline-flex; align-items: center; justify-content: center; border-radius: 9px;
  background: linear-gradient(160deg, #ffffff 0%, #e8e8ec 55%, #cfd2d8 100%);
  box-shadow: 0 3px 6px rgba(0,0,0,.35), inset 0 1px 0 rgba(255,255,255,.9), inset 0 -2px 3px rgba(0,0,0,.15);
  color: #2b2b33;
}
.ludo-log { flex-basis: 100%; font-size: 12px; color: var(--text-dim); }
/* Plain block layout, NOT flex - a flex row here previously fought with the
   JS-computed `transform: scale()` in fitLudoBoard() (ludo.js): the browser
   would flex-shrink this container's child to fit a narrow phone screen on
   top of (and completely uncoordinated with) that transform, and the two
   shrinks stacking is what caused the board to render off-center with its
   right edge clipped off on mobile. overflow-x is auto (not hidden) so that
   on the rare screen too narrow to fit the board even at ludo.js's MIN_SCALE
   floor, the board can be scrolled sideways (by touch/drag or the
   #ludoHScrollSlider slider next to it) instead of being clipped and
   unreachable. position:relative anchors #ludoBoard's absolute positioning
   below - fitLudoBoard() computes and sets its `left` itself (not CSS
   margin:auto - a scaled-down-but-still-wider-than-container box centers
   inconsistently via margin:auto across browsers, which is exactly what
   caused a second, subtler version of this same off-center bug). */
.ludo-board-outer {
  position: relative; overflow-x: auto; overflow-y: hidden; -webkit-overflow-scrolling: touch;
  border-radius: 16px; box-shadow: 0 10px 24px rgba(0,0,0,.35);
}
/* A thick colorful "frame" plus a soft inner vignette gives the board some
   depth instead of a flat white square - same 3D approach as the carrom
   board's wood frame, just in board-game-box colors instead of wood. */
.ludo-board {
  position: absolute; top: 0; left: 0; transform-origin: 0 0; box-sizing: border-box;
  background:
    radial-gradient(ellipse at 30% 20%, rgba(255,255,255,.5), transparent 60%),
    linear-gradient(135deg, #fdfdff 0%, #eef0f5 100%);
  border-radius: 10px;
  border: 7px solid #3a4a7a;
  border-image: linear-gradient(155deg, #e53935, #f2b705 33%, #43a047 66%, #1e88e5) 1;
  box-shadow:
    inset 0 0 0 2px rgba(255,255,255,.6),
    inset 0 2px 10px rgba(0,0,0,.12),
    0 6px 16px rgba(0,0,0,.35);
}
#ludoFullscreenBtn { display: inline-flex; margin-bottom: 8px; }
/* Left-right slider - shown only when the board can't fully fit even at
   MIN_SCALE (fitLudoBoard() in ludo.js toggles this). */
.ludo-hscroll-row { align-items: center; gap: 8px; margin: 2px 0 10px; }
.ludo-hscroll-row input[type="range"] { flex: 1; accent-color: var(--accent); }
.ludo-hscroll-arrow { font-size: 13px; color: var(--text-dim); flex-shrink: 0; }
/* Full-screen mode for the Ludo game itself - a CSS-only "cover the app"
   toggle (not the native Fullscreen API, which Capacitor's iOS/Android
   WebViews and some mobile browsers don't reliably support for a plain
   div) so it works the same everywhere the app runs. z-index 60 is
   deliberately BELOW the message-alert toast (80), incoming-call toast
   (90), call-waiting toast (110) and active call overlay (100) - a call
   or message must still interrupt a full-screen game, never get buried
   under it. See fitLudoBoard()/toggleLudoFullscreen() in ludo.js. */
.ludo-fullscreen-active {
  position: fixed; inset: 0; z-index: 60; background: var(--panel);
  padding: 14px; box-sizing: border-box; overflow-y: auto;
  display: flex; flex-direction: column;
}
.ludo-fullscreen-active #ludoFullscreenBtn { align-self: flex-end; position: sticky; top: 0; }
/* Each ring cell gets a slight raised-tile gradient + inset highlight
   instead of a flat white fill, so the track itself has some depth. Safe
   cells and the colored start/stretch/home cells (background/border set
   inline from ludo.js via color.hex) keep their own color but pick up the
   same inset lighting via box-shadow, which layers fine on top of any
   inline background color. */
.ludo-cell {
  position: absolute; box-sizing: border-box; border: 1px solid var(--border);
  background: linear-gradient(160deg, #ffffff 0%, #eef0f4 100%);
  box-shadow: inset 0 1px 0 rgba(255,255,255,.9), inset 0 -1px 2px rgba(0,0,0,.06);
  display: flex; align-items: center; justify-content: center;
  font-size: 12px; color: #cf9b00;
}
.ludo-safe {
  font-weight: 700; color: #b8860b;
  box-shadow: inset 0 1px 0 rgba(255,255,255,.9), inset 0 -1px 2px rgba(0,0,0,.08), inset 0 0 0 2px rgba(242,183,5,.5);
}
.ludo-stretch-cell, .ludo-home-cell {
  border-width: 1px;
  box-shadow: inset 0 2px 3px rgba(255,255,255,.5), inset 0 -3px 5px rgba(0,0,0,.25);
}
.ludo-home-cell { border-radius: 4px; }
.ludo-yard-box {
  position: absolute; box-sizing: border-box; border: 2px dashed; border-radius: 12px;
  box-shadow: inset 0 0 14px rgba(0,0,0,.08);
}
.ludo-token-layer { position: absolute; inset: 0; pointer-events: none; }
/* Glossy "playing piece" look: an inline background color from ludo.js
   (color.hex) still shows through, with a highlight/shadow overlay drawn
   via ::after on top so every token reads as a rounded 3D marble. */
.ludo-token {
  position: absolute; border-radius: 50%; border: 2px solid rgba(0,0,0,.3);
  box-shadow: 0 3px 5px rgba(0,0,0,.4), inset 0 -3px 4px rgba(0,0,0,.35);
  transition: left .25s ease, top .25s ease;
  pointer-events: none;
}
.ludo-token::after {
  content: ''; position: absolute; inset: 0; border-radius: 50%;
  background: radial-gradient(circle at 32% 26%, rgba(255,255,255,.85) 0%, rgba(255,255,255,.15) 40%, transparent 65%);
}
.ludo-token-movable {
  pointer-events: auto; cursor: pointer; animation: ludoPulse 1s infinite;
}
@keyframes ludoPulse {
  0%, 100% { box-shadow: 0 3px 5px rgba(0,0,0,.4), inset 0 -3px 4px rgba(0,0,0,.35), 0 0 0 0 rgba(255,255,255,.9); }
  50% { box-shadow: 0 3px 5px rgba(0,0,0,.4), inset 0 -3px 4px rgba(0,0,0,.35), 0 0 0 5px rgba(255,255,255,.55); }
}
.ludo-legend { display: flex; flex-wrap: wrap; gap: 8px 14px; margin-top: 14px; }
.ludo-legend-item {
  font-size: 12px; font-weight: 600; color: var(--text); border-left: 4px solid; padding-left: 6px;
}
.ludo-winner-banner {
  flex-basis: 100%; font-size: 13.5px; font-weight: 700; color: var(--text);
  background: linear-gradient(135deg, #fff7d6, #ffe9a3);
  border: 1.5px solid #f2b705; border-radius: 9px; padding: 10px 12px; margin-top: 8px;
  box-shadow: 0 3px 8px rgba(242,183,5,.3);
}
@media (max-width: 480px) {
  .ludo-dice-face { font-size: 22px; }
}

/* ---------- Carrom (ক্যারম) mini-game ---------- */
.carrom-status-bar { display: flex; align-items: center; flex-wrap: wrap; gap: 10px; margin-bottom: 12px; }
.carrom-turn-badge {
  font-weight: 700; font-size: 12px; padding: 6px 14px; border-radius: 999px;
  box-shadow: 0 2px 4px rgba(0,0,0,.25), inset 0 1px 0 rgba(255,255,255,.4);
}
.carrom-log { flex-basis: 100%; font-size: 12px; color: var(--text-dim); }
/* Same rationale as .ludo-board-outer/.ludo-board: plain block layout (not
   flex) so it doesn't fight the JS-computed transform:scale() in
   fitCarromBoard(), and position:relative anchors the absolutely
   positioned pockets/coins/striker inside #carromBoard. Styled after a
   real wooden carrom board: light honey-oak surface with visible grain,
   big rounded corners, a thin inset cushion-boundary line (not a thick
   physical frame), and decorative fan arcs radiating from each pocket. */
.carrom-board-outer {
  position: relative; overflow: hidden; touch-action: none;
  border-radius: 30px; box-shadow: 0 10px 24px rgba(0,0,0,.35);
}
.carrom-board {
  position: absolute; top: 0; left: 0; transform-origin: 0 0; box-sizing: border-box;
  background:
    repeating-linear-gradient(100deg, rgba(150,101,45,.07) 0 2px, transparent 2px 14px),
    radial-gradient(ellipse at 28% 18%, rgba(255,255,255,.35), transparent 55%),
    linear-gradient(135deg, #f3d9a4 0%, #e8c483 45%, #d9a95f 100%);
  border-radius: 30px;
  border: 3px solid #c8985a;
  box-shadow:
    inset 0 0 0 1px rgba(255,244,220,.6),
    inset 0 2px 10px rgba(0,0,0,.12),
    inset 0 -3px 14px rgba(0,0,0,.1),
    0 6px 16px rgba(0,0,0,.3);
}
/* Thin rounded-square boundary line marking the cushion, inset from the
   board edge so it curves neatly between the four pockets - drawn as its
   own element (see buildGameView) rather than a border on .carrom-board
   itself, since the board's own edge is rounded much more (matches the
   reference photo's light wood margin outside the play-line). */
.carrom-cushion-line {
  position: absolute; box-sizing: border-box; pointer-events: none;
  border: 2px solid rgba(122,58,22,.4); border-radius: 26px;
}
/* Small double-arc "fan" decoration curving out from each pocket, same
   spirit as the scalloped corner pattern on a real board. One element per
   corner; box-sizing + a large radius on just the corner facing the
   center turns two solid edges into a quarter-circle stroke. */
.carrom-corner-arc {
  position: absolute; box-sizing: border-box; pointer-events: none;
  border-style: solid; border-color: transparent;
}
#carromFullscreenBtn { display: inline-flex; margin-bottom: 8px; }
.carrom-fullscreen-active {
  position: fixed; inset: 0; z-index: 60; background: var(--panel);
  padding: 14px; box-sizing: border-box; overflow-y: auto;
  display: flex; flex-direction: column;
}
.carrom-fullscreen-active #carromFullscreenBtn { align-self: flex-end; position: sticky; top: 0; }
.carrom-pocket {
  position: absolute; border-radius: 50%;
  background: radial-gradient(circle at 40% 35%, #4a2f18 0%, #1c0f06 55%, #000 100%);
  box-shadow: inset 0 0 8px rgba(0,0,0,.9), inset 0 2px 3px rgba(255,255,255,.08), 0 0 0 3px #8a5a30;
}
.carrom-center-ring {
  position: absolute; border-radius: 50%;
  border: 2px solid rgba(122,58,22,.5);
  box-shadow: 0 0 0 6px rgba(122,58,22,.1), inset 0 0 10px rgba(122,58,22,.12);
  box-sizing: border-box;
}
.carrom-baseline { position: absolute; height: 0; border-top: 2px dashed rgba(90,52,24,.5); }
.carrom-coin-layer { position: absolute; inset: 0; pointer-events: none; }
/* Glossy "poker chip" look: a bright highlight top-left, darker rim
   shadow bottom-right, plus a thin inner ring so each coin reads as a
   rounded 3D disc rather than a flat circle. */
.carrom-coin {
  position: absolute; border-radius: 50%; box-sizing: border-box;
  box-shadow:
    0 3px 5px rgba(0,0,0,.5),
    inset 0 2px 3px rgba(255,255,255,.55),
    inset 0 -3px 4px rgba(0,0,0,.35);
}
.carrom-coin-white {
  background: radial-gradient(circle at 32% 28%, #ffffff 0%, #f1f1f1 45%, #d6d6d6 100%);
  border: 1px solid #b8b8b8;
}
.carrom-coin-black {
  background: radial-gradient(circle at 32% 28%, #555 0%, #262626 55%, #000 100%);
  border: 1px solid #000;
}
.carrom-coin-queen {
  background: radial-gradient(circle at 32% 28%, #ff7a6e 0%, #e0362a 50%, #941f16 100%);
  border: 1px solid #6e130c;
  box-shadow:
    0 3px 6px rgba(0,0,0,.5),
    inset 0 2px 3px rgba(255,255,255,.6),
    inset 0 -3px 4px rgba(0,0,0,.4),
    0 0 6px 1px rgba(255,60,40,.5);
}
/* Blue/white pinwheel striker, same spirit as a real carrom striker's
   painted rim pattern - a repeating conic gradient makes the alternating
   wedges, with a small white hub in the middle. */
.carrom-striker {
  position: absolute; border-radius: 50%; touch-action: none; cursor: grab; z-index: 3;
  background:
    radial-gradient(circle at center, #ffffff 0 22%, transparent 23%),
    repeating-conic-gradient(#2f7bc4 0deg 30deg, #ffffff 30deg 60deg);
  border: 2px solid #ffffff;
  box-shadow:
    0 4px 8px rgba(0,0,0,.5),
    inset 0 2px 4px rgba(255,255,255,.5),
    inset 0 -4px 6px rgba(0,0,0,.25);
}
.carrom-striker-ready { animation: carromPulse 1.1s infinite; }
@keyframes carromPulse {
  0%, 100% { box-shadow: 0 0 0 0 rgba(255,214,110,.9), 0 4px 8px rgba(0,0,0,.5), inset 0 2px 4px rgba(255,255,255,.5), inset 0 -4px 6px rgba(0,0,0,.25); }
  50% { box-shadow: 0 0 0 6px rgba(255,214,110,.35), 0 4px 8px rgba(0,0,0,.5), inset 0 2px 4px rgba(255,255,255,.5), inset 0 -4px 6px rgba(0,0,0,.25); }
}
.carrom-aim-line {
  position: absolute; height: 3px; border-radius: 2px;
  background: repeating-linear-gradient(90deg, rgba(255,214,110,.95) 0 6px, transparent 6px 10px);
  filter: drop-shadow(0 0 2px rgba(0,0,0,.6));
  transform-origin: 0 50%; pointer-events: none; z-index: 2;
}
.carrom-controls { display: flex; align-items: center; justify-content: center; gap: 10px; margin-top: 10px; flex-wrap: wrap; }
.carrom-controls-hint { font-size: 11.5px; color: var(--text-dim); text-align: center; }
.carrom-legend { display: flex; flex-wrap: wrap; gap: 8px 14px; margin-top: 14px; }
.carrom-legend-item { display: flex; align-items: center; gap: 6px; font-size: 12px; font-weight: 600; color: var(--text); }
.carrom-legend-swatch {
  display: inline-block; width: 13px; height: 13px; border-radius: 50%;
  box-shadow: inset 0 1px 2px rgba(255,255,255,.6), inset 0 -2px 3px rgba(0,0,0,.35), 0 1px 2px rgba(0,0,0,.3);
}
.carrom-winner-banner {
  flex-basis: 100%; font-size: 13.5px; font-weight: 700; color: var(--text);
  background: linear-gradient(135deg, #fff7d6, #ffe9a3);
  border: 1.5px solid #f2b705; border-radius: 9px; padding: 10px 12px; margin-top: 8px;
  box-shadow: 0 3px 8px rgba(242,183,5,.3);
}

/* ---------- DxBall (ডিএক্স বল) mini-game ---------- */
.dxball-status-bar { display: flex; align-items: center; flex-wrap: wrap; gap: 10px 16px; margin-bottom: 10px; }
.dxball-stat { font-size: 12.5px; font-weight: 600; color: var(--text); }
/* Canvas keeps its fixed internal resolution (380x480) and is scaled purely
   via CSS width/aspect-ratio - simpler than ludo/carrom's manual JS
   transform:scale() fit, since a <canvas> already redraws crisply at any
   CSS size. max-width caps it on wide desktop screens. */
.dxball-board-outer {
  position: relative; margin: 0 auto; max-width: 420px;
  border-radius: 14px; overflow: hidden; box-shadow: 0 10px 24px rgba(0,0,0,.35);
}
.dxball-canvas {
  display: block; width: 100%; height: auto; aspect-ratio: 380 / 480;
  touch-action: none; cursor: pointer; background: #0e1119;
}
#dxballFullscreenBtn { display: inline-flex; margin-bottom: 8px; }
.dxball-fullscreen-active {
  position: fixed; inset: 0; z-index: 60; background: var(--panel);
  padding: 14px; box-sizing: border-box; overflow-y: auto;
  display: flex; flex-direction: column; align-items: center;
}
.dxball-fullscreen-active #dxballFullscreenBtn { align-self: flex-end; position: sticky; top: 0; }
.dxball-fullscreen-active .dxball-board-outer { flex: 1; max-width: min(420px, 92vw); display: flex; align-items: center; }
.dxball-fullscreen-active .dxball-canvas { max-height: 68vh; width: auto; height: 100%; }
.dxball-controls { display: flex; align-items: center; justify-content: center; gap: 10px; margin-top: 10px; flex-wrap: wrap; }
.dxball-controls-hint { font-size: 11.5px; color: var(--text-dim); text-align: center; }
.dxball-winner-banner {
  flex-basis: 100%; font-size: 13.5px; font-weight: 700; color: var(--text);
  background: linear-gradient(135deg, #ffe3e3, #ffc9c9);
  border: 1.5px solid #ff5c5c; border-radius: 9px; padding: 10px 12px; margin-top: 4px;
  box-shadow: 0 3px 8px rgba(255,92,92,.3);
}

/* ---------- Chess (দাবা) mini-game ---------- */
.chess-status-bar { display: flex; align-items: center; flex-wrap: wrap; gap: 10px; margin-bottom: 12px; }
.chess-turn-badge { font-weight: 700; font-size: 13px; color: var(--text); }
/* Plain block layout + JS transform:scale, same rationale as
   .ludo-board-outer/.carrom-board-outer - avoids the flex/transform
   double-shrink bug documented there. */
.chess-board-outer {
  position: relative; overflow-x: auto; overflow-y: hidden; -webkit-overflow-scrolling: touch;
  border-radius: 10px; box-shadow: 0 10px 24px rgba(0,0,0,.35);
}
.chess-board {
  position: absolute; top: 0; left: 0; transform-origin: 0 0; box-sizing: border-box;
  border: 6px solid #5a3417; border-radius: 4px;
  box-shadow: inset 0 0 0 2px rgba(255,255,255,.15), 0 6px 16px rgba(0,0,0,.35);
}
.chess-cell { position: absolute; box-sizing: border-box; display: flex; align-items: center; justify-content: center; cursor: pointer; }
.chess-cell-light { background: #f0d9b5; }
.chess-cell-dark { background: #b58863; }
.chess-cell-selected { box-shadow: inset 0 0 0 3px #4d96ff; }
.chess-cell-target::after {
  content: ''; width: 28%; height: 28%; border-radius: 50%; background: rgba(30,30,30,.35);
}
.chess-cell-target-capture::after {
  content: ''; width: 90%; height: 90%; border-radius: 50%; background: transparent;
  box-shadow: inset 0 0 0 4px rgba(220,50,50,.65);
}
.chess-cell-check { box-shadow: inset 0 0 0 3px #ff5c5c, inset 0 0 16px rgba(255,92,92,.55); }
.chess-piece { font-size: 30px; line-height: 1; user-select: none; pointer-events: none; }
.chess-piece-w { color: #fbfbfb; text-shadow: 0 1px 2px rgba(0,0,0,.8), 0 0 1px #000; }
.chess-piece-b { color: #1a1a1a; text-shadow: 0 1px 1px rgba(255,255,255,.3); }
#chessFullscreenBtn { display: inline-flex; margin-bottom: 8px; }
.chess-fullscreen-active {
  position: fixed; inset: 0; z-index: 60; background: var(--panel);
  padding: 14px; box-sizing: border-box; overflow-y: auto;
  display: flex; flex-direction: column;
}
.chess-fullscreen-active #chessFullscreenBtn { align-self: flex-end; position: sticky; top: 0; }
.chess-promo-picker {
  display: flex; flex-direction: column; align-items: center; gap: 8px; margin-top: 12px;
  background: var(--panel-2, rgba(0,0,0,.03)); border: 1.5px solid var(--border); border-radius: 10px; padding: 10px;
}
.chess-promo-label { font-size: 12px; font-weight: 700; color: var(--text-dim); }
.chess-promo-options { display: flex; gap: 8px; }
.chess-promo-btn {
  font-size: 26px; width: 46px; height: 46px; border-radius: 8px; border: 1.5px solid var(--border);
  background: var(--panel); cursor: pointer; display: flex; align-items: center; justify-content: center;
}
.chess-captured-row { display: flex; flex-direction: column; gap: 4px; margin-top: 12px; }
.chess-captured-line { font-size: 12px; color: var(--text-dim); display: flex; align-items: center; flex-wrap: wrap; gap: 2px; }
.chess-captured-label { font-weight: 600; margin-right: 4px; }
.chess-captured-line .chess-piece { font-size: 16px; }
.chess-log {
  margin-top: 10px; font-size: 11.5px; color: var(--text-dim); line-height: 1.6;
  max-height: 90px; overflow-y: auto; font-family: monospace;
}
.chess-winner-banner {
  flex-basis: 100%; font-size: 13.5px; font-weight: 700; color: var(--text);
  background: linear-gradient(135deg, #fff7d6, #ffe9a3);
  border: 1.5px solid #f2b705; border-radius: 9px; padding: 10px 12px; margin-top: 8px;
  box-shadow: 0 3px 8px rgba(242,183,5,.3);
}

/* ---- Desktop sidebar: wider, auto-scaling column with proportionally
   larger type/icons ------------------------------------------------------
   The sidebar was a flat 280px on every screen, phone or 27" monitor alike.
   That's a sensible *minimum* for a phone, but on a real desktop window it
   left the tab bar, colleague list, names and search box all sized for a
   much smaller screen - tiny 9.5px tab labels, names clipped to "Md. S...",
   a scrollbar just to see the rest of the tab row. `clamp()` lets the
   column genuinely respond to the window instead of a single fixed number:
   it never drops below 300px (still comfortable), grows with the viewport
   via `22vw`, and stops widening past 380px so it can't crowd out the chat
   panel on ultrawide displays. Scoped to min-width:821px so it never touches
   the existing mobile layout (which uses the opposite max-width:820px
   breakpoint elsewhere in this file). */
@media (min-width: 821px) {
  .app { grid-template-columns: clamp(300px, 22vw, 380px) 1fr; }

  .sidebar-header { padding: 22px 20px 16px; gap: 12px; }
  .sidebar-header .mark { width: 38px; height: 38px; border-radius: 10px; }
  .sidebar-header .title { font-size: 17px; }
  .sidebar-header .subtitle { font-size: 12.5px; }

  .me-bar { padding: 14px 20px; gap: 12px; }
  .me-bar .avatar { width: 40px; height: 40px; font-size: 15px; }
  .me-bar .me-name { font-size: 14.5px; }
  .me-bar .me-role { font-size: 12px; }

  /* Tabs keep single-row + horizontal scroll by design (there can be 10+
     of them, see the .tabs comment above) - only their own size grows, so
     more of the row is legible before anyone needs to scroll it at all. */
  .tabs { padding: 9px 12px 8px; gap: 5px; }
  .tab-btn { min-width: 62px; padding: 7px 5px 8px; font-size: 11px; gap: 3px; border-radius: 9px; }
  .tab-btn svg { width: 18px; height: 18px; }

  .conv-search-wrap { margin: 12px 16px 6px; padding: 10px 14px; }
  .conv-search-wrap input { font-size: 13.5px; }
  .conv-filter-chips { padding: 6px 14px 4px; gap: 6px; }
  .conv-filter-chips .chip { font-size: 11px; padding: 3px 10px; }

  .conv-list { padding: 10px 12px; }
  .conv-item { padding: 11px 12px; gap: 12px; }
  .conv-item .avatar { width: 42px; height: 42px; font-size: 15px; }
  .conv-item .conv-name { font-size: 14.5px; }
  .conv-item .conv-preview { font-size: 12.5px; max-width: none; }
  .conv-time { font-size: 11px; }
  .unread-badge { font-size: 11px; min-width: 19px; height: 19px; }

  .side-icon-toolbar { padding: 10px 14px; }
  .side-icon-btn { width: 36px; height: 36px; }
  .side-icon-btn svg { width: 20px; height: 20px; }
}

/* ---------- Jobs (চাকরি) tool ---------- */
.jobs-sub-panel { max-width: 100%; }
.jobs-card {
  border: 1.5px solid var(--border); border-radius: 12px; padding: 14px 16px; margin-bottom: 10px; background: white;
}
.jobs-card-top { display: flex; justify-content: space-between; align-items: flex-start; gap: 10px; }
.jobs-card-title { font-size: 14.5px; font-weight: 700; color: var(--text); margin-bottom: 2px; }
.jobs-card-sub { font-size: 12px; color: var(--text-dim); margin-bottom: 6px; }
.jobs-card-meta { display: flex; flex-wrap: wrap; gap: 6px; font-size: 11px; color: var(--text-dim); margin: 6px 0; }
.jobs-card-meta span { background: var(--bg); border-radius: 6px; padding: 3px 8px; }
.jobs-card-actions { display: flex; flex-wrap: wrap; gap: 8px; margin-top: 10px; }
.jobs-status-pill { padding: 3px 10px; border-radius: 20px; font-size: 11px; font-weight: 700; display: inline-block; }
.jobs-status-applied, .jobs-status-draft { background: #F1F2F4; color: var(--text-dim); }
.jobs-status-shortlisted, .jobs-status-published { background: #E6F7F1; color: var(--accent-dark); }
.jobs-status-interview_scheduled { background: #FFF4E0; color: #A9720D; }
.jobs-status-hired { background: #E6F7F1; color: var(--accent-dark); }
.jobs-status-rejected, .jobs-status-closed { background: #FDECEC; color: var(--danger); }
.jobs-notif-item { border-bottom: 1px solid var(--border); padding: 10px 4px; font-size: 12.5px; }
.jobs-notif-item.unread { background: rgba(31,174,142,0.05); }
.jobs-notif-title { font-weight: 700; margin-bottom: 2px; }
.jobs-notif-time { font-size: 10.5px; color: var(--text-dim); margin-top: 3px; }
.jobs-cv-row { border: 1.5px solid var(--border); border-radius: 10px; padding: 10px 12px; margin-bottom: 8px; position: relative; }
.jobs-cv-row-remove { position: absolute; top: 8px; right: 8px; background: none; border: none; color: var(--danger); font-size: 13px; cursor: pointer; }
.jobs-cv-row .field { margin-bottom: 8px; }
.jobs-timeline { border-left: 2px solid var(--border); padding-left: 14px; margin: 10px 0; }
.jobs-timeline-item { margin-bottom: 12px; font-size: 12.5px; position: relative; }
.jobs-timeline-item::before { content: ''; position: absolute; left: -18px; top: 4px; width: 8px; height: 8px; border-radius: 50%; background: var(--accent); }

/* প্রয়োজন (Proyojon marketplace) - reuses .jobs-card/.jobs-status-pill/
   .jobs-notif-item/.jobs-timeline for order cards, status badges,
   notifications and order timelines (same visual language as চাকরি/Jobs),
   and only adds the bits Jobs never needed: a responsive product photo
   grid and a couple of ecommerce-specific status colors. */
.proyojon-product-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(140px, 1fr)); gap: 12px; }
.proyojon-product-card { border: 1.5px solid var(--border); border-radius: 12px; overflow: hidden; background: white; cursor: pointer; transition: box-shadow .15s; }
.proyojon-product-card:hover { box-shadow: 0 4px 14px rgba(0,0,0,0.08); }
.proyojon-product-thumb { width: 100%; aspect-ratio: 1/1; object-fit: cover; background: var(--bg); display: block; }
.proyojon-product-info { padding: 8px 10px 10px; }
.proyojon-product-title { font-size: 12.5px; font-weight: 700; color: var(--text); line-height: 1.3; margin-bottom: 4px; display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical; overflow: hidden; }
.proyojon-product-price { font-size: 13.5px; font-weight: 800; color: var(--accent-dark); }
.proyojon-product-price-old { font-size: 11px; color: var(--text-dim); text-decoration: line-through; margin-left: 5px; }
.proyojon-product-meta { font-size: 10.5px; color: var(--text-dim); margin-top: 3px; }
.proyojon-thumb-strip { display: flex; gap: 6px; flex-wrap: wrap; margin: 8px 0; }
.proyojon-thumb-strip img { width: 56px; height: 56px; object-fit: cover; border-radius: 8px; border: 1.5px solid var(--border); }
.jobs-status-active, .jobs-status-confirmed, .jobs-status-delivered { background: #E6F7F1; color: var(--accent-dark); }
.jobs-status-pending { background: #FFF4E0; color: #A9720D; }
.jobs-status-packed, .jobs-status-shipped { background: #E6EEFB; color: #2A5FBD; }
.jobs-status-paused, .jobs-status-out_of_stock { background: #F1F2F4; color: var(--text-dim); }
.jobs-status-cancelled { background: #FDECEC; color: var(--danger); }
.proyojon-stat-chip { background: var(--bg); border-radius: 10px; padding: 8px 14px; font-size: 11.5px; color: var(--text-dim); }
.proyojon-stat-chip b { display: block; font-size: 16px; color: var(--text); font-weight: 800; }
.proyojon-star { color: #E8A200; }
