/* ============================================================================
 * mobile.css — InTeraNet distinct mobile mode
 * Every rule is scoped under `body.mobile-mode` (toggled at runtime by
 * mobile.js via isMobile()). On desktop this file is inert, so there is zero
 * risk of regressing the PC layout. The shell (#m-root) is hidden unless
 * mobile-mode is active.
 * ========================================================================== */

/* ---- Shell visibility -------------------------------------------------- */
#m-root { display: none; }
body.mobile-mode #m-root { display: block; }

/* Hide the desktop shell; its children are physically relocated into the
 * mobile screens while mobile-mode is active (mobile.js move/restore). */
body.mobile-mode .dashboard-container { display: none !important; }
body.mobile-mode .sidebar-overlay { display: none !important; }
body.mobile-mode { overflow: hidden; }

/* ---- Full-screen stacked views ---------------------------------------- */
.m-screen { display: none; }
body.mobile-mode .m-screen.m-active {
    display: flex;
    flex-direction: column;
    position: fixed;
    top: 0;
    left: 0;
    right: 0;
    bottom: calc(56px + env(safe-area-inset-bottom));
    background: var(--bg-primary);
    z-index: 50;
}

.m-screen-body {
    flex: 1;
    min-height: 0;
    display: flex;
    flex-direction: column;
    overflow-y: auto;
    -webkit-overflow-scrolling: touch;
}

/* Force relocated panels visible regardless of the inline display:none/flex
 * toggles that dashboard.js sets (selectGroup / showChatPanel / etc.).
 * Screen visibility is owned by .m-active above, not by these nodes. */
body.mobile-mode #chatPanel,
body.mobile-mode #friendsPanel,
body.mobile-mode #chatsSection,
body.mobile-mode #channelsSection {
    display: flex !important;
    flex-direction: column;
    flex: 1;
    min-height: 0;
    height: auto !important;
    width: 100%;
}
/* Servers list: full-width rows (avatar + name pulled from the title attr),
 * instead of the cramped desktop icon rail. */
body.mobile-mode #mScreenBody-servers #groupsList {
    display: flex !important;
    flex-direction: column;
    align-items: stretch;
    gap: 4px;
    padding: 8px;
    width: 100%;
}
body.mobile-mode #mScreenBody-servers .group-item {
    display: flex !important;
    flex-direction: row !important;
    align-items: center;
    gap: 14px;
    width: 100%;
    height: auto !important;
    margin: 0 !important;
    padding: 10px 14px;
    border-radius: 14px;
    box-sizing: border-box;
    cursor: pointer;
    position: relative;
}
body.mobile-mode #mScreenBody-servers .group-item:active { background: var(--bg-secondary); }
body.mobile-mode #mScreenBody-servers .group-item .group-avatar {
    width: 48px !important;
    height: 48px !important;
    flex-shrink: 0;
    border-radius: 14px;
}
body.mobile-mode #mScreenBody-servers .group-item::after {
    content: attr(title);
    flex: 1;
    min-width: 0;
    font-weight: 600;
    font-size: 16px;
    color: var(--text-primary);
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
}
body.mobile-mode #mScreenBody-servers .group-item .unread-badge {
    position: static !important;
    margin-left: auto;
    flex-shrink: 0;
}

/* "You" screen: show the user menu expanded as a settings list rather than
 * hidden behind the ⋮ toggle. */
