/* ============================================================================
   MemeHouse OS — mobile / app layer
   Added 2026-08-17.

   Loaded after style.css. Everything here is inside a media query, so desktop
   is untouched.

   The layout was built desktop-first with inline-styled grids inside app.js
   template strings, so there are no class hooks to target. That shapes the
   approach: fix the structural defaults that cause the breakage rather than
   chase individual elements, and use attribute selectors for the inline grids.
   ========================================================================== */

/* ── iOS chrome: safe areas, scroll behaviour, tap feel ──────────────────── */
:root {
  --safe-top:    env(safe-area-inset-top, 0px);
  --safe-bottom: env(safe-area-inset-bottom, 0px);
  --safe-left:   env(safe-area-inset-left, 0px);
  --safe-right:  env(safe-area-inset-right, 0px);
  /* Tab bar height plus the home indicator. */
  --dock-h: calc(64px + var(--safe-bottom));
}

html {
  -webkit-text-size-adjust: 100%;   /* stop iOS inflating text in landscape */
}

body {
  /* Rubber-banding the whole page reveals the white void behind a dark app and
     reads as broken rather than bouncy. */
  overscroll-behavior-y: none;
  -webkit-tap-highlight-color: transparent;
}

@media (max-width: 820px) {

  /* ── the actual bug ────────────────────────────────────────────────────────
     Grid and flex children default to min-width:auto, so they refuse to shrink
     below their intrinsic content width and burst out of their cell. This is
     why 167 elements were rendering outside a 375px viewport while the grids
     themselves measured correctly. */
  .content [style*="grid-template-columns"] > *,
  .content [style*="display:flex"] > *,
  .content [style*="display: flex"] > * {
    min-width: 0;
  }

  /* Multi-column grids become one column. Two 178px columns cannot hold a card
     that was designed for a desktop half-width. */
  .content [style*="grid-template-columns"] {
    grid-template-columns: 1fr !important;
  }

  /* Except deliberately compact stat rows, which read better kept side by side.
     Marked with data-compact so this stays opt-in rather than guessed. */
  .content [data-compact][style*="grid-template-columns"] {
    grid-template-columns: repeat(auto-fit, minmax(96px, 1fr)) !important;
  }

  /* Nothing may exceed the viewport, whatever it thinks its width is. */
  .content img,
  .content video,
  .content canvas,
  .content table,
  .content pre { max-width: 100%; height: auto; }

  .content pre,
  .content code { overflow-x: auto; white-space: pre-wrap; word-break: break-word; }

  /* Long unbroken strings (URLs, ids, emails) are a common overflow source. */
  .content, .card { overflow-wrap: anywhere; }

  /* Wide tables scroll inside themselves instead of pushing the page. */
  .content table { display: block; overflow-x: auto; -webkit-overflow-scrolling: touch; }

  /* ── layout ─────────────────────────────────────────────────────────────── */
  .app { flex-direction: column; }

  /* Top padding must clear #user-pill, which is fixed at top:10 and 36px tall.
     Dropping this to 12px is what made the greeting render under the avatar. */
  .content {
    padding: calc(56px + var(--safe-top)) 14px calc(var(--dock-h) + 20px) !important;
  }

  /* The pill itself sits below the notch rather than in it. */
  .user-pill, #user-pill {
    top: calc(10px + var(--safe-top)) !important;
    right: calc(10px + var(--safe-right)) !important;
  }

  /* Hero headings are inline-styled in app.js template strings, so there is no
     class to hook. Cap the sizes that actually appear. */
  .content [style*="font-size:32px"] { font-size: 24px !important; }
  .content [style*="font-size:34px"],
  .content [style*="font-size:36px"] { font-size: 25px !important; }
  .content [style*="font-size:40px"],
  .content [style*="font-size:42px"],
  .content [style*="font-size:48px"] { font-size: 27px !important; }
  .content [style*="font-size:28px"] { font-size: 22px !important; }

  /* Floating UI was positioned against a centred pill dock. The dock is now a
     full-width bar, so anything anchored to the bottom has to clear it. */
  #chat-bubble-container {
    bottom: calc(var(--dock-h) + 14px) !important;
    right: calc(16px + var(--safe-right)) !important;
  }
  #brief-reminder-toast,
  .toast, .snackbar {
    bottom: calc(var(--dock-h) + 76px) !important;
    right: calc(12px + var(--safe-right)) !important;
    left: calc(12px + var(--safe-left)) !important;
    width: auto !important;
    max-width: none !important;
  }

  .main { padding-bottom: 0 !important; }

  .card { padding: 16px !important; border-radius: 14px; }

  /* ── typography: desktop hero type eats a phone screen ──────────────────── */
  h1, .h1 { font-size: 26px !important; line-height: 1.15 !important; letter-spacing: -.02em; }
  h2       { font-size: 19px !important; line-height: 1.2 !important; }
  h3       { font-size: 16px !important; }
  .label   { font-size: 10px !important; }

  /* ── tap targets: Apple's HIG floor is 44pt ─────────────────────────────── */
  button, .btn, a.btn, [role="button"], select, .dock-item {
    min-height: 44px;
  }
  input, textarea, select {
    /* Anything under 16px makes iOS zoom the whole page on focus. */
    font-size: 16px !important;
  }

  /* ── the dock ───────────────────────────────────────────────────────────────
     16 items needing 753px inside a 351px pill, so over half the app was
     unreachable. Until this becomes a proper 5-tab bar it at least scrolls,
     with snap points so it lands on whole icons. */
  .dock {
    left: 0 !important;
    right: 0 !important;
    bottom: 0 !important;
    transform: none !important;
    width: 100% !important;
    max-width: 100% !important;
    border-radius: 0 !important;
    border-left: none !important;
    border-right: none !important;
    border-bottom: none !important;
    padding: 8px calc(10px + var(--safe-left)) calc(8px + var(--safe-bottom)) calc(10px + var(--safe-right)) !important;
    gap: 2px !important;
    justify-content: flex-start;
    overflow-x: auto;
    overflow-y: hidden;
    scroll-snap-type: x proximity;
    -webkit-overflow-scrolling: touch;
    scrollbar-width: none;
    animation: none !important;   /* the rise-in animation fights a fixed bar */
  }
  .dock::-webkit-scrollbar { display: none; }

  .dock-item {
    scroll-snap-align: center;
    flex: 0 0 auto;
    min-width: 60px;
    padding: 4px 6px !important;
  }
  .dock-label { font-size: 9px !important; }

  /* ── calendar (Events) ──────────────────────────────────────────────────────
     Seven columns cannot be squeezed into 375px and stay legible, so the month
     grid scrolls sideways as one unit rather than each cell bursting its
     column. This was 67 of the remaining overflows on its own. */
  .cal-grid, .calendar-grid, [class*="cal-month"] {
    overflow-x: auto;
    -webkit-overflow-scrolling: touch;
  }
  .cal-cell, .cal-weekday {
    min-width: 0;
    overflow: hidden;
  }
  .cal-cell-num {
    font-size: 11px !important;
    line-height: 1.1;
  }
  .cal-event-chip {
    font-size: 9px !important;
    padding: 1px 3px !important;
    max-width: 100%;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
  }

  /* ── agent task rows ────────────────────────────────────────────────────── */
  .agent-task-row, .agent-task-prompt, .agent-task-meta,
  [class*="agent-task-status"] {
    min-width: 0;
    max-width: 100%;
    overflow-wrap: anywhere;
    white-space: normal !important;
  }
  .agent-task-row { flex-wrap: wrap; }

  /* ── fixed-width cards in inline styles ─────────────────────────────────────
     Departments lays out cards at a hardcoded width:140px, which walks straight
     off a phone once there are seven of them. */
  .content [style*="width:140px"],
  .content [style*="width: 140px"],
  .content [style*="width:160px"],
  .content [style*="width: 160px"],
  .content [style*="width:180px"],
  .content [style*="width: 180px"],
  .content [style*="width:200px"],
  .content [style*="width: 200px"] {
    width: auto !important;
    min-width: 0 !important;
    max-width: 100% !important;
  }

  /* Any horizontal strip of cards wraps instead of running off the edge. */
  .content [style*="display:flex"]:not([style*="column"]),
  .content [style*="display: flex"]:not([style*="column"]) {
    flex-wrap: wrap;
  }

  /* ── class-based layout grids ──────────────────────────────────────────────
     These are defined in style.css so the inline-style selectors above never
     reached them. Enumerated deliberately rather than collapsing every grid,
     because the calendar day grids below must stay at seven columns.

     .cal-wrap was the Events bug: a 260px sidebar plus the calendar left the
     month grid 76px wide, so its seven day columns were 21px each and every
     weekday label burst out. The calendar was never too wide, it was crushed. */
  .cal-wrap,
  .dept-layout,
  .dept-layout.has-artifact,
  .agents-layout,
  .agents-grid,
  .grid-2,
  .grid-3,
  .bento {
    grid-template-columns: 1fr !important;
  }
  .cal-main { min-width: 0; }

  /* A week has seven days on a phone too. These keep their columns and simply
     get smaller, rather than collapsing into a 42-row list. */
  .cal-grid, .cal-mini-grid {
    grid-template-columns: repeat(7, minmax(0, 1fr)) !important;
    overflow-x: visible;
  }
  .cal-weekday { font-size: 9px !important; text-overflow: ellipsis; overflow: hidden; }

  /* ── controls that refuse to shrink ─────────────────────────────────────── */
  .agent-dispatch-bar { flex-wrap: wrap; gap: 8px; }
  .agent-dispatch-bar > * { flex-shrink: 1 !important; min-width: 0; max-width: 100%; }
  select, .form-select, .form-input, input[type="text"], input[type="search"] {
    max-width: 100% !important;
  }

  /* ── chat: dept command centre and DMs ─────────────────────────────────────
     Message rows were rendering at 531px inside a 351px column. Bubbles are
     sized for a desktop reading width and long tokens (urls, ids) never wrap. */
  .msg-row, .dm-row, [class*="msg-bubble"], [class*="msg-content"],
  .dept-messages > *, .chat-message {
    max-width: 100% !important;
    min-width: 0;
  }
  .msg-row, .dm-row { flex-wrap: wrap; }
  [class*="msg-bubble"], [class*="msg-content"], .chat-message, .msg-text {
    overflow-wrap: anywhere;
    word-break: break-word;
  }
  .dept-messages, .dept-main, [id^="dept-chat-row-"], [id^="dept-msgs-"] {
    min-width: 0 !important;
    max-width: 100%;
  }
  /* Composer and its buttons stack rather than pushing the thread sideways. */
  .dept-composer, .chat-composer, .msg-composer { flex-wrap: wrap; min-width: 0; }

  /* Full-bleed pages still need to clear the tab bar. */
  .content--full-bleed { padding-bottom: calc(var(--dock-h) + 12px) !important; }

  /* ══════════════════════════════════════════════════════════════════════════
     TOUCH PASS
     Beyond making things fit, these are the behaviours that separate "a website
     on a phone" from "an app". Applied by pattern rather than per page, so they
     cover screens built later too.
     ══════════════════════════════════════════════════════════════════════════ */

  /* ── modals become bottom sheets ────────────────────────────────────────────
     A centred desktop dialog on a phone lands under the thumb's reach and
     leaves dead space above and below. Sheets rise from the bottom, which is
     both the native idiom and the reachable half of the screen. */
  .modal,
  .dispatch-modal,
  .cal-event-modal,
  .agent-live-modal {
    position: fixed !important;
    left: 0 !important;
    right: 0 !important;
    bottom: 0 !important;
    top: auto !important;
    transform: none !important;
    width: 100% !important;
    max-width: 100% !important;
    max-height: 88vh !important;
    max-height: 88dvh !important;
    margin: 0 !important;
    border-radius: 18px 18px 0 0 !important;
    padding-bottom: calc(18px + var(--safe-bottom)) !important;
    overflow-y: auto;
    -webkit-overflow-scrolling: touch;
    overscroll-behavior: contain;
    animation: mh-sheet-up .22s cubic-bezier(.22,.9,.34,1) both;
  }

  /* The grab handle is what tells someone this is draggable-feeling content
     rather than a page that failed to load properly. */
  .modal::before,
  .dispatch-modal::before,
  .cal-event-modal::before,
  .agent-live-modal::before {
    content: '';
    display: block;
    width: 36px;
    height: 4px;
    border-radius: 999px;
    background: var(--border-md);
    margin: 0 auto 14px;
  }

  @keyframes mh-sheet-up {
    from { transform: translateY(14px); opacity: 0; }
    to   { transform: translateY(0);    opacity: 1; }
  }

  .modal-overlay,
  .wf-panel-overlay,
  .wfp-overlay,
  .search-overlay {
    padding: 0 !important;
    align-items: flex-end !important;
  }

  .modal-title { font-size: 17px !important; }

  /* ── list rows: thumbs, not cursors ─────────────────────────────────────── */
  .task-item,
  .agent-task-item,
  .search-result-item,
  .cal-upcoming-item,
  .agent-card,
  .artifact-card {
    min-height: 48px;
    padding: 12px 14px !important;
  }

  /* A row that does something should look like it does something. */
  .task-item:active,
  .agent-task-item:active,
  .search-result-item:active,
  .cal-upcoming-item:active,
  .agent-card:active,
  .card[onclick]:active,
  [role="button"]:active,
  button:active {
    opacity: .68;
    transition: opacity .04s;
  }

  /* ── scrolling feel ─────────────────────────────────────────────────────── */
  [style*="overflow-y"], [style*="overflow:auto"], [style*="overflow: auto"],
  .task-list, .dept-messages, .modal, .content {
    -webkit-overflow-scrolling: touch;
  }
  /* Scrolling a thread should not drag the page behind it. */
  .dept-messages, .task-list, .modal { overscroll-behavior: contain; }

  /* ── search overlay is full screen on a phone ───────────────────────────── */
  .search-overlay input, .search-overlay .form-input {
    font-size: 16px !important;
    padding: 13px 14px !important;
  }

  /* ── keyboard safety ────────────────────────────────────────────────────────
     When the iOS keyboard opens it does not resize the viewport, so a composer
     pinned to the bottom ends up underneath it. dvh tracks the visible area. */
  .modal, .dispatch-modal { max-height: 88dvh !important; }

  /* ── things that assume a mouse ─────────────────────────────────────────── */
  *:hover { transform: none !important; }   /* sticky hover states on touch */
}