body.mobile-mode #mScreenBody-you .sidebar-footer {
    display: flex;
    flex-direction: column;
    align-items: stretch;
    gap: 8px;
    padding: 16px;
    height: auto;
}
body.mobile-mode #mScreenBody-you .user-info {
    gap: 14px;
    padding: 8px 6px 16px;
    border-bottom: 1px solid var(--border-color);
}
body.mobile-mode #mScreenBody-you #sidebarMenuBtn { display: none; }   /* toggle not needed */
body.mobile-mode #mScreenBody-you #sidebarMenu,
body.mobile-mode #mScreenBody-you #sidebarMenu.hidden {
    display: flex !important;
    flex-direction: column;
    position: static !important;
    inset: auto !important;
    visibility: visible !important;
    width: 100%;
    min-width: 0;
    box-shadow: none;
    border: none;
    background: none;
    border-radius: 0;
}
body.mobile-mode #mScreenBody-you #sidebarMenu button {
    padding: 16px 12px;
    font-size: 16px;
    border-radius: 12px;
    border-bottom: 1px solid var(--border-color);
}
body.mobile-mode #mScreenBody-you #sidebarMenu button:active { background: var(--bg-secondary); }

/* The chat panel manages its own internal scroll (messagesContainer); don't
 * double-scroll the wrapper. */
body.mobile-mode #mScreenBody-chat { overflow: hidden; }

/* ---- App bars (top of drilldown / list screens) ----------------------- */
.m-appbar {
    display: flex;
    align-items: center;
    gap: 10px;
    height: 52px;
    flex-shrink: 0;
    padding: 0 12px;
    padding-top: env(safe-area-inset-top);
    background: var(--bg-secondary);
    border-bottom: 1px solid var(--border-color);
    box-sizing: content-box;
}
.m-appbar .m-title {
    font-weight: 600;
    font-size: 17px;
    color: var(--text-primary);
    flex: 1;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}
.m-back,
.m-appbar-action {
    background: none;
    border: none;
    color: var(--text-primary);
    cursor: pointer;
    width: 40px;
    height: 40px;
    border-radius: 50%;
    display: flex;
    align-items: center;
    justify-content: center;
}
.m-back { font-size: 30px; line-height: 1; }
.m-appbar-action { font-size: 24px; }
.m-back:active,
.m-appbar-action:active { background: var(--bg-primary); }

/* ---- Bottom tab bar --------------------------------------------------- */
#mTabBar { display: none; }
body.mobile-mode #mTabBar {
    display: flex;
    position: fixed;
    left: 0;
    right: 0;
    bottom: 0;
    height: calc(56px + env(safe-area-inset-bottom));
    padding-bottom: env(safe-area-inset-bottom);
    background: var(--bg-secondary);
    border-top: 1px solid var(--border-color);
    z-index: 60;
}
.m-tab {
    flex: 1;
    background: none;
    border: none;
    cursor: pointer;
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    gap: 2px;
    color: var(--text-muted);
    font-size: 11px;
    padding: 6px 0;
}
.m-tab .m-tab-ico { font-size: 20px; line-height: 1; }
.m-tab.active { color: var(--accent-color); }

/* ---- Repurpose existing hamburger as the chat "back" button ----------- */
/* Hide the legacy drawer hamburgers everywhere in mobile-mode... */
body.mobile-mode .mobile-menu-btn { display: none !important; }
/* ...except the one inside the chat header, which becomes the back chevron. */
body.mobile-mode #chatPanel .chat-header #mobileMenuBtn {
    display: inline-flex !important;
    order: -1;            /* sit before the title */
    font-size: 0;         /* hide the original ☰ glyph */
    width: 40px;
    height: 40px;
    align-items: center;
    justify-content: center;
}
body.mobile-mode #chatPanel .chat-header #mobileMenuBtn::before {
    content: "\2039";     /* ‹ */
    font-size: 30px;
    line-height: 1;
}
body.mobile-mode .chat-header { align-items: center; }

/* ---- Touch target sizing --------------------------------------------- */
body.mobile-mode button { touch-action: manipulation; }

/* ============================================================================
 * Phase 2 — Modals as mobile sheets
 * Generic modals dock to the bottom as swipe-dismissable sheets; the big
 * settings/group-settings modals go full-screen. #mediaViewerModal keeps its
 * own full-screen viewer untouched. Inline max-width on .modal-content needs
 * !important to override.
 * ========================================================================== */