/* ── very small phones ───────────────────────────────────────────────────── */
@media (max-width: 380px) {
  .content { padding-left: 11px !important; padding-right: 11px !important; }
  h1, .h1  { font-size: 23px !important; }
  .card    { padding: 14px !important; }
}

/* ── installed as an app: no browser chrome to fall back on ─────────────── */
@media (display-mode: standalone) {
  body { user-select: none; -webkit-user-select: none; }
  /* Text the user may genuinely need to copy stays selectable. */
  input, textarea, [contenteditable], .selectable, .recnote, .hbody, p, td {
    user-select: text; -webkit-user-select: text;
  }
}

/* ── respect reduced motion ─────────────────────────────────────────────── */
@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after {
    animation-duration: .01ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: .01ms !important;
  }
}


/* Drawer controls are markup at every width, so hide them where the sidebar
   is permanently visible. Only the <=860px block below turns them on. */
.dept-sidebar-toggle, .dept-scrim { display: none; }

/* ══════════════════════════════════════════════════════════════════════════
   DEPARTMENT AGENT PAGE
   Below 860px style.css collapses the sidebar to 0px with no way to reopen it,
   so the connected tools and the conversation history became unreachable on
   every tablet and phone. It becomes a drawer instead of disappearing.
   ══════════════════════════════════════════════════════════════════════════ */
@media (max-width: 860px){
  /* With the sidebar lifted out of flow as a drawer, a three column grid left
     .dept-main auto-placed into the 0px first column, collapsing the chat to
     nothing. Below 860px there is exactly one in-flow column. */
  .dept-layout,
  .dept-layout.has-artifact{
    grid-template-columns: 1fr !important;
    grid-template-rows: 1fr !important;
  }
  .dept-main{ grid-area: 1 / 1 !important; min-width: 0 !important; }

  /* The artifact used to be pinned to 0px wide here, so generated documents
     were unreachable on a phone. It takes the full screen instead, closed with
     the existing close button in its header. */
  .dept-artifact-panel{ grid-area: 1 / 1 !important; }
  .dept-layout:not(.has-artifact) .dept-artifact-panel{ display:none !important; }
  .dept-layout.has-artifact .dept-artifact-panel{
    display:flex !important; width:auto !important; min-width:0 !important;
    opacity:1 !important; z-index:40; background:var(--bg-1);
    border-left:none !important;
  }

  .dept-layout{ position:relative; }

  /* Off-canvas rather than zero-width, so its contents keep their real size. */
  .dept-layout .dept-sidebar{
    position:absolute; top:0; bottom:0; left:0; z-index:60;
    width:min(84vw, 280px) !important;
    min-width:min(84vw, 280px) !important;
    padding:12px !important;
    background:var(--bg-2);
    border-right:1px solid var(--border-md) !important;
    box-shadow:14px 0 40px rgba(0,0,0,.5);
    transform:translateX(-102%);
    transition:transform .22s cubic-bezier(.22,.9,.34,1);
    overflow-y:auto !important;
    -webkit-overflow-scrolling:touch;
    overscroll-behavior:contain;
  }
  .dept-layout.sidebar-open .dept-sidebar{ transform:translateX(0); }

  /* Contents must not inherit the crushed widths any more. */
  .dept-sidebar .dept-hist-list,
  .dept-sidebar .dept-sidebar-tools,
  .dept-sidebar .dept-hist-item,
  .dept-sidebar .dept-hist-item-title,
  .dept-sidebar .dept-tool-row,
  .dept-sidebar .dept-tool-info,
  .dept-sidebar .dept-tool-name{
    width:auto !important; min-width:0 !important; max-width:100%;
  }
  .dept-sidebar .dept-hist-item-title{
    white-space:nowrap; overflow:hidden; text-overflow:ellipsis;
  }
  .dept-sidebar .dept-tool-row{ display:flex; align-items:center; gap:9px; }
  .dept-sidebar .dept-tool-info{ flex:1; min-width:0; }
  .dept-sidebar .dept-tool-name{ white-space:nowrap; overflow:hidden; text-overflow:ellipsis; }

  .dept-scrim{
    display:block;
    position:absolute; inset:0; z-index:55; background:rgba(0,0,0,.5);
    opacity:0; pointer-events:none; transition:opacity .22s;
  }
  .dept-layout.sidebar-open .dept-scrim{ opacity:1; pointer-events:auto; }

  .dept-sidebar-toggle{
    display:flex;
    position:absolute; top:10px; left:10px; z-index:50;
    width:38px; height:38px; border-radius:10px;
    background:var(--bg-3); border:1px solid var(--border-md); color:var(--text-1);
    display:flex; align-items:center; justify-content:center; cursor:pointer; padding:0;
  }
  .dept-layout.sidebar-open .dept-sidebar-toggle{ opacity:0; pointer-events:none; }
  /* The header carries an inline padding attribute, so this needs !important
     to stop the toggle button sitting on top of the agent name. */
  .dept-main .dept-chat-header{ padding-left:56px !important; }
}