body.mobile-mode .modal:not(#mediaViewerModal) {
    align-items: flex-end !important;
}
body.mobile-mode .modal:not(#mediaViewerModal) > .modal-content {
    width: 100% !important;
    max-width: 100% !important;
    max-height: 90dvh;
    border-radius: 18px 18px 0 0 !important;
    padding-bottom: calc(20px + env(safe-area-inset-bottom));
    animation: mSheetUp 0.25s ease-out;
    position: relative;
    will-change: transform;
}
/* Grabber handle at the top of each sheet. */
body.mobile-mode .modal:not(#mediaViewerModal) > .modal-content::before {
    content: "";
    display: block;
    width: 40px;
    height: 4px;
    border-radius: 2px;
    background: var(--text-muted);
    opacity: 0.4;
    margin: -8px auto 12px;
}
@keyframes mSheetUp {
    from { transform: translateY(100%); }
    to { transform: translateY(0); }
}
/* While the user is dragging a sheet, disable the entry animation. */
body.mobile-mode .modal-content.m-dragging {
    animation: none;
    transition: none;
}
body.mobile-mode .modal-content.m-snapback {
    transition: transform 0.2s ease-out;
}

/* Full-screen modals (settings, group settings). Higher specificity (#id)
 * wins over the generic sheet rule above. */
body.mobile-mode #settingsModal > .modal-content,
body.mobile-mode #groupSettingsModal > .modal-content {
    width: 100% !important;
    max-width: 100% !important;
    height: 100dvh;
    max-height: 100dvh !important;
    border-radius: 0 !important;
    padding-top: calc(28px + env(safe-area-inset-top));
}
body.mobile-mode #settingsModal > .modal-content::before,
body.mobile-mode #groupSettingsModal > .modal-content::before {
    display: none;   /* no grabber on full-screen modals */
}

/* ============================================================================
 * Phase 3 — Full-screen call overlay + return banner
 * The existing #callEmbedPanel (moved to <body> in mobile mode) becomes a
 * full-screen overlay that slides up when body.m-call-active. Minimizing keeps
 * the call running and shows a return banner above the tab bar.
 * ========================================================================== */
body.mobile-mode #callEmbedPanel {
    position: fixed !important;
    inset: 0 !important;
    width: 100% !important;
    min-width: 0 !important;
    max-width: 100% !important;
    height: 100dvh !important;
    z-index: 130 !important;
    border-left: none !important;
    transform: translateY(100%);
    transition: transform 0.3s ease;
}
body.mobile-mode.m-call-active #callEmbedPanel { transform: translateY(0); }
body.mobile-mode #callEmbedIframe { min-width: 0 !important; width: 100% !important; }
body.mobile-mode #callEmbedHeader { padding-top: calc(8px + env(safe-area-inset-top)) !important; }
body.mobile-mode #callEmbedPopoutBtn { display: none !important; }   /* no popups on mobile */
.m-call-min {
    background: none;
    border: 1px solid var(--border-color);
    border-radius: 5px;
    color: var(--text-muted);
    font-size: 14px;
    padding: 3px 9px;
    cursor: pointer;
}

/* Return banner (shown when the call is minimized). */
#mCallBanner { display: none; }
body.mobile-mode.m-call-minimized #mCallBanner {
    display: flex;
    position: fixed;
    left: 0;
    right: 0;
    /* Natural spot: just above the tab bar. The active chat screen is shrunk by
     * this banner's height (see rule below) so the composer rides up and the
     * banner fills the gap — nothing overlaps. */
    bottom: calc(56px + env(safe-area-inset-bottom));
    height: 44px;
    z-index: 70;
    align-items: center;
    gap: 10px;
    padding: 0 14px;
    background: var(--accent-color);
    color: #fff;
    cursor: pointer;
}
/* While a call is minimized, lift the whole active screen by the banner height
 * (44px) on top of the tab-bar inset, so the composer sits ABOVE the banner
 * instead of the banner covering it. The keyboard-open rule overrides this. */