/* An artifact panel collapsed to zero width still laid its header, tabs and
   buttons out at their natural size, which is what was rendering hundreds of
   pixels outside the viewport. */
.dept-artifact-panel{ overflow:hidden; }
.dept-artifact-panel:not(.open){ }
.dept-layout:not(.has-artifact) .dept-artifact-panel{
  overflow:hidden !important; width:0 !important; min-width:0 !important; border-left:none !important;
}
.dept-layout:not(.has-artifact) .dept-artifact-panel > *{ display:none !important; }

/* The action bar labels and the cook tooltip are revealed on hover, which does
   not exist on a touch screen: those buttons were unlabelled icons on every
   phone and tablet. The labels are always shown where there is no hover. */
@media (hover: none), (max-width: 860px){
  .ab-lbl{ max-width:none !important; opacity:1 !important; }
  .dept-cook-tip{ display:none; }
}

/* The connected tools sit at the foot of the sidebar. If the list ever grows
   past the space available it scrolls rather than disappearing off the end. */
/* The tools block was flex-shrink:0, so on a short screen it overflowed the
   sidebar and the last tool was clipped with no way to reach it. It shrinks
   and scrolls instead, so every tool is reachable at any height. */
.dept-sidebar-tools{ flex-shrink: 1 !important; min-height: 0 !important; overflow-y: auto !important; }
.dept-hist-list{ min-height: 70px; }