body.mobile-mode.m-call-minimized .m-screen.m-active {
    bottom: calc(100px + env(safe-area-inset-bottom));
}
.m-callbanner-dot {
    width: 10px;
    height: 10px;
    border-radius: 50%;
    background: #fff;
    animation: mPulse 1.2s infinite;
}
.m-callbanner-txt { flex: 1; font-weight: 600; font-size: 14px; }
.m-callbanner-leave {
    background: rgba(0, 0, 0, 0.25);
    border: none;
    color: #fff;
    width: 30px;
    height: 30px;
    border-radius: 50%;
    cursor: pointer;
}
@keyframes mPulse { 0%, 100% { opacity: 1; } 50% { opacity: 0.3; } }

/* ============================================================================
 * Phase 5 — Soft keyboard / safe area / input zoom
 * ========================================================================== */
/* While the keyboard is open, lift the active screen above it and hide the tab
 * bar so the chat input stays visible (iOS-overlay fallback via --m-kb). */
body.mobile-mode.m-kb-open #mTabBar { display: none; }
body.mobile-mode.m-kb-open .m-screen.m-active { bottom: var(--m-kb, 0px); }

/* iOS zooms inputs with font-size < 16px on focus; force 16px in mobile mode. */
body.mobile-mode input,
body.mobile-mode textarea,
body.mobile-mode [contenteditable="true"] {
    font-size: 16px;
}

/* ============================================================================
 * Message interactions (mobile): 3-dot button, action sheet, swipe-to-reply
 * ========================================================================== */
body.mobile-mode .copy-message-btn { display: none !important; }   /* replaced by ⋮ */

body.mobile-mode .message { position: relative; }
body.mobile-mode .msg-more-btn {
    position: absolute;
    top: 2px;
    right: 4px;
    width: 28px;
    height: 28px;
    border: none;
    border-radius: 50%;
    background: rgba(127, 127, 127, 0.18);
    color: var(--text-secondary);
    font-size: 18px;
    line-height: 1;
    display: flex;
    align-items: center;
    justify-content: center;
    cursor: pointer;
    z-index: 3;
}
/* Keep the ⋮ on the top-right for ALL messages (incl. own) — placing it on the
   left collided with the avatar/name and was awkward to reach. */
body.mobile-mode .message.own .msg-more-btn { left: auto; right: 4px; }
/* Desktop: never show it. */
.msg-more-btn { display: none; }
body.mobile-mode .msg-more-btn { display: flex; }

/* ============================================================================
 * Message input row (mobile): drop emoji, move Attach to the LEFT of the input
 * ========================================================================== */
/* Emoji picker isn't needed on phones — the OS keyboard has its own. */
body.mobile-mode .emoji-picker-container { display: none !important; }

/* Pull the attach button out to the left of the message input. The row is a
   flexbox; negative order floats it ahead of the input wrapper. */
body.mobile-mode #mpConnectBtn { order: -2; }
/* style.css's mobile @media pins #attachBtn position:absolute over the input's
   left edge. Override to a real flex item so it sits OUTSIDE the rounded field. */
body.mobile-mode #attachBtn {
    position: static;
    transform: none;
    top: auto;
    left: auto;
    order: -1;
    flex-shrink: 0;
    width: 38px;
    height: 38px;
    padding: 0;
    margin: 0;
    display: flex;
    align-items: center;
    justify-content: center;
    border: none;
    border-radius: 50%;
    background: rgba(127, 127, 127, 0.16);
    color: var(--text-secondary);
}
body.mobile-mode #attachBtn:active { background: rgba(127, 127, 127, 0.28); }
/* Swap the paper glyph for a clean "+" that inherits the button colour. */
body.mobile-mode #attachBtn img { display: none !important; }
body.mobile-mode #attachBtn::before {
    content: '';
    width: 22px;
    height: 22px;
    background: currentColor;
    -webkit-mask: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'%3E%3Cpath fill='none' stroke='black' stroke-width='2.5' stroke-linecap='round' d='M12 5v14M5 12h14'/%3E%3C/svg%3E") center / contain no-repeat;
            mask: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'%3E%3Cpath fill='none' stroke='black' stroke-width='2.5' stroke-linecap='round' d='M12 5v14M5 12h14'/%3E%3C/svg%3E") center / contain no-repeat;
}

/* Give the message field a sensible inner padding now that the right-side
   emoji/attach buttons are gone, so text isn't pinned against a dead gap. */
body.mobile-mode .message-input-wrapper #messageInput[contenteditable] {
    padding: 11px 14px;
}

/* ============================================================================
 * Invite card (mobile): the desktop card uses `margin: 0 100px` on its body
 * which crushes the timer/buttons on a phone. Rebuild edge-to-edge & stacked.
 * ========================================================================== */
body.mobile-mode .invite-card {
    max-width: 100%;
    width: 100%;
    margin: 8px 0;
    padding: 14px 16px;
}
body.mobile-mode .invite-card:hover { transform: none; }   /* no hover lift on touch */
body.mobile-mode .invite-card-header { justify-content: flex-start; }
body.mobile-mode .invite-card-group-name { font-size: 16px; }
body.mobile-mode .invite-card-body {
    margin: 0;                 /* kill the 100px desktop side margins */
    gap: 10px;
    margin-top: 10px;
}
body.mobile-mode .invite-card-timer { align-self: flex-start; }
body.mobile-mode .invite-card-actions { gap: 8px; }
body.mobile-mode .invite-card-join-btn,
body.mobile-mode .invite-card-ping-btn {
    padding: 11px 12px;
    font-size: 14px;
}

/* ============================================================================
 * Jump-to-latest button (mobile): Claude-style — a small circular chevron
 * button, horizontally CENTERED just above the composer, never overlapping it.
 *
 * mobile.js relocates the wrapper INSIDE #chatInput, so we anchor it to the
 * composer itself with `bottom: 100%` (its bottom edge = the composer's top
 * edge). This tracks the composer automatically: it rides up as the field
 * grows to multiple lines, and moves with the screen when the call banner
 * shrinks the chat — no pixel guessing, no overlap in any state.
 *
 * dashboard.js creates the wrapper with inline fixed/bottom/right (correct for
 * desktop); the mobile overrides must use !important to win over those. */
body.mobile-mode #chatInput { position: relative; overflow: visible; }
body.mobile-mode #scrollToBottomBtnWrapper {
    position: absolute !important;
    bottom: calc(100% + 10px) !important;
    top: auto !important;
    left: 50% !important;
    right: auto !important;
    transform: translateX(-50%) !important;
    z-index: 40;            /* under the composer's own popups, over messages */
}
/* Claude-style pill: small, subtle surface circle with a soft shadow rather
 * than the bold accent disc used on desktop. */
body.mobile-mode #scrollToBottomBtn {
    bottom: 0 !important;
    width: 34px !important;
    height: 34px !important;
    font-size: 18px;
    background: var(--bg-secondary);
    color: var(--text-primary);
    border: 1px solid var(--border-color);
    box-shadow: 0 2px 10px rgba(0, 0, 0, 0.22);
}
body.mobile-mode #scrollToBottomBtn:hover { transform: none; background: var(--bg-secondary); }

/* Swipe-to-reply cue */
.m-reply-cue {
    position: absolute;
    left: 14px;
    top: 50%;
    transform: translateY(-50%) scale(0.7);
    width: 38px;
    height: 38px;
    border-radius: 50%;
    background: var(--accent-color);
    color: #fff;
    display: flex;
    align-items: center;
    justify-content: center;
    opacity: 0;
    pointer-events: none;
    transition: transform 0.12s ease;
    z-index: 1;
}
.m-reply-cue.ready { transform: translateY(-50%) scale(1); }