/* 1fr is minmax(auto,1fr), so a long unbreakable task title pushed one column
   to 1344px and squashed the other to 184px. The columns are pinned equal at
   the grid, and long titles wrap here rather than setting the column width. */
#home-missions-widget, #home-actions-widget, #home-pulse-widget, #home-done-widget { min-width: 0; }
#home-missions-body, #home-actions-widget, #home-missions-widget {
  overflow-wrap: anywhere; word-break: break-word;
}

/* Home widget rows: every card in a row is the same height and its content
   scrolls, so the row is a clean band rather than one tall card beside a short
   one with dead space under it. */
#home-pulse-widget, #home-missions-widget, #home-done-widget, #home-actions-widget {
  height: 300px; display: flex; flex-direction: column;
}
#home-missions-body, #home-pulse-row, #home-done-row, #home-actions-body, #home-actions-list {
  flex: 1; min-height: 0; overflow-y: auto; max-height: none !important;
  /* Content sits at the top of its card. Centred, a card holding two avatars
     floated them in the middle of the box and read as a layout fault. */
  align-items: flex-start !important;
  align-content: flex-start !important;
}
/* Rows are as tall as they need to be, to a limit, rather than always 300px.
   A row of short cards should be a short band. */
#home-pulse-widget, #home-missions-widget, #home-actions-widget {
  height: auto; max-height: 264px;
}
/* Completed lists one tile per person, so 264px cut the last row off once the
   team grew past nine. It still has a ceiling, just one that fits four rows,
   and anything past that scrolls inside the card rather than stretching it. */