/* Message action sheet (opened by the ⋮ button) */
.m-msg-overlay {
    position: fixed;
    inset: 0;
    z-index: 1200;
    background: rgba(0, 0, 0, 0.5);
    display: flex;
    align-items: flex-end;
    opacity: 0;
    transition: opacity 0.2s ease;
}
.m-msg-overlay.show { opacity: 1; }
.m-msg-sheet {
    width: 100%;
    background: var(--bg-secondary);
    border-radius: 18px 18px 0 0;
    padding: 8px 12px calc(12px + env(safe-area-inset-bottom));
    transform: translateY(100%);
    transition: transform 0.25s ease;
    max-height: 80vh;
    overflow-y: auto;
}
.m-msg-overlay.show .m-msg-sheet { transform: translateY(0); }
.m-msg-grab {
    width: 40px;
    height: 4px;
    border-radius: 2px;
    background: var(--text-muted);
    opacity: 0.4;
    margin: 4px auto 10px;
}
.m-msg-reactions {
    display: flex;
    justify-content: space-between;
    gap: 4px;
    overflow-x: auto;
    padding: 4px 2px 12px;
    border-bottom: 1px solid var(--border-color);
    margin-bottom: 6px;
}
.m-msg-reactions .reaction-btn {
    flex: 0 0 auto;
    width: 44px;
    height: 44px;
    border: none;
    background: none;
    border-radius: 50%;
    cursor: pointer;
    display: flex;
    align-items: center;
    justify-content: center;
}
.m-msg-reactions .reaction-btn.reacted { background: var(--accent-color); }
.m-msg-actions { display: flex; flex-direction: column; }
.m-msg-row {
    display: flex;
    align-items: center;
    gap: 16px;
    width: 100%;
    padding: 15px 10px;
    background: none;
    border: none;
    color: var(--text-primary);
    font-size: 16px;
    text-align: left;
    cursor: pointer;
    border-radius: 12px;
}
.m-msg-row:active { background: var(--bg-primary); }
.m-msg-row.danger { color: var(--danger); }
.m-msg-row svg { flex-shrink: 0; }

/* ============================================================================
 * New-message search overlay (Messages tab ✎)
 * ========================================================================== */
#mNewDm { display: none; }
body.mobile-mode.m-newdm-open #mNewDm {
    display: flex;
    flex-direction: column;
    position: fixed;
    inset: 0;
    z-index: 90;
    background: var(--bg-primary);
}
.m-newdm-bar {
    display: flex;
    align-items: center;
    gap: 8px;
    padding: 8px 12px;
    padding-top: calc(8px + env(safe-area-inset-top));
    border-bottom: 1px solid var(--border-color);
    flex-shrink: 0;
}
#mNewDmInput {
    flex: 1;
    border: none;
    background: var(--bg-secondary);
    color: var(--text-primary);
    border-radius: 10px;
    padding: 10px 14px;
    outline: none;
}
.m-newdm-results { flex: 1; overflow-y: auto; padding: 6px; }
.m-newdm-hint { text-align: center; color: var(--text-muted); padding: 24px; }
.m-newdm-item {
    display: flex;
    align-items: center;
    gap: 14px;
    width: 100%;
    padding: 10px 12px;
    background: none;
    border: none;
    color: var(--text-primary);
    text-align: left;
    cursor: pointer;
    border-radius: 12px;
}
.m-newdm-item:active { background: var(--bg-secondary); }
.m-newdm-av {
    width: 44px;
    height: 44px;
    flex-shrink: 0;
    border-radius: 50%;
    overflow: hidden;
    background: var(--accent-color);
    color: #fff;
    font-weight: 600;
    display: flex;
    align-items: center;
    justify-content: center;
}
.m-newdm-av img { width: 100%; height: 100%; object-fit: cover; }
.m-newdm-name { display: flex; flex-direction: column; min-width: 0; font-weight: 600; }
.m-newdm-name small { font-weight: 400; color: var(--text-muted); font-size: 13px; }

/* ============================================================================
 * In-place tab search (servers / messages / friends)
 * The bar visually replaces the appbar; results fill the screen body above the
 * tab bar. Opens with a small slide+fade for smoothness.
 * ========================================================================== */
#mSearch { display: none; }
body.mobile-mode.m-search-open #mSearch {
    display: flex;
    flex-direction: column;
    position: fixed;
    top: 0;
    left: 0;
    right: 0;
    bottom: calc(56px + env(safe-area-inset-bottom));
    z-index: 65;
    background: var(--bg-primary);
    animation: mSearchIn 0.18s ease-out;
}
@keyframes mSearchIn { from { opacity: 0; transform: translateY(-8px); } to { opacity: 1; transform: translateY(0); } }
.m-search-bar {
    display: flex;
    align-items: center;
    gap: 8px;
    height: 52px;
    flex-shrink: 0;
    padding: 0 10px;
    padding-top: env(safe-area-inset-top);
    background: var(--bg-secondary);
    border-bottom: 1px solid var(--border-color);
}
#mSearchInput {
    flex: 1;
    border: none;
    background: var(--bg-primary);
    color: var(--text-primary);
    border-radius: 10px;
    padding: 10px 14px;
    outline: none;
}
.m-search-x {
    background: none;
    border: none;
    color: var(--text-secondary);
    font-size: 20px;
    width: 40px;
    height: 40px;
    border-radius: 50%;
    cursor: pointer;
    flex-shrink: 0;
}
.m-search-x:active { background: var(--bg-primary); }
.m-search-results { flex: 1; overflow-y: auto; padding: 6px; }

/* Non-friend choice dialog */
.m-choice-name {
    text-align: center;
    font-weight: 700;
    font-size: 17px;
    padding: 4px 0 12px;
    border-bottom: 1px solid var(--border-color);
    margin-bottom: 6px;
}

/* Friends tab: hide the legacy header (tabs + search + pending) — replaced by
 * the appbar search icon; pending requests now live in the You tab. */
body.mobile-mode #friendsPanel .friends-header { display: none !important; }

/* ============================================================================
 * You tab: pending friend requests section
 * ========================================================================== */