#home-done-widget { height: auto; max-height: 340px; }

/* Pending action rows were sized to their own text, so a row of short titles
   and a row of long ones ended at different widths and the column looked
   ragged. Every row is the full width of the card and long titles truncate. */
#home-actions-widget > div:not(:first-child) > *,
#home-actions-body > *, #home-actions-list > * {
  width: 100% !important; box-sizing: border-box;
}
#home-actions-widget [class*="task"], #home-actions-body > div, #home-actions-list > div {
  min-width: 0;
}
#home-actions-widget > div:not(:first-child) > * > span:not([class]) { min-width: 0; }

/* The ten missions, as compact rows. */
.hm-row{ display:flex; align-items:baseline; gap:8px; padding:6px 0;
         border-top:1px solid var(--border); font-size:12.5px; line-height:1.45; }
.hm-row:first-child{ border-top:none; }
.hm-t{ color:var(--text-1); flex:1; min-width:0; }
.hm-cat{ font-size:8.5px; font-weight:800; letter-spacing:.07em; text-transform:uppercase;
         border-radius:4px; padding:2px 6px; flex:none; background:var(--bg-4); color:var(--text-3); }
.hm-cat.recover{ background:rgba(251,191,36,.15); color:#fbbf24; }
.hm-cat.save{ background:rgba(96,165,250,.15); color:#60a5fa; }
.hm-cat.make{ background:rgba(46,232,166,.14); color:#2EE8A6; }
.hm-cat.build{ background:rgba(167,139,250,.15); color:#a78bfa; }
.hm-cat.creative{ background:rgba(244,114,182,.15); color:#f472b6; }

/* ── Voice rooms ─────────────────────────────────────────────────────────── */
.voice-panel{ border-top:1px solid var(--border); padding:12px 14px; }
.voice-panel .vlabel{ font-size:10px; font-weight:800; letter-spacing:.09em; text-transform:uppercase;
  color:var(--text-3); margin-bottom:9px; display:flex; align-items:center; gap:7px; }
.vroom{ display:flex; align-items:center; justify-content:space-between; gap:10px;
  padding:8px 10px; border-radius:9px; cursor:pointer; margin-bottom:4px;
  border:1px solid transparent; transition:background .15s, border-color .15s; }
.vroom:hover{ background:var(--bg-3); }
.vroom.on{ background:rgba(46,232,166,.09); border-color:rgba(46,232,166,.35); }
.vr-l{ display:flex; align-items:center; gap:8px; min-width:0; }
.vr-l b{ font-size:12.5px; font-weight:600; color:var(--text-1); white-space:nowrap;
  overflow:hidden; text-overflow:ellipsis; }
.vr-dot{ width:7px; height:7px; border-radius:50%; background:var(--border-md); flex:none; }
.vr-dot.live{ background:#2EE8A6; box-shadow:0 0 6px #2EE8A6aa; }
.vr-r{ display:flex; align-items:center; gap:4px; flex:none; }
.vr-empty{ font-size:11px; color:var(--text-3); }
.vpill{ position:relative; width:22px; height:22px; border-radius:50%; flex:none;
  background:var(--bg-4); border:1px solid var(--border-md); color:var(--text-2);
  display:inline-flex; align-items:center; justify-content:center;
  font-size:8.5px; font-weight:800; }
.vpill.me{ background:rgba(46,232,166,.16); border-color:var(--green); color:var(--green); }
.vpill .vm{ position:absolute; right:-2px; bottom:-2px; width:8px; height:8px; border-radius:50%;
  background:#f87171; border:1.5px solid var(--bg-2); }

#voice-bar{ position:fixed; left:50%; transform:translateX(-50%);
  bottom:calc(var(--dock-h, 72px) + 26px); z-index:300;
  display:flex; align-items:center; gap:14px; flex-wrap:wrap;
  background:var(--bg-2); border:1px solid rgba(46,232,166,.35); border-radius:14px;
  padding:10px 16px; box-shadow:0 10px 40px rgba(0,0,0,.55); max-width:calc(100vw - 32px); }
.vb-l{ display:flex; align-items:center; gap:8px; }
.vb-l b{ font-size:13px; }
.vb-dot{ width:8px; height:8px; border-radius:50%; background:#2EE8A6;
  box-shadow:0 0 8px #2EE8A6aa; animation:livePulse 2s infinite; }
.vb-n{ font-size:11px; color:var(--text-3); }
.vb-who{ display:flex; gap:4px; }
.vb-r{ display:flex; gap:7px; }
.vb-btn{ background:var(--bg-3); border:1px solid var(--border-md); color:var(--text-1);
  border-radius:8px; padding:7px 14px; font-size:12px; font-weight:700; cursor:pointer;
  font-family:inherit; min-height:auto; }
.vb-btn.muted{ background:rgba(248,113,113,.14); border-color:rgba(248,113,113,.4); color:#f87171; }
.vb-btn.leave{ background:rgba(248,113,113,.1); border-color:rgba(248,113,113,.3); color:#f87171; }
.vb-msg{ flex-basis:100%; font-size:11.5px; color:#fbbf24; }
@media (max-width:640px){
  #voice-bar{ left:12px; right:12px; transform:none; max-width:none; justify-content:space-between; }
}

.vlock{ font-size:9px; font-weight:800; letter-spacing:.05em; text-transform:uppercase;
  color:var(--text-3); background:var(--bg-4); border-radius:4px; padding:1px 5px; margin-left:6px; }
.vx{ color:var(--text-3); font-size:15px; line-height:1; padding:0 3px; cursor:pointer; }
.vx:hover{ color:#f87171; }
.vsub{ font-size:9.5px; font-weight:800; letter-spacing:.09em; text-transform:uppercase;
  color:var(--text-3); margin:10px 0 5px; }
.vroom.livemeet{ background:rgba(251,191,36,.08); border-color:rgba(251,191,36,.3); }
.vactions{ display:flex; gap:6px; margin-top:8px; }
.vactions button{ flex:1; background:var(--bg-3); border:1px solid var(--border); color:var(--text-2);
  border-radius:8px; padding:6px 8px; font-size:11.5px; font-weight:700; cursor:pointer;
  font-family:inherit; min-height:auto; }
.vactions button:hover{ color:var(--text-1); border-color:var(--text-3); }
#voice-mini{ position:fixed; right:18px; bottom:calc(var(--dock-h,72px) + 26px); z-index:300;
  display:flex; align-items:center; gap:8px; cursor:pointer;
  background:var(--bg-2); border:1px solid rgba(46,232,166,.35); border-radius:999px;
  padding:8px 15px; box-shadow:0 8px 28px rgba(0,0,0,.5); font-size:12.5px; }

/* Home page voice row */
.hv-label{ font-size:10px; font-weight:800; letter-spacing:.09em; text-transform:uppercase;
  color:var(--text-3); margin-bottom:9px; display:flex; align-items:center; gap:9px; }
.hv-now{ font-size:9.5px; font-weight:800; letter-spacing:.05em; color:#fbbf24;
  background:rgba(251,191,36,.14); border-radius:5px; padding:2px 7px; text-transform:none; }
.hv-row{ display:flex; gap:8px; flex-wrap:wrap; }
.hv-room{ display:inline-flex; align-items:center; gap:9px; cursor:pointer;
  background:var(--bg-2); border:1px solid var(--border); border-radius:999px;
  padding:8px 15px 8px 13px; font-family:inherit; font-size:12.5px; color:var(--text-2);
  min-height:auto; transition:border-color .15s, background .15s; }
.hv-room:hover{ border-color:var(--text-3); color:var(--text-1); }
.hv-room.live{ border-color:rgba(46,232,166,.4); background:rgba(46,232,166,.06); }
.hv-room b{ font-size:12.5px; font-weight:700; color:var(--text-1); }
.hv-dot{ width:7px; height:7px; border-radius:50%; background:var(--border-md); flex:none; }
.hv-dot.on{ background:#2EE8A6; box-shadow:0 0 6px #2EE8A6aa; }
.hv-who{ display:inline-flex; align-items:center; gap:3px; }
.hv-av{ width:20px; height:20px; border-radius:50%; background:var(--bg-4);
  border:1px solid var(--border-md); color:var(--text-2); display:inline-flex;
  align-items:center; justify-content:center; font-size:8px; font-weight:800; }
.hv-more{ font-size:10px; color:var(--text-3); font-weight:700; margin-left:2px; }
.hv-join{ font-size:11px; font-weight:700; color:var(--green); }

/* Count and the hover list of who is in a room */
.hv-room{ position:relative; }
.hv-n{ font-size:11px; font-weight:800; color:var(--green);
  background:rgba(46,232,166,.14); border-radius:999px; padding:1px 8px; }
.hv-pop{ position:absolute; left:50%; transform:translateX(-50%) translateY(4px);
  bottom:calc(100% + 8px); z-index:60; min-width:170px; max-width:260px;
  background:var(--bg-2); border:1px solid var(--border-md); border-radius:11px;
  padding:9px 11px; box-shadow:0 10px 30px rgba(0,0,0,.55);
  display:flex; flex-direction:column; gap:6px; text-align:left;
  opacity:0; pointer-events:none; transition:opacity .14s, transform .14s; }
.hv-room:hover .hv-pop{ opacity:1; transform:translateX(-50%) translateY(0); }
.hv-pop:after{ content:''; position:absolute; top:100%; left:50%; margin-left:-5px;
  border:5px solid transparent; border-top-color:var(--border-md); }
.hv-p{ display:flex; align-items:center; gap:7px; font-size:12px; color:var(--text-1);
  white-space:nowrap; }
.hv-p i{ font-style:normal; font-size:9px; font-weight:800; letter-spacing:.04em;
  text-transform:uppercase; color:#f87171; margin-left:auto; }
.hv-av.sm{ width:18px; height:18px; font-size:7.5px; }
@media (hover:none){ .hv-pop{ display:none; } }


/* A meeting in progress reads differently from a room standing empty: it has a
   name, a time and people already in it, so it gets a wider card than a chip. */
.hv-meet{ display:flex; align-items:center; gap:10px; width:100%; text-align:left;
  padding:11px 13px; margin-bottom:7px; border-radius:11px; cursor:default;
  background:var(--bg-3); border:1px solid var(--border); color:var(--text-2);
  font-family:inherit; font-size:13px; }
.hv-meet.live{ cursor:pointer; border-color:rgba(46,232,166,.35);
  background:linear-gradient(90deg, rgba(46,232,166,.09), transparent); }
.hv-meet.live:hover{ border-color:var(--green); }
.hv-mt{ display:flex; flex-direction:column; min-width:0; flex:1; }
.hv-mt b{ font-size:13.5px; font-weight:700; color:var(--text-1);
  overflow:hidden; text-overflow:ellipsis; white-space:nowrap; }
.hv-mt i{ font-style:normal; font-size:11.5px; color:var(--text-3); margin-top:2px;
  overflow:hidden; text-overflow:ellipsis; white-space:nowrap; }
.hv-meet .hv-join{ flex:none; }