#mYouPending:empty { display: none; }
#mYouPending { padding: 8px 6px 4px; }
.m-you-section {
    font-size: 13px;
    font-weight: 700;
    text-transform: uppercase;
    letter-spacing: 0.04em;
    color: var(--text-muted);
    padding: 6px 10px;
}
/* Collapsible Incoming / Outgoing groups */
.m-pend-group { margin: 4px 6px 8px; }
.m-pend-head {
    display: flex;
    align-items: center;
    gap: 10px;
    width: 100%;
    padding: 12px 12px;
    background: var(--bg-secondary);
    border: none;
    border-radius: 12px;
    color: var(--text-primary);
    font-size: 15px;
    font-weight: 600;
    cursor: pointer;
}
.m-pend-chev { font-size: 14px; transition: transform 0.18s ease; }
.m-pend-group.collapsed .m-pend-chev { transform: rotate(-90deg); }
.m-pend-label { flex: 1; text-align: left; }
.m-pend-count {
    min-width: 22px;
    height: 22px;
    padding: 0 7px;
    border-radius: 11px;
    background: var(--accent-color);
    color: #fff;
    font-size: 12px;
    display: flex;
    align-items: center;
    justify-content: center;
}
.m-pend-body {
    overflow: hidden;
    transition: max-height 0.2s ease;
}
.m-pend-group.collapsed .m-pend-body { display: none; }
.m-pending-row {
    display: flex;
    align-items: center;
    gap: 12px;
    padding: 8px 10px;
}
.m-pending-row .m-newdm-name small { color: var(--text-muted); }
.m-pending-acts { margin-left: auto; display: flex; gap: 6px; flex-shrink: 0; }
.m-pa {
    border: none;
    border-radius: 8px;
    padding: 8px 12px;
    font-size: 15px;
    cursor: pointer;
    background: var(--bg-primary);
    color: var(--text-primary);
}
.m-pa.accept { background: var(--accent-color); color: #fff; }
.m-pa.reject { background: var(--danger); color: #fff; }

/* ============================================================================
 * Media viewer (mobile): full-screen cinematic + touch-sized controls.
 * Gestures (pinch/pan/double-tap/swipe-down) are wired in mobile.js.
 * ========================================================================== */
body.mobile-mode #mediaViewerModal .mvs-shell {
    width: 100vw;
    height: 100dvh;
    max-width: 100vw;
    max-height: 100dvh;
    border-radius: 0;
}
body.mobile-mode #mediaViewerModal .mvs-topbar {
    padding-top: calc(8px + env(safe-area-inset-top));
}
body.mobile-mode #mediaViewerModal .mvs-stage {
    touch-action: none;   /* we handle pinch/pan ourselves */
}
body.mobile-mode #mediaViewerModal .mvs-stage img,
body.mobile-mode #mediaViewerModal .mvs-stage video {
    max-width: 100vw;
    max-height: 78dvh;
    transform-origin: center center;
}
body.mobile-mode #mediaViewerModal .mvs-nav {
    width: 44px;
    height: 44px;
}
body.mobile-mode #mediaViewerModal .mvs-btn { min-height: 40px; }

/* ============================================================================
 * Bot / announcements + misc desktop features adapted for mobile
 * ========================================================================== */

/* Bot DM gate ("Request Chat" / "please be patient") sits where the composer is,
 * so give it the same safe-area cushion above the home indicator / tab bar. */
body.mobile-mode #botGateBar {
    padding: 14px 16px calc(16px + env(safe-area-inset-bottom));
}
body.mobile-mode #botGateBar #botRequestChatBtn { width: 100%; padding: 13px 0; font-size: 15px; }

/* "New version available" banner: keep it a top bar but clear of the notch and
 * above the mobile header, with a tappable height. */
body.mobile-mode #updateBanner {
    padding-top: calc(10px + env(safe-area-inset-top));
    font-size: 13px;
    z-index: 9999;
}

/* The per-DM call / reconnect button must be a comfortable tap target. */
body.mobile-mode #dmCallWrapper button {
    width: 38px !important;
    height: 38px !important;
    font-size: 20px;
}

/* Hotkeys are keyboard-only — hide that settings pane (and its nav item) on mobile. */
body.mobile-mode .settings-nav-item[data-pane="hotkeys"],
body.mobile-mode #pane-hotkeys { display: none !important; }

/* Surface distinction: mobile browser is a sheet; installed app owns the screen. */
body.mobile-mode.surface-web-mobile #groupSettingsModal > .modal-content {
    position:absolute;
    inset:auto 0 0;
    width:100% !important;
    height:auto;
    min-height:72dvh;
    max-height:92dvh !important;
    padding-top:0;
    border-radius:20px 20px 0 0 !important;
}
body.mobile-mode.surface-web-mobile #groupSettingsModal > .modal-content::before {
    display:block;
    margin:8px auto 4px;
}
body.mobile-mode.surface-app-mobile #groupSettingsModal > .modal-content,
body.mobile-mode.surface-app-mobile #channelPermissionsModal > .modal-content {
    position:fixed;
    inset:0;
    width:100% !important;
    height:100dvh;
    max-height:100dvh !important;
    border-radius:0 !important;
    padding-top:env(safe-area-inset-top);
}
body.mobile-mode.surface-app-mobile #channelPermissionsModal > .modal-content::before {
    display:none;
}
