/* Chat links: keep current color, emphasize with underline + bold */
.message-content a {
  color: inherit;
  text-decoration: underline;
  font-weight: 700;
}
/* --- Toggle Switch Styles for Encryption --- */
.toggle-switch-label {
    margin-bottom: 8px;
    font-weight: 500;
}

.toggle-switch {
    position: relative;
    display: inline-block;
    width: 50px;
    height: 28px;
}

.toggle-switch input {
    opacity: 0;
    width: 0;
    height: 0;
}

.slider {
    position: absolute;
    cursor: pointer;
    top: 0;
    left: 0;
    right: 0;
    bottom: 0;
    background-color: #ccc;
    transition: .4s;
}

.slider:before {
    position: absolute;
    content: "";
    height: 20px;
    width: 20px;
    left: 4px;
    bottom: 4px;
    background-color: white;
    transition: .4s;
}

input:checked + .slider {
    background-color: var(--app-primary);
}

input:checked + .slider:before {
    transform: translateX(22px);
}

.slider.round {
    border-radius: 28px;
}

.slider.round:before {
    border-radius: 50%;
}

/* Connection Status Banner */
.connection-status-banner {
    position: fixed;
    top: 0;
    left: 0;
    width: 100%;
    padding: 10px;
    text-align: center;
    color: white;
    font-weight: 500;
    z-index: 10001; /* Above everything else */
    transition: background-color 0.3s ease, transform 0.3s ease;
    transform: translateY(-100%);
}

/* --- Video Focus Layout Styles --- */
#videos {
    position: relative;
    width: 100%;
    min-height: 400px;
    /*display: block;*/
}

.video-wrapper {
    transition: width 0.4s ease-in-out, height 0.4s ease-in-out, top 0.4s ease-in-out, left 0.4s ease-in-out;
    background: rgba(0, 0, 0, 0.8);
    border-radius: 8px;
    overflow: hidden;
}

.video-wrapper video {
    display: block;
    width: 100%;
    height: 100%;
    object-fit: cover;
}

.video-wrapper.focused {
    /* z-index is managed dynamically by JavaScript - removed !important to allow click-to-front */
    border: 3px solid var(--app-primary);
    box-shadow: 0 0 25px rgba(10, 132, 255, 0.6);
}

.video-container.has-focused .video-wrapper:not(.focused) {
    border: 1px solid #444;
    box-shadow: none;
}

.connection-status-banner:not(.hidden) {
    transform: translateY(0);
}

.connection-status-banner.connected {
    background-color: #28a745; /* Green for success */
}

.connection-status-banner.disconnected {
    background-color: #dc3545; /* Red for error */
}

.connection-status-banner.reconnecting {
    background-color: #ffc107; /* Yellow for warning/reconnecting */
    color: #333;
}

.hidden {
    display: none !important;
}

/* Encrypted Config UI Styles */
.login-description {
    color: #b8c5d6;
    margin-bottom: 20px;
    text-align: center;
    font-size: 16px;
    line-height: 1.5;
}

.button-group {
    display: flex;
    gap: 12px;
    margin-top: 20px;
    justify-content: center;
    flex-wrap: wrap;
}

.primary-btn {
    background: linear-gradient(135deg, #4a90e2, #357abd);
    color: white;
    border: none;
    padding: 16px 32px;
    font-size: 16px;
    font-weight: 600;
    border-radius: 12px;
    cursor: pointer;
    transition: all 0.3s ease;
    min-width: 140px;
    min-height: 48px;
    touch-action: manipulation;
}

.primary-btn:hover {
    background: linear-gradient(135deg, #357abd, #2a5d8f);
    transform: translateY(-2px);
}

.primary-btn:active {
    transform: translateY(0);
}

.secondary-btn {
    background: transparent;
    color: #4a90e2;
    border: 2px solid #4a90e2;
    padding: 14px 28px;
    font-size: 16px;
    font-weight: 600;
    border-radius: 12px;
    cursor: pointer;
    transition: all 0.3s ease;
    min-width: 140px;
    min-height: 48px;
    touch-action: manipulation;
}

.secondary-btn:hover {
    background: #4a90e2;
    color: white;
    transform: translateY(-2px);
}

.secondary-btn:active {
    transform: translateY(0);
}

.config-btn {
    background: #2c3e50;
    color: #ecf0f1;
    border: 1px solid #34495e;
    padding: 12px 20px;
    font-size: 14px;
    border-radius: 10px;
    cursor: pointer;
    transition: all 0.3s ease;
    margin: 8px;
    min-height: 44px;
    touch-action: manipulation;
}

.config-btn:hover {
    background: #34495e;
    transform: translateY(-1px);
}

.config-actions {
    display: flex;
    justify-content: center;
    flex-wrap: wrap;
    margin-top: 15px;
    padding: 15px;
    background: rgba(52, 73, 94, 0.3);
    border-radius: 8px;
}

.error-message {
    background: rgba(231, 76, 60, 0.2);
    border: 1px solid #e74c3c;
    color: #e74c3c;
    padding: 10px;
    border-radius: 6px;
    margin-bottom: 15px;
    font-size: 14px;
    text-align: center;
}

#setupUi h3,
#loginUi h3 {
    color: #4a90e2;
    margin-bottom: 20px;
    text-align: center;
    font-weight: 600;
}

#setupUi,
#loginUi {
    animation: fadeIn 0.3s ease-in-out;
}

@keyframes fadeIn {
    from {
        opacity: 0;
        transform: translateY(-10px);
    }
    to {
        opacity: 1;
        transform: translateY(0);
    }
}

.config-locked-overlay {
    position: fixed;
    top: 0;
    left: 0;
    right: 0;
    bottom: 0;
    background: rgba(0, 0, 0, 0.8);
    z-index: 9999;
    display: flex;
    align-items: center;
    justify-content: center;
}

.config-unlock-modal {
    background: #2c3e50;
    padding: 30px;
    border-radius: 12px;
    box-shadow: 0 8px 32px rgba(0, 0, 0, 0.5);
    max-width: 400px;
    width: 90%;
    text-align: center;
    animation: scaleIn 0.3s ease-out;
}

@keyframes scaleIn {
    from {
        transform: scale(0.8);
        opacity: 0;
    }
    to {
        transform: scale(1);
        opacity: 1;
    }
}

.config-unlock-modal h3 {
    color: #f39c12;
    margin-bottom: 15px;
}

.config-unlock-modal p {
    color: #b8c5d6;
    margin-bottom: 20px;
    font-size: 14px;
}

/* Base styles */
* {
    margin: 0;
    padding: 0;
    box-sizing: border-box;
    -webkit-tap-highlight-color: transparent;
}

:root {
    --app-primary: #0A84FF;
    --app-secondary: #5E5CE6;
    --app-background: #000000;
    --app-card-bg: #1C1C1E;
    --app-card-secondary: #2C2C2E;
    --app-text-primary: #FFFFFF;
    --app-text-secondary: #8E8E93;
    --app-border-radius: 12px;
    --app-status-bar-height: env(safe-area-inset-top, 44px);
    --app-bottom-bar-height: env(safe-area-inset-bottom, 34px);
}

/* ========== CUSTOM SCROLLBAR STYLES ========== */
/* Webkit browsers (Chrome, Safari, Edge) */
::-webkit-scrollbar {
    width: 8px;
    height: 8px;
}

::-webkit-scrollbar-track {
    background: var(--app-card-bg);
    border-radius: 4px;
}

::-webkit-scrollbar-thumb {
    background: var(--app-card-secondary);
    border-radius: 4px;
    border: 2px solid var(--app-card-bg);
}

::-webkit-scrollbar-thumb:hover {
    background: var(--app-primary);
}

/* Firefox */
* {
    scrollbar-width: thin;
    scrollbar-color: var(--app-card-secondary) var(--app-card-bg);
}

body {
    font-family: -apple-system, BlinkMacSystemFont, 'SF Pro Text', 'Segoe UI', Roboto, Helvetica, sans-serif;
    line-height: 1.6;
    background-color: var(--app-background);
    position: relative;
    overflow: hidden; /* FIX: Prevents scrollbars when videos go off-screen */
    overscroll-behavior: none; /* Prevents bounce effects on Mac */
    color: var(--app-text-primary);
    height: 100vh;
    height: 100dvh; /* Use dynamic viewport height when available */
    width: 100vw;
    display: flex;
    flex-direction: column;
    /* Mobile-optimized touch behavior */
    -webkit-touch-callout: none;
    -webkit-user-select: none;
    -khtml-user-select: none;
    -moz-user-select: none;
    -ms-user-select: none;
    user-select: none;
    /* Better font rendering on mobile */
    -webkit-font-smoothing: antialiased;
    -moz-osx-font-smoothing: grayscale;
}

/* Animated Ocean Waves Container */
.ocean-waves {
    position: fixed;
    bottom: 0;
    left: 0;
    width: 100%;
    height: 25vh;
    min-height: 150px;
    max-height: 250px;
    overflow: hidden;
    z-index: -1;
    pointer-events: none;
}

.wave {
    position: absolute;
    bottom: 0;
    left: 0;
    width: 200%;
    height: 100%;
    background-repeat: repeat-x;
    background-size: 50% 100%;
    /* GPU acceleration for low CPU usage */
    will-change: transform;
    backface-visibility: hidden;
    -webkit-backface-visibility: hidden;
}

/* Wave 1 - Back layer (darkest) */
.wave1 {
    background: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 1200 120' preserveAspectRatio='none'%3E%3Cpath d='M0,60 C150,120 350,0 600,60 C850,120 1050,0 1200,60 L1200,120 L0,120 Z' fill='rgba(30,40,80,0.9)'/%3E%3C/svg%3E");
    background-size: 50% 100%;
    animation: waveMove 25s linear infinite;
    opacity: 1;
}

/* Wave 2 - Middle layer */
.wave2 {
    background: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 1200 120' preserveAspectRatio='none'%3E%3Cpath d='M0,80 C200,40 400,100 600,80 C800,60 1000,100 1200,80 L1200,120 L0,120 Z' fill='rgba(40,55,100,0.8)'/%3E%3C/svg%3E");
    background-size: 50% 100%;
    animation: waveMove 18s linear infinite reverse;
    opacity: 0.9;
    bottom: -5px;
}

/* Wave 3 - Front layer (lightest, with blue tint) */
.wave3 {
    background: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 1200 120' preserveAspectRatio='none'%3E%3Cpath d='M0,90 C100,50 300,110 500,90 C700,70 900,110 1100,90 C1150,85 1200,95 1200,90 L1200,120 L0,120 Z' fill='rgba(50,70,120,0.85)'/%3E%3C/svg%3E");
    background-size: 50% 100%;
    animation: waveMove 12s linear infinite;
    opacity: 0.95;
    bottom: -8px;
}

/* Wave 4 - Very front accent wave */
.wave4 {
    background: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 1200 120' preserveAspectRatio='none'%3E%3Cpath d='M0,100 C150,70 350,110 550,95 C750,80 950,105 1200,100 L1200,120 L0,120 Z' fill='rgba(60,85,140,0.7)'/%3E%3C/svg%3E");
    background-size: 50% 100%;
    animation: waveMove 8s linear infinite reverse;
    opacity: 0.8;
    bottom: -10px;
}

@keyframes waveMove {
    0% {
        transform: translate3d(0, 0, 0);
    }
    100% {
        transform: translate3d(-50%, 0, 0);
    }
}

/* Respect user's reduced motion preference - pauses animation for accessibility */
@media (prefers-reduced-motion: reduce) {
    .wave {
        animation: none !important;
    }
}

/* Pause wave animation after login to save CPU */
body.app-visible .wave {
    animation-play-state: paused;
}

/* Hide body pseudo-elements - we're using .ocean-waves now */
body::before {
    display: none;
}

body::after {
    display: none;
}

.app-container {
    width: 100%;
    height: 100%;
    display: flex;
    flex-direction: column;
    position: relative;
    z-index: 1;
    flex: 1;
    overflow: hidden;
}

#app-content {
    display: flex;
    flex-direction: column;
    height: 100%;
    overflow: hidden;
    position: relative;
}

.tab-content-container {
    flex: 1;
    overflow: hidden; /* Desktop: prevent container-level scrolling */
    -webkit-overflow-scrolling: touch;
    padding-top: env(safe-area-inset-top, 0);
    padding-bottom: 0; /* Desktop: remove bottom padding */
}

/* Mobile: restore original scroll behavior for tab-content-container */
@media (max-width: 768px) {
    .tab-content-container {
        overflow-y: auto; /* Mobile: allow container scrolling */
        padding-bottom: 70px; /* Mobile: restore bottom padding for tab bar */
    }
}

/* UI Toggle Button */
.ui-toggle-btn {
    background-color: rgba(26, 35, 48, 0.8);
    color: var(--app-text-primary);
    border: none;
    padding: 6px 12px;
    border-radius: 20px;
    cursor: pointer;
    transition: all 0.2s;
    backdrop-filter: blur(10px);
    -webkit-backdrop-filter: blur(10px);
    font-weight: 500;
    box-shadow: 0 4px 12px rgba(0, 0, 0, 0.2);
    font-size: 14px;
    margin-left: 5px;
}

.ui-toggle-btn:hover {
    background-color: rgba(42, 59, 77, 0.9);
    transform: translateY(-2px);
}

.ui-toggle-btn:active {
    transform: translateY(0);
}

.toggle-controls {
    position: absolute;
    top: calc(var(--app-status-bar-height) + 10px);
    right: 20px;
    z-index: 10;
}

/* App title */
.app-title {
    display: flex;
    justify-content: space-between;
    align-items: center;
    padding: calc(var(--app-status-bar-height) + 20px) 24px 20px 24px;
    background-color: rgba(0, 0, 0, 0.8);
    backdrop-filter: blur(15px);
    -webkit-backdrop-filter: blur(15px);
    position: sticky;
    top: 0;
    z-index: 100;
    min-height: 80px;
}

.app-title h1 {
    color: var(--app-primary);
    font-size: 28px;
    font-weight: 700;
    letter-spacing: -0.8px;
    margin: 0;
}

.app-title-right {
    display: flex;
    align-items: center;
    gap: 16px;
    flex-wrap: wrap;
}

.encryption-status {
    display: flex;
    align-items: center;
    gap: 8px;
    background-color: rgba(26, 35, 48, 0.6);
    padding: 6px 14px;
    border-radius: 20px;
    backdrop-filter: blur(8px);
    -webkit-backdrop-filter: blur(8px);
    margin-top: 8px;
}

.status-indicator {
    width: 12px;
    height: 12px;
    border-radius: 50%;
    background-color: #30D158;
    display: inline-block;
    box-shadow: 0 0 8px rgba(52, 199, 89, 0.8);
    position: relative;
}

.status-indicator.secure {
    background-color: #34c759;
    animation: pulse 2s infinite;
}

/* POST-QUANTUM STREAM NEGOTIATION: amber dot when media legs fall back to classical
   DTLS-SRTP for one or more peers. Messages & files remain post-quantum. */
.status-indicator.mixed {
    background-color: #FF9F0A;
    box-shadow: 0 0 8px rgba(255, 159, 10, 0.8);
    animation: pulse 2s infinite;
}

/* Fully classical (no PQ anywhere, e.g. user disabled PQ globally). Rare but possible. */
.status-indicator.classical {
    background-color: #FF453A;
    box-shadow: 0 0 8px rgba(255, 69, 58, 0.8);
    animation: pulse 2s infinite;
}

@keyframes pulse {
    0% { opacity: 0.7; }
    50% { opacity: 1; }
    100% { opacity: 0.7; }
}

/* Resize handle for videos */
.video-wrapper {
    position: relative;
}

/* Resize handle */
.video-wrapper::after {
    content: '';
    position: absolute;
    bottom: 0;
    right: 0;
    width: 30px; /* Larger hit area */
    height: 30px;
    background: linear-gradient(135deg, transparent 50%, rgba(255, 255, 255, 0.6) 50%);
    cursor: nwse-resize;
    border-radius: 0 0 12px 0;
    z-index: 100;
}

/* Ensure handle is touchable on mobile */
@media (max-width: 768px) {
    .video-wrapper::after {
        width: 40px !important;
        height: 40px !important;
        background: linear-gradient(135deg, transparent 50%, rgba(10, 132, 255, 0.8) 50%) !important;
        display: block !important;
    }
}

.status-text {
    font-size: 14px;
    color: #34c759;
    font-weight: 600;
    letter-spacing: 0.3px;
}

/* Login section */
#login-section {
    width: 100%;
    max-width: 400px;
    /* Desktop: top/bottom margin with auto horizontal centering */
    margin: 20px auto;
    background-color: var(--app-card-bg);
    border-radius: var(--app-border-radius);
    padding: 32px;
    box-shadow: 0 16px 32px rgba(0, 0, 0, 0.4);
    animation: slideUp 0.5s ease-out;
    /*
     * Make the login card itself scrollable when its content (multi-account
     * selector + login form + security badge) is taller than the viewport.
     * Without this, the surrounding chain (`body` and `.app-container` both
     * use `overflow: hidden`) clips the bottom of the card and the password
     * input/login button become unreachable on short viewports or once the
     * iOS soft keyboard pops up.
     *
     * The 40px subtraction accounts for the 20px top + 20px bottom margin so
     * the card never extends past the visible viewport. `100dvh` adapts to
     * the dynamic viewport (e.g., shrinks when the iOS keyboard appears),
     * with a `100vh` fallback for browsers that don't support `dvh`. Mirrors
     * the body's existing dvh/vh pattern (see the `body` rule above).
     *
     * `overflow-y: auto` (not `scroll`) means the scrollbar is invisible when
     * the card already fits — single-account/setup screens look identical to
     * before. The webkit/Firefox scrollbar styling defined at the top of
     * this file is inherited automatically so we don't restyle here.
     */
    max-height: calc(100vh - 40px);
    max-height: calc(100dvh - 40px);
    overflow-y: auto;
    -webkit-overflow-scrolling: touch; /* Smooth momentum scroll on iOS */
}

@keyframes slideUp {
    from { transform: translateY(30px); opacity: 0; }
    to { transform: translateY(0); opacity: 1; }
}

#login-section h2 {
    color: var(--app-primary);
    margin-bottom: 24px;
    text-align: center;
    font-size: 28px;
    font-weight: 700;
    letter-spacing: -0.5px;
}

.input-group {
    margin-bottom: 24px;
}

.input-group input {
    width: 100%;
    padding: 20px;
    border-radius: 16px;
    border: 2px solid rgba(58, 74, 93, 0.3);
    background-color: var(--app-card-secondary);
    color: var(--app-text-primary);
    font-size: 18px;
    margin-bottom: 20px;
    transition: all 0.3s;
    outline: none;
    min-height: 56px;
    touch-action: manipulation;
}

.input-group input:focus {
    border-color: var(--app-primary);
    box-shadow: 0 0 0 2px rgba(10, 132, 255, 0.3);
}

.input-group button {
    width: 100%;
    padding: 20px;
    border-radius: 16px;
    border: none;
    background-color: var(--app-primary);
    color: white;
    font-size: 18px;
    font-weight: 700;
    cursor: pointer;
    transition: all 0.3s;
    box-shadow: 0 6px 16px rgba(10, 132, 255, 0.4);
    min-height: 56px;
    touch-action: manipulation;
}

.input-group button:hover {
    background-color: #007AFF;
    transform: translateY(-2px);
    box-shadow: 0 6px 16px rgba(10, 132, 255, 0.4);
}

.input-group button:active {
    transform: translateY(0);
    box-shadow: 0 2px 8px rgba(10, 132, 255, 0.3);
}

.security-info {
    margin-top: 30px;
    background-color: var(--app-card-secondary);
    border-radius: var(--app-border-radius);
    padding: 20px;
    box-shadow: 0 4px 12px rgba(0, 0, 0, 0.1);
}

.security-badge {
    display: flex;
    align-items: center;
    gap: 12px;
    margin-bottom: 12px;
    background-color: rgba(10, 132, 255, 0.1);
    padding: 10px 16px;
    border-radius: 12px;
}

.badge-icon {
    font-size: 20px;
    color: var(--app-primary);
}

.badge-text {
    font-weight: 600;
    color: var(--app-primary);
    letter-spacing: -0.3px;
}

.security-description {
    font-size: 15px;
    color: var(--app-text-secondary);
    line-height: 1.5;
    padding: 0 4px;
}

/* App section */
#app-section {
    display: flex;
    flex-direction: column;
    height: 100%;
    overflow: hidden;
}

.app-tabs {
    display: flex;
    justify-content: space-around;
    background-color: rgba(0, 0, 0, 0.7);
    backdrop-filter: blur(10px);
    -webkit-backdrop-filter: blur(10px);
    padding: 10px 0;
    position: sticky;
    bottom: 0;
    z-index: 100;
    padding-bottom: calc(10px + var(--app-bottom-bar-height));
}

.tab-button {
    background: none;
    border: none;
    color: var(--app-text-secondary);
    padding: 16px 20px;
    cursor: pointer;
    font-size: 16px;
    position: relative;
    font-weight: 600;
    flex: 1;
    transition: all 0.3s;
    border-radius: 0;
    text-align: center;
    min-height: 56px;
    touch-action: manipulation;
    display: flex;
    align-items: center;
    justify-content: center;
}

.tab-button:not(:last-child) {
    border-right: 1px solid rgba(255, 255, 255, 0.1); /* Delimiter */
}

.tab-button.active {
    color: var(--app-primary);
}

.tab-button::after {
    content: '';
    position: absolute;
    bottom: -5px;
    left: 50%;
    transform: translateX(-50%);
    width: 6px;
    height: 6px;
    border-radius: 50%;
    background-color: transparent;
    transition: all 0.2s;
}

.tab-button.active::after {
    background-color: var(--app-primary);
}

.tab-content {
    display: none;
    flex: 1;
    overflow-y: auto;
    -webkit-overflow-scrolling: touch;
    padding: 5px;
}

.tab-content.active {
    display: block;
    animation: fadeIn 0.3s ease-out;
}

@keyframes fadeIn {
    from { opacity: 0; }
    to { opacity: 1; }
}

/* Rooms list section */
.rooms-list-section {
    background-color: var(--app-card-bg);
    border-radius: var(--app-border-radius);
    padding: 20px;
    margin-bottom: 20px;
    box-shadow: 0 8px 24px rgba(0, 0, 0, 0.15);
    overflow: hidden;
    display: flex;
    flex-direction: column;
    max-height: calc(100vh - 160px); /* Constrain to viewport: 80px header + 40px padding + 40px margins */
    height: auto; /* Auto height within max constraint */
}

.rooms-header {
    display: flex;
    justify-content: space-between;
    align-items: center;
    margin-bottom: 16px;
    padding-bottom: 12px;
    border-bottom: 1px solid rgba(255, 255, 255, 0.1);
    flex-shrink: 0; /* Don't shrink */
}

.rooms-header h3 {
    margin: 0;
    color: var(--app-primary);
    font-size: 18px;
    font-weight: 600;
    letter-spacing: -0.3px;
}

/* Contacts User Header */
.contacts-user-header {
    display: flex;
    align-items: center;
    gap: 12px;
    cursor: pointer;
    transition: opacity 0.2s;
    padding: 5px;
    border-radius: 8px;
}

.contacts-user-header:hover {
    background-color: rgba(255, 255, 255, 0.05);
}

.contacts-user-avatar {
    width: 40px;
    height: 40px;
    border-radius: 50%;
    object-fit: cover;
    border: 2px solid var(--app-primary);
}

.contacts-user-info {
    display: flex;
    flex-direction: column;
}

/* Override existing h3 margin inside this specific container */
.contacts-user-info h3 {
    margin: 0;
    font-size: 16px;
    font-weight: 700;
    color: var(--app-text-primary);
    line-height: 1.2;
}

.contacts-subtitle {
    font-size: 11px;
    color: var(--app-primary);
    font-weight: 500;
}

.create-room-btn {
    background-color: var(--app-primary);
    color: white;
    border: none;
    padding: 14px 24px;
    border-radius: 24px;
    cursor: pointer;
    font-weight: 700;
    font-size: 16px;
    transition: all 0.3s;
    box-shadow: none;
    display: flex;
    align-items: center;
    min-height: 48px;
    touch-action: manipulation;
}

.create-room-btn:hover {
    background-color: #007AFF;
    transform: translateY(-2px);
    box-shadow: none;
}

.create-room-btn:active {
    transform: translateY(0);
    box-shadow: none;
}

.rooms-container {
    flex: 1; /* Fill available space */
    overflow-y: auto;
    margin-bottom: 10px; /* Reduced margin */
    min-height: 100px; /* Ensure minimum scrollable area without excessive push */
}

.no-rooms-message {
color: #999;
text-align: center;
padding: 20px;
font-style: italic;
}

.join-room-section {
    display: flex;
    gap: 12px;
    margin-top: 8px;
    padding-top: 12px;
    border-top: 1px solid rgba(255, 255, 255, 0.1);
    flex-shrink: 0; /* Don't shrink */
}

.join-room-section input {
    flex: 1;
    padding: 14px 16px;
    border-radius: 12px;
    border: 1px solid rgba(58, 74, 93, 0.3);
    background-color: var(--app-card-secondary);
    color: var(--app-text-primary);
    font-size: 16px;
    transition: all 0.2s;
    outline: none;
    min-height: 48px;
    touch-action: manipulation;
}

.join-room-section input:focus {
    border-color: var(--app-primary);
    box-shadow: 0 0 0 2px rgba(10, 132, 255, 0.3);
}

.join-room-section button {
    background-color: var(--app-primary);
    color: white;
    border: none;
    padding: 14px 20px;
    border-radius: 12px;
    cursor: pointer;
    font-weight: 600;
    transition: all 0.2s;
    box-shadow: 0 4px 10px rgba(10, 132, 255, 0.3);
    min-height: 48px;
    touch-action: manipulation;
}

.join-room-section button:hover {
    background-color: #007AFF;
    transform: translateY(-2px);
}

.join-room-section button:active {
    transform: translateY(0);
}

.join-room-section .scan-qr-btn {
    flex: 0 0 auto;
    align-self: center;
    min-width: 48px;
    width: 48px;
    height: 48px;
    padding: 0;
    font-size: 20px;
    line-height: 1;
    background-color: var(--app-primary);
}

/* =====================================================================
 * Create Contact modal — Join tab "code + scan" row
 * ---------------------------------------------------------------------
 * The Join tab inside #createRoomModal pairs the typed-code input
 * (#modalJoinCodeInput) with a QR-scan button (#modalScanQrBtn) on a
 * single horizontal row. Originally the bottom `.join-room-section`
 * strip below the contacts list provided this combo, but that strip
 * was removed (in v2 first, now in v1 too) to keep the contacts list
 * the full vertical space and make the modal the single entry point.
 *
 * SPECIFICITY NOTE — this is the entire reason this block is so verbose
 *   The button lives inside `.input-group`, and `.input-group button`
 *   higher in this stylesheet (≈ line 732) blasts every <button> in
 *   that container with `width: 100%; padding: 20px; min-height: 56px;
 *   box-shadow: <giant blue glow>`. Specificity of that rule is
 *   (0,1,1) — class + tag. A bare `.scan-qr-btn` rule is (0,1,0) and
 *   LOSES the cascade, leaving us with a 100% wide, 56px tall, blue-
 *   glowing camera button that swallows the input next to it. Until
 *   I caught this, the rendered modal had a tiny pill of an input on
 *   the left and a giant dark slab labeled "📷" on the right — which
 *   is the bug the user reported in the second-pass UI review.
 *   Fix is to combine TWO classes (`.scan-qr-btn.modal-scan-qr-btn`)
 *   for (0,2,0), which wins cleanly without resorting to !important.
 *
 * Why the wrapper exists
 *   `.input-group` already has its own column layout (label on top,
 *   field below), so we can't just slap the button at the same level
 *   as the input — it would land on a new line. Wrapping input +
 *   button in `.join-code-with-scan` gives them their own flex row
 *   without disturbing the label-stacks-above behaviour the rest of
 *   the modal relies on.
 *
 * `.scan-qr-btn` base rule
 *   The only existing `.scan-qr-btn` rule above is scoped to
 *   `.join-room-section .scan-qr-btn` — so a `.scan-qr-btn` placed
 *   anywhere else (like inside this modal) would inherit only the
 *   browser default <button> styling and look broken. The base rule
 *   below covers visual properties (typography, transitions); the
 *   high-specificity `.scan-qr-btn.modal-scan-qr-btn` block below
 *   handles size/layout to overpower `.input-group button`.
 * ===================================================================== */
.join-code-with-scan {
    display: flex;
    gap: 10px;
    /* Both children are now hard-locked to 56px tall (input via the
       rule below, button via `.scan-qr-btn.modal-scan-qr-btn`), so
       align-items value is cosmetic — `center` is kept as a safety
       net in case some future rule changes one of the heights. */
    align-items: center;
    width: 100%;
}
.join-code-with-scan > input {
    flex: 1 1 auto;
    min-width: 0;               /* allow shrink so button never overflows */
    /* MATCH THE BUTTON'S 56px BASELINE
       The user reported on the third pass that the camera button
       looked "slightly below" the input even though both were
       inside an `align-items: center` flex row. Root cause:
       `.input-group input` (line ≈ 712) sets `margin-bottom: 20px`
       AND `.modal input` (line ≈ 3339) sets its own padding —
       together those gave the input an OUTER flex height of ~80px
       (60px visible + 20px margin) while the button's outer height
       was 56px. Flexbox `align-items: center` centers items by
       their OUTER box size, so the input's visible content sat
       ~10px higher than the button's visible center, producing
       the perceived offset.
       
       Fix: pin the input to exactly the button's dimensions inside
       this wrapper. With both children at the same outer 56px,
       any align-items strategy produces a flush top-and-bottom
       match. !important on each property because both
       `.input-group input` (0,1,1) AND `.modal input` (0,1,1) are
       trying to set padding/margin/min-height; this rule's
       (0,2,0 with the wrapper combinator) is enough on paper but
       !important removes any specificity ambiguity from future
       responsive rules.
       
       Width 16px horizontal padding keeps the placeholder text
       breathing comfortably without inflating vertical size — the
       18px font from `.input-group input` still fits because
       `box-sizing: border-box` lets the 56px total absorb the
       2px border on each edge and the ~27px text line-height. */
    height: 56px !important;
    min-height: 56px !important;
    max-height: 56px !important;
    margin: 0 !important;       /* kill `.input-group input`'s 20px margin-bottom */
    padding: 0 16px !important; /* horizontal only — vertical determined by height */
    box-sizing: border-box;
}

/* Base .scan-qr-btn — visual properties only. Anything that conflicts
   with `.input-group button` is moved to the higher-specificity rule
   below. Kept here so future standalone uses of `.scan-qr-btn` outside
   an `.input-group` still get a sane default. */
.scan-qr-btn {
    border: none;
    color: #fff;                /* light text on the walnut/blue bg */
    font-size: 20px;
    line-height: 1;
    cursor: pointer;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    -webkit-tap-highlight-color: transparent;
    transition: background-color 0.15s ease, transform 0.1s ease,
                box-shadow 0.15s ease;
}

/* High-specificity rule: `.scan-qr-btn.modal-scan-qr-btn` is (0,2,0)
   which beats `.input-group button` (0,1,1). EVERY property here is
   one that `.input-group button` also sets, plus the size/layout we
   actually want. Order matters: width and min-height are the two
   the parent rule sets aggressively, so they're listed first. */
.scan-qr-btn.modal-scan-qr-btn {
    /* override `.input-group button { width: 100%; min-height: 56px; }`.
       56x56 is chosen because it equals the input's `min-height: 56px`
       baseline, making the button a clean square at exactly the same
       footprint as a single line of the input field.
       
       WHY EVERY DIMENSION USES !important
       The user reported on the second pass that the button STILL
       rendered as a tall portrait rectangle even after I bumped the
       selector to (0,2,0). Two specificity-paired rules in this file
       — `.input-group button` (0,1,1) on desktop and the same selector
       inside the @media (max-width: 768px) block on mobile — were
       still in play, and depending on viewport / cache the larger
       padding (`padding: 20px`) plus `min-height: 56px` were enough
       to inflate the button beyond a square. !important on the six
       dimension properties + `padding` is the only way to guarantee
       a 56x56 regardless of specificity surprises in any future
       responsive rule that might add height. The aesthetic
       properties (border-radius, color, etc.) stay un-!important
       because they're not where the regression keeps coming from. */
    flex: 0 0 auto;
    width: 56px !important;
    min-width: 56px !important;
    max-width: 56px !important;
    height: 56px !important;
    min-height: 56px !important;
    max-height: 56px !important;
    /* override `.input-group button { padding: 20px; }` AND the mobile
       override `.input-group button { padding: 18px }` in the
       @media (max-width: 768px) block — either of those leaking in
       turns the 56x56 box into a 92x92+ blob. */
    padding: 0 !important;
    /* override `.input-group button { border-radius: 16px; }`. 14px
       reads as "rounded square" — large enough to feel like a touch
       target, small enough that the corners don't dominate the icon. */
    border-radius: 14px;
    /* override `.input-group button { background-color: var(--app-primary); }` —
       same colour, redeclared explicitly so the cascade is unambiguous */
    background-color: var(--app-primary);
    color: #fff;                /* belt-and-braces; ensures legible icon */
    /* slightly larger emoji to fill the 56x56 surface visually */
    font-size: 24px;
    /* override `.input-group button { box-shadow: 0 6px 16px rgba(10,132,255,0.4); }`.
       The giant blue glow is meant for big "Login" / "Join" buttons; on
       a 56px icon button it dominates the modal AND visually inflates
       the perceived button size (which contributed to the user reading
       it as "too tall"). !important here too because the parent rule
       sets the same property and we want zero ambiguity. */
    box-shadow: 0 2px 6px rgba(0, 0, 0, 0.15) !important;
    /* `align-self: center` (paired with `align-items: center` on the
       wrapper) keeps the square vertically centered next to the taller
       input field. */
    align-self: center;
    /* Defensive: keep the box-sizing identical to siblings so any
       padding/border math stays predictable even if a future rule
       changes box-sizing on `.modal *` or similar. */
    box-sizing: border-box;
}

.scan-qr-btn.modal-scan-qr-btn:hover {
    background-color: #007AFF !important;
    transform: translateY(-1px);
    box-shadow: 0 4px 12px rgba(10, 132, 255, 0.25) !important;
}
.scan-qr-btn.modal-scan-qr-btn:active {
    transform: translateY(0);
    box-shadow: 0 2px 6px rgba(0, 0, 0, 0.15) !important;
}
.scan-qr-btn.modal-scan-qr-btn:focus-visible {
    outline: 2px solid rgba(10, 132, 255, 0.6);
    outline-offset: 2px;
}

#qrScannerOverlay {
    position: fixed;
    inset: 0;
    background: rgba(0, 0, 0, 0.92);
    z-index: 100000;
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    padding: 16px;
    color: #fff;
}

#qrScannerOverlay .qr-scanner-frame {
    position: relative;
    width: min(90vw, 460px);
    aspect-ratio: 1 / 1;
    background: #000;
    border-radius: 16px;
    overflow: hidden;
    box-shadow: 0 10px 40px rgba(0, 0, 0, 0.6);
}

#qrScannerOverlay video {
    width: 100%;
    height: 100%;
    object-fit: cover;
}

#qrScannerOverlay .qr-scanner-reticle {
    position: absolute;
    inset: 12%;
    border: 3px solid rgba(10, 132, 255, 0.9);
    border-radius: 12px;
    box-shadow: 0 0 0 9999px rgba(0, 0, 0, 0.35);
    pointer-events: none;
}

#qrScannerOverlay .qr-scanner-status {
    margin-top: 16px;
    font-size: 15px;
    opacity: 0.85;
    text-align: center;
    max-width: 80vw;
}

#qrScannerOverlay .qr-scanner-controls {
    display: flex;
    gap: 10px;
    margin-top: 16px;
    flex-wrap: wrap;
    justify-content: center;
}

#qrScannerOverlay .qr-scanner-controls button {
    padding: 10px 18px;
    border: none;
    border-radius: 10px;
    font-size: 14px;
    font-weight: 600;
    cursor: pointer;
    background: #fff;
    color: #111;
}

#qrScannerOverlay .qr-scanner-controls button.qr-cancel {
    background: #e53935;
    color: #fff;
}

/* Media Controls Buttons */
.controls button {
    background-color: var(--app-primary);
    color: white;
    border: none;
    padding: 16px 24px;
    border-radius: 28px;
    cursor: pointer;
    transition: all 0.3s ease-out;
    font-weight: 700;
    font-size: 16px;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    text-transform: capitalize;
    box-shadow: 0 6px 16px rgba(10, 132, 255, 0.3);
    min-height: 56px;
    min-width: 120px;
    touch-action: manipulation;
    gap: 8px;
}

.controls button:hover:not(:disabled) {
    background-color: #007AFF; /* Slightly darker shade of primary on hover */
    transform: translateY(-2px);
    box-shadow: 0 6px 16px rgba(10, 132, 255, 0.3);
}

.controls button:active:not(:disabled) {
    transform: translateY(0);
    box-shadow: 0 2px 8px rgba(10, 132, 255, 0.2);
}

.controls button:disabled {
    background-color: var(--app-card-secondary);
    color: var(--app-text-secondary);
    opacity: 0.6;
    cursor: not-allowed;
    box-shadow: none;
    content-visibility: hidden;
}

/* Specific styling for stop/negative action buttons */
.controls button#stopVideo,
.controls button#stopAudio,
.controls button#stopScreenShare {
    background-color: #FF3B30; /* iOS red for destructive actions */
    box-shadow: 0 4px 12px rgba(255, 59, 48, 0.2);
}

.controls button#stopVideo:hover:not(:disabled),
.controls button#stopAudio:hover:not(:disabled),
.controls button#stopScreenShare:hover:not(:disabled) {
    background-color: #E03024; /* Darker red on hover */
    box-shadow: 0 6px 16px rgba(255, 59, 48, 0.3);
}

.controls button#stopVideo:active:not(:disabled),
.controls button#stopAudio:active:not(:disabled),
.controls button#stopScreenShare:active:not(:disabled) {
    box-shadow: 0 2px 8px rgba(255, 59, 48, 0.2);
}

/* Mute buttons can have a slightly different style to indicate state */
.controls button#muteVideo,
.controls button#muteAudio {
    background-color: var(--app-card-secondary);
    color: var(--app-text-primary);
    box-shadow: 0 4px 12px rgba(0, 0, 0, 0.1);
}

.controls button#muteVideo.muted,
.controls button#muteAudio.muted {
    background-color: #FF9500; /* iOS orange for warning/muted state */
    color: white;
    box-shadow: 0 4px 12px rgba(255, 149, 0, 0.2);
}

.controls button#muteVideo:hover:not(:disabled),
.controls button#muteAudio:hover:not(:disabled) {
    background-color: rgba(94, 92, 230, 0.15); /* Subtle hover for non-primary actions */
    transform: translateY(-2px);
}

.controls button#muteVideo.muted:hover:not(:disabled),
.controls button#muteAudio.muted:hover:not(:disabled) {
    background-color: #E68A00; /* Darker orange on hover */
    transform: translateY(-2px);
}

/* Video grid and controls */
.video-container {
    margin-top: 10px;
    display: flex;
    flex-wrap: wrap;
    gap: 15px;
    justify-content: center;
}

/* Ensure videos maintain proper aspect ratio */
.video-wrapper video, .remote-video-container video {
    width: 100%;
    height: 100%;
    object-fit: contain;
}

.room-content {
    height: 100%;
    display: flex;
    flex-direction: column;
    overflow: hidden;
    /* DUAL-PANE BRIDGE FIX: establish a positioning context so children with
     * `position: absolute; inset: 0` (notably .bridge-mode-container) stay
     * scoped to the right pane in the desktop dual-pane layout instead of
     * covering the whole viewport (including the contact sidebar).
     * In single-column mode this is harmless because the room-content already
     * fills the viewport when visible. */
    position: relative;
}

.room-header {
    display: flex;
    align-items: center;
    background-color: var(--app-card-bg);
    padding: 2px 2px;
    border-radius: var(--app-border-radius) var(--app-border-radius) 0 0;
    margin-bottom: 0;
    position: sticky;
    top: 0;
    z-index: 10;
    backdrop-filter: blur(10px);
    -webkit-backdrop-filter: blur(10px);
    box-shadow: 0 2px 8px rgba(0, 0, 0, 0.1);
}

.back-button {
    background: none;
    border: none;
    color: var(--app-primary);
    font-size: 22px;
    cursor: pointer;
    margin-right: 15px;
    width: 36px;
    height: 36px;
    display: flex;
    align-items: center;
    justify-content: center;
    border-radius: 50%;
    transition: all 0.2s;
}

.back-button:hover {
    background-color: rgba(10, 132, 255, 0.1);
}

.room-name-container {
    display: flex;
    align-items: center;
    flex: 1;
    /* Allow this flex child to shrink below the intrinsic width of
       its h3 + edit-button. Without this override the default
       min-width: auto pins the container to its content width and
       pushes trailing flex items (.connection-status, .call-btn,
       .room-header-menu-toggle) off the right edge of the viewport
       on narrow phones. With min-width: 0 the h3's ellipsis kicks
       in and the trailing items stay visible. */
    min-width: 0;
    overflow: hidden;
}

.room-header h3 {
    margin: 0;
    color: var(--app-text-primary);
    font-size: 18px;
    font-weight: 600;
    letter-spacing: -0.3px;
}

.edit-nickname-btn {
    background: none;
    border: none;
    color: var(--app-primary);
    font-size: 14px;
    cursor: pointer;
    margin-left: 10px;
    padding: 5px 10px;
    border-radius: 12px;
    transition: all 0.2s;
}

.edit-nickname-btn:hover {
    background-color: rgba(10, 132, 255, 0.1);
}

.room-code-display {
    font-size: 14px;
    color: #9db3ca;
    margin-top: 5px;
}

.connection-status .status-dot {
    width: 8px;
    height: 8px;
    border-radius: 50%;
    display: inline-block;
    margin-right: 5px;
    transition: background-color 0.3s;
}

.status-dot {
    width: 10px;
    height: 10px;
    border-radius: 50%;
    background-color: #4CAF50;
}

/* Pulse animation for server relay status */
@keyframes pulse-orange {
    0%, 100% {
        opacity: 1;
    }
    50% {
        opacity: 0.5;
    }
}

/* Call Button in Room Header */
.call-btn {
    display: inline-flex;
    align-items: center;
    gap: 4px;
    padding: 4px 12px;
    background: #4CAF50;
    color: white;
    border: none;
    border-radius: 16px;
    font-size: 12px;
    font-weight: 600;
    cursor: pointer;
    transition: background 0.2s, transform 0.1s;
    margin-left: 8px;
    white-space: nowrap;
    /* Pin at intrinsic width so the kebab next to us is never the
       first thing pushed off the right edge on narrow viewports.
       The .room-name-container (flex: 1, min-width: 0) is the
       proper release valve when the header overflows. */
    flex-shrink: 0;
}
.call-btn:hover { background: #43A047; transform: scale(1.05); }
.call-btn:active { transform: scale(0.95); }
.call-btn.calling {
    background: #ff9800;
    animation: pulse-orange 1.5s infinite;
    /* pointer-events: auto so the user can tap the button again to
       cancel their outgoing ring. The click handler in app.js
       (_handleCallButtonClick) detects the .calling class and routes
       the second click into client.cancelCall() instead of dialing
       again. Disabling pointer-events here would silently break that
       cancel affordance. */
    cursor: pointer;
}
.call-btn.end-call-btn { background: #f44336; }
.call-btn.end-call-btn:hover { background: #e53935; }

/* Incoming Call Modal
 *
 * iPad USABILITY FIX: previously this popup was anchored to the top-right
 * corner (top: 16px; right: 16px) with a slideInRight animation. On iPad
 * that corner is occupied by the room toolbar — the user had to fight the
 * Share / Settings / Reconnect buttons to hit Accept, and a stray tap on
 * the toolbar could send a different action while the call modal sat over
 * it. Centering the popup horizontally and pinning it to the upper third
 * of the viewport puts the Accept/Reject controls in clear space on every
 * form factor without overlapping the chat thread. The slideInDown keyframe
 * keeps the same visual "incoming notification" cue. */
.incoming-call-modal {
    position: fixed;
    top: 25%;
    left: 50%;
    transform: translate(-50%, -50%);
    z-index: 10000;
    animation: slideInDown 0.3s ease-out;
    /* Allow the content to size itself but cap to viewport so it never
     * runs off the side on narrow phones. */
    max-width: calc(100vw - 32px);
}
@keyframes slideInDown {
    from { transform: translate(-50%, calc(-50% - 60px)); opacity: 0; }
    to { transform: translate(-50%, -50%); opacity: 1; }
}
/* Legacy alias kept so any inline animation references still resolve. */
@keyframes slideInRight {
    from { transform: translate(-50%, calc(-50% - 60px)); opacity: 0; }
    to { transform: translate(-50%, -50%); opacity: 1; }
}
.incoming-call-content {
    display: flex;
    align-items: center;
    gap: 12px;
    padding: 12px 16px;
    background: linear-gradient(135deg, #1a2332 0%, #243447 100%);
    border: 1px solid #4CAF50;
    border-radius: 12px;
    box-shadow: 0 4px 24px rgba(76, 175, 80, 0.3);
}
.incoming-call-icon {
    animation: callPulse 1.2s ease-in-out infinite;
}
@keyframes callPulse {
    0%, 100% { transform: rotate(0deg); }
    25% { transform: rotate(-15deg); }
    50% { transform: rotate(15deg); }
    75% { transform: rotate(-10deg); }
}
.incoming-call-text {
    display: flex;
    flex-direction: column;
    gap: 2px;
}
.incoming-call-label {
    font-size: 11px;
    color: #9db3ca;
    text-transform: uppercase;
    letter-spacing: 0.5px;
}
.incoming-caller-name {
    font-size: 14px;
    font-weight: 600;
    color: #e0e0e0;
}
.incoming-call-actions {
    display: flex;
    gap: 8px;
    margin-left: 8px;
}
.accept-call-btn, .reject-call-btn {
    width: 40px;
    height: 40px;
    border-radius: 50%;
    border: none;
    cursor: pointer;
    display: flex;
    align-items: center;
    justify-content: center;
    transition: transform 0.15s;
}
.accept-call-btn { background: #4CAF50; color: white; }
.accept-call-btn:hover { transform: scale(1.1); background: #43A047; }
.reject-call-btn { background: #f44336; color: white; }
.reject-call-btn:hover { transform: scale(1.1); background: #e53935; }

/* Call-Media-Choice modal: large icon buttons for Mic / Video */
.call-media-choice-grid {
    display: grid;
    grid-template-columns: 1fr 1fr;
    gap: 12px;
}
.call-media-choice-btn {
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    gap: 6px;
    padding: 18px 12px;
    background: rgba(76, 175, 80, 0.1);
    color: inherit;
    border: 1px solid rgba(76, 175, 80, 0.35);
    border-radius: 10px;
    cursor: pointer;
    transition: background 0.15s, transform 0.1s, border-color 0.15s;
}
.call-media-choice-btn:hover {
    background: rgba(76, 175, 80, 0.22);
    border-color: rgba(76, 175, 80, 0.65);
    transform: translateY(-1px);
}
.call-media-choice-btn:active { transform: translateY(0); }
.call-media-choice-title { font-weight: 600; }
.call-media-choice-sub { font-size: 0.85em; opacity: 0.75; }

/* Per-call "Share LLM" toggle button inside call-media-choice modal.
   Two visual states keyed by the `.on` / `.off` class set from app.js:
     - .off (default): muted grey outline — matches the "not sharing"
       safe default so a user who just opens the modal sees the button
       as inactive rather than primary.
     - .on: amber/green fill to echo the accept-call colour palette
       used elsewhere in this modal; signals compute/cost is being
       shared outward so it stands out at a glance before dialling. */
.call-media-share-llm-btn {
    width: 100%;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    gap: 8px;
    padding: 10px 14px;
    border-radius: 8px;
    font-weight: 600;
    font-size: 14px;
    cursor: pointer;
    transition: background 0.15s, border-color 0.15s, color 0.15s, transform 0.1s;
}
.call-media-share-llm-btn.off {
    background: rgba(148, 163, 184, 0.12);
    color: #cbd5e1;
    border: 1px solid rgba(148, 163, 184, 0.45);
}
.call-media-share-llm-btn.off:hover {
    background: rgba(148, 163, 184, 0.22);
    border-color: rgba(148, 163, 184, 0.7);
}
.call-media-share-llm-btn.on {
    background: rgba(76, 175, 80, 0.22);
    color: #86efac;
    border: 1px solid rgba(76, 175, 80, 0.75);
}
.call-media-share-llm-btn.on:hover {
    background: rgba(76, 175, 80, 0.35);
    border-color: #4caf50;
}
.call-media-share-llm-btn:active { transform: translateY(1px); }

/* New Room Layout Styles */
.room-body {
    flex: 1;
    display: flex;
    overflow: hidden; /* Crucially, this prevents the entire body from scrolling */
    padding: 5px;
    position: relative;
    min-height: 0; /* Important for flex containers to shrink properly */
    height: 100%; /* Take full available height from parent */
}

/* Desktop Video Container - Overlay Mode */
.video-container {
    position: fixed !important; /* Fixed relative to window */
    top: 0;
    left: 0;
    width: 100vw !important;  /* Changed from 100% to break out of parent */
    height: 100vh !important; /* Changed from 100% to cover full viewport */
    z-index: 9000; /* High z-index to sit above chat */
    pointer-events: none; /* Let clicks pass through to chat */
    overflow: visible !important; /* Allow dragging off-screen */
}

/* Re-enable clicks on the videos themselves */
.video-container > * {
    pointer-events: auto !important;
}

/* Add a resize handle 
.video-container::after {
    content: '⤡';
    position: absolute;
    bottom: 5px;
    right: 5px;
    font-size: 18px;
    color: white;
    background-color: rgba(0,0,0,0.5);
    width: 24px;
    height: 24px;
    display: flex;
    align-items: center;
    justify-content: center;
    border-radius: 4px;
    cursor: nwse-resize;
    pointer-events: auto;
}*/

.video-wrapper { 
    position: relative;
    border-radius: var(--app-border-radius);
    overflow: visible; /* MUST be visible to show external controls */
    box-shadow: 0 4px 12px rgba(0,0,0,0.5);
    /* REMOVED fixed dimensions to allow JavaScript control */
    /* height: 270px; */
    /* width: 480px; */
    background-color: transparent; /* Transparent so controls aren't covered */
    transition: transform 0.2s ease;
    cursor: grab;
    margin-top: 50px; /* Space above for recording controls */
    margin-bottom: 55px; /* Space below for drawing controls (status is inside controls now) */
}

/* Ensure video stays within wrapper bounds with rounded corners */
.video-wrapper > video {
    position: relative;
    z-index: 1;
    border-radius: var(--app-border-radius);
    overflow: hidden; /* This clips the video to rounded corners */
    width: 100%;
    height: 100%;
    display: block;
    background-color: #222d3e; /* Dark background for video elements */
}

/* Canvas for line drawing - keep it within video bounds */
.video-wrapper > canvas {
    position: absolute;
    top: 0;
    left: 0;
    width: 100%;
    height: 100%;
    max-width: 100%;
    max-height: 100%;
    z-index: 10; /* Below controls but above video */
    pointer-events: none;
    border-radius: var(--app-border-radius);
}

.video-wrapper[data-dragging="true"] {
    cursor: grabbing;
    transform: scale(1.02);
    box-shadow: 0 8px 24px rgba(0,0,0,0.7);
}

.video-wrapper:hover {
    transform: scale(1.02);
}

/* Add a maximize button 
.video-wrapper::before {
    content: '⛶';
    position: absolute;
    top: 8px;
    right: 8px;
    font-size: 18px;
    color: white;
    background-color: rgba(0,0,0,0.5);
    width: 32px;
    height: 32px;
    display: flex;
    align-items: center;
    justify-content: center;
    border-radius: 4px;
    cursor: pointer;
    z-index: 20; *//* Increased z-index */
   /* opacity: 0.8;  More visible by default */
   /* transition: opacity 0.2s ease;
    pointer-events: auto;  Ensure clicks are registered
} */

.video-wrapper:hover::before {
    opacity: 1;
}

/* Add explicit styles for fullscreen and focus buttons */
.fullscreen-button, .focus-button {
    position: absolute;
    background-color: rgba(0, 0, 0, 0.6);
    color: white;
    border: none;
    width: 40px;
    height: 40px;
    border-radius: 50%;
    display: flex;
    align-items: center;
    justify-content: center;
    cursor: pointer;
    font-size: 18px;
    z-index: 30; /* Very high z-index to ensure visibility */
    transition: all 0.2s ease;
    box-shadow: 0 2px 8px rgba(0, 0, 0, 0.3);
}

/* Hide the focus button for now 
.focus-button {
    display: none !important;
}

.fullscreen-button {
    bottom: 15px;
    right: 15px;
}*/

/* Fullscreen button - back inside video at top-right corner */
.fullscreen-button {
    position: absolute;
    top: 8px;
    right: 8px;
    background-color: rgba(10, 132, 255, 0.9);
    color: white;
    border: 2px solid rgba(255, 255, 255, 0.3);
    width: 32px;
    height: 32px;
    border-radius: 6px;
    display: flex;
    align-items: center;
    justify-content: center;
    cursor: pointer;
    font-size: 16px;
    z-index: 30; /* Above video but below external controls */
    transition: all 0.2s ease;
    box-shadow: 0 2px 8px rgba(0, 0, 0, 0.5);
}

.fullscreen-button:hover {
    background-color: rgba(10, 132, 255, 1);
    transform: scale(1.1);
    box-shadow: 0 3px 10px rgba(10, 132, 255, 0.6);
}

.fullscreen-button:active {
    transform: scale(1.05);
    box-shadow: 0 1px 4px rgba(0, 0, 0, 0.6);
}

/* Picture-in-Picture button - positioned below fullscreen button */
.pip-button {
    position: absolute;
    top: 48px; /* Below fullscreen button (8px + 32px + 8px spacing) */
    right: 8px;
    background-color: rgba(138, 43, 226, 0.9); /* Purple to distinguish from fullscreen */
    color: white;
    border: 2px solid rgba(255, 255, 255, 0.3);
    width: 32px;
    height: 32px;
    border-radius: 6px;
    display: flex;
    align-items: center;
    justify-content: center;
    cursor: pointer;
    font-size: 14px;
    z-index: 30;
    transition: all 0.2s ease;
    box-shadow: 0 2px 8px rgba(0, 0, 0, 0.5);
}

.pip-button:hover {
    background-color: rgba(138, 43, 226, 1);
    transform: scale(1.1);
    box-shadow: 0 3px 10px rgba(138, 43, 226, 0.6);
}

.pip-button:active {
    transform: scale(1.05);
    box-shadow: 0 1px 4px rgba(0, 0, 0, 0.6);
}

/* Video control buttons container at bottom - prevents overlap */
.video-controls-bottom {
    position: absolute;
    bottom: -42px;
    left: 0;
    right: 0;
    display: flex;
    gap: 8px;
    justify-content: flex-end;
    align-items: center;
    z-index: 300;
    pointer-events: none; /* Allow clicks to pass through container */
}

.video-controls-bottom > * {
    pointer-events: auto; /* Re-enable clicks on buttons */
}

/* Focus button - in bottom control bar */
.focus-button {
    background: linear-gradient(180deg, #4a90e2 0%, #357abd 100%);
    color: white;
    border: 2px solid rgba(255, 255, 255, 0.3);
    border-radius: 8px;
    padding: 6px 12px;
    font-weight: 600;
    font-size: 13px;
    cursor: pointer;
    transition: all 0.2s;
    box-shadow: 0 2px 4px rgba(0, 0, 0, 0.3);
    white-space: nowrap;
    display: inline-block !important;
    opacity: 1 !important;
    z-index: 300 !important;
    min-width: 85px;
    text-align: center;
}

.focus-button:hover {
    background: linear-gradient(180deg, #5aa0f2 0%, #458acd 100%);
    box-shadow: 0 3px 6px rgba(10, 132, 255, 0.5);
}

.focus-button:active {
    border-style: inset;
    background: linear-gradient(180deg, #006edc 0%, #005ec2 100%);
    transform: translateY(1px);
    box-shadow: inset 0 2px 4px rgba(0,0,0,0.6);
}

.video-wrapper video { 
    width: 100%;
    height: 100%;
    object-fit: contain; /* Show full video without cropping */
    background-color: #222d3e; /* Dark background for video elements */
}

/* Video label - person's name on video */
.video-label {
    position: absolute;
    bottom: 8px;
    left: 8px;
    background-color: rgba(0, 0, 0, 0.7);
    color: white;
    padding: 4px 8px;
    border-radius: 4px;
    font-size: 14px;
    font-weight: 500;
    z-index: 20; /* Above video but below controls */
    pointer-events: none; /* Don't block clicks */
    white-space: nowrap;
}

/* Ensure video controls are visible and accessible */
.video-wrapper video::-webkit-media-controls {
    opacity: 1 !important;
    pointer-events: auto !important;
    visibility: visible !important;
}

/* Ensure controls remain visible in fullscreen mode */
video::-webkit-media-controls-panel,
video::-webkit-media-controls-play-button,
video::-webkit-media-controls-volume-slider-container,
video::-webkit-media-controls-volume-slider,
video::-webkit-media-controls-mute-button,
video::-webkit-media-controls-timeline,
video::-webkit-media-controls-current-time-display,
video::-webkit-media-controls-time-remaining-display,
video::-webkit-media-controls-fullscreen-button {
    display: none !important;
    opacity: 0 !important;
}

/* Special handling for fullscreen mode */
video:fullscreen::-webkit-media-controls,
video:fullscreen::-webkit-media-controls-panel {
    display: flex !important;
    opacity: 1 !important;
    background: rgba(0, 0, 0, 0.2); /* Reduced opacity for less darkening */
    z-index: 2147483647;
    bottom: 0; /* Position at bottom only */
    height: auto; /* Only take needed height */
    width: 100%; /* Full width */
}

/* Ensure videos in fullscreen mode have proper control visibility */
.video-wrapper.fullscreen {
    position: fixed;
    top: 0;
    left: 0;
    width: 100vw;
    height: 100vh;
    z-index: 9999;
    background-color: #000;
    border-radius: 0;
}

/* FULLSCREEN VIDEO RULE — must use !important so it wins over the desktop
 * media-query at the bottom of this file which forces
 *   .video-wrapper video { object-fit: cover !important; }
 * for tile view. Without !important here the desktop cover rule survives
 * into fullscreen mode and crops the remote user's video on either the
 * sides or the top/bottom depending on the camera-vs-screen aspect-ratio
 * mismatch. The user requirement is "no part of the video should ever be
 * cut off in fullscreen" → contain (letterbox/pillarbox to fit). */
.video-wrapper.fullscreen video {
    width: 100% !important;
    height: 100% !important;
    object-fit: contain !important;
    background-color: #000; /* fill any letterbox/pillarbox bars in black */
}

/* Native fullscreen API fallback: when the wrapper is the browser's native
 * fullscreen element, also force contain. Browsers that paint the video
 * directly (rather than the wrapper) hit this via the descendant selector. */
.video-wrapper:fullscreen video,
.video-wrapper:-webkit-full-screen video {
    width: 100% !important;
    height: 100% !important;
    object-fit: contain !important;
    background-color: #000;
}

/* If the <video> itself is the fullscreen target (e.g. via the native
 * media-controls fullscreen button), force contain on it too. */
video:fullscreen,
video:-webkit-full-screen {
    object-fit: contain !important;
    background-color: #000;
}

/* Make sure controls are visible in fullscreen */
.video-wrapper.fullscreen .fullscreen-button,
.video-wrapper.fullscreen .pip-button,
.video-wrapper.fullscreen .focus-button {
    z-index: 10000;
    opacity: 0.8;
    background-color: rgba(0, 0, 0, 0.6);
    box-shadow: 0 2px 10px rgba(0, 0, 0, 0.4);
}

/* Make sure the fullscreen button is also visible */
video:fullscreen::-webkit-media-controls-fullscreen-button {
    display: flex !important;
    opacity: 1 !important;
}

.video-wrapper video::-webkit-media-controls-fullscreen-button {
    display: block !important;
    opacity: 1 !important;
    pointer-events: auto !important;
}

.username-label { /* Kept existing style */
    position: absolute;
    bottom: 10px;
    left: 10px;
    background-color: rgba(0, 0, 0, 0.65);
    color: white;
    padding: 5px 10px;
    border-radius: 12px;
    font-size: 13px;
    font-weight: 500;
    backdrop-filter: blur(5px);
    -webkit-backdrop-filter: blur(5px);
    box-shadow: 0 1px 4px rgba(0, 0, 0, 0.2);
}

/* Drawing Controls - Cassette Player Style at Bottom Border */
.drawing-controls {
    position: absolute;
    bottom: -45px; /* Places it below the video */
    left: 0;
    right: 0;
    display: flex;
    justify-content: center;
    gap: 4px;
    padding: 5px;
    background: rgba(0, 0, 0, 0.9);
    border-radius: 0 0 8px 8px;
    z-index: 100; /* High z-index to stay above video and canvas */
    pointer-events: auto;
    box-shadow: 0 4px 8px rgba(0, 0, 0, 0.6);
    border: 1px solid rgba(255, 255, 255, 0.1);
}

/* Cassette Player Style Buttons for Drawing Controls */
.drawing-control-btn {
    padding: 4px 8px;
    margin: 0;
    font-size: 11px;
    border: 2px outset #5a8ec8;
    border-radius: 4px;
    background: linear-gradient(180deg, #4a90e2 0%, #357abd 100%); /* App blue theme */
    color: #fff;
    cursor: pointer;
    transition: all 0.1s;
    box-shadow: 0 2px 4px rgba(10, 132, 255, 0.4);
    min-width: 50px;
    font-weight: 600;
}

/* Pressed state - like a cassette player button */
.drawing-control-btn:active,
.drawing-control-btn.active {
    border-style: inset;
    background: linear-gradient(180deg, #006edc 0%, #005ec2 100%);
    transform: translateY(1px);
    box-shadow: inset 0 2px 4px rgba(0,0,0,0.6);
}

.drawing-control-btn:hover:not(:disabled) {
    background: linear-gradient(180deg, #5aa0f2 0%, #458acd 100%);
    box-shadow: 0 3px 6px rgba(10, 132, 255, 0.5);
}

/* Color picker container styling */
.color-picker-container {
    position: relative;
    display: inline-block;
}

.chat-wrapper {
    flex-grow: 1;
    display: flex;
    flex-direction: column;
    overflow: hidden; /* This is key to contain the layout */
    background-color: var(--app-card-bg);
    border-radius: var(--app-border-radius);
    padding: 15px;
    box-shadow: 0 4px 12px rgba(0, 0, 0, 0.1);
    width: calc(100% - 30px);
    height: 100%;
}

.messages-container {
    flex: 1; /* This makes it take up all available vertical space */
    overflow-y: auto; /* This gives it its OWN scrollbar */
    background-color: var(--app-card-secondary);
    border-radius: 16px;
    padding: 16px;
    margin-bottom: 16px;
    -webkit-overflow-scrolling: touch; /* Good for mobile */
    min-height: 0; /* Important for flexbox behavior in some browsers */
    color: var(--app-text-primary);
}

.message-input-container {
    flex-shrink: 0;
    display: flex;
    gap: 10px;
}

.message-input-container input[type="text"] {
    flex-grow: 1;
    padding: 10px 15px;
    border-radius: 20px; /* Pill shape */
    border: 1px solid var(--app-card-secondary);
    background-color: var(--app-card-secondary);
    color: var(--app-text-primary);
    font-size: 15px;
}

.message-input-container input[type="text"]::placeholder {
    color: var(--app-text-secondary);
}

.message-input-container button {
    padding: 10px 20px;
    border-radius: 20px; /* Pill shape */
    background-color: var(--app-primary);
    color: white;
    border: none;
    cursor: pointer;
    font-weight: 500;
    transition: background-color 0.2s;
}

.message-input-container button:hover {
    background-color: #007AFF; /* Slightly darker blue */
}

.additional-features {
    display: flex;
    flex-direction: column;
    gap: 15px;
    flex-shrink: 0;
}

.additional-features > div { /* Card styling for .file-transfer-section, .iframe-section, etc. */
    background-color: var(--app-card-bg);
    border-radius: var(--app-border-radius);
    padding: 15px;
    box-shadow: 0 4px 12px rgba(0, 0, 0, 0.1);
}

.additional-features .section-header {
    display: flex;
    justify-content: space-between;
    align-items: center;
    margin-bottom: 10px;
    padding-bottom: 10px;
    border-bottom: 1px solid var(--app-card-secondary);
}

.additional-features .section-header h3 {
    margin: 0;
    color: var(--app-text-primary);
    font-size: 16px;
}

/* Chat actions toolbar styling */
.chat-actions-toolbar {
    flex-shrink: 0; /* Keep toolbar fixed size - don't shrink */
    display: flex;
    flex-wrap: wrap;
    background-color: var(--app-card-bg); /* Match container */
    border-bottom: 1px solid rgba(255, 255, 255, 0.1);
    padding: 8px 12px;
    gap: 8px;
    transition: opacity 0.3s ease, max-height 0.3s ease, padding 0.3s ease;
    position: relative;
}

/* Auto-hide toolbar states */
.chat-actions-toolbar.toolbar-hidden {
    display: none;
}

.chat-actions-toolbar.toolbar-visible {
    display: flex;
}

/* Toolbar hover zone - invisible area at top to trigger toolbar on hover */
.toolbar-hover-zone {
    position: absolute;
    top: 0;
    left: 0;
    right: 0;
    height: 40px;
    z-index: 99;
    pointer-events: auto;
}

/* Desktop: show toolbar on hover over hover zone */
@media (min-width: 769px) {
    .toolbar-hover-zone:hover + .chat-actions-toolbar.toolbar-hidden,
    .chat-actions-toolbar.toolbar-hidden:hover {
        display: flex;
    }
}

/* Show toolbar toggle button */
.toolbar-toggle-btn {
    position: absolute;
    top: 8px;
    right: 8px;
    background: var(--app-card-secondary);
    border: none;
    border-radius: 50%;
    width: 32px;
    height: 32px;
    display: flex;
    align-items: center;
    justify-content: center;
    cursor: pointer;
    z-index: 101;
    color: var(--app-primary);
    font-size: 16px;
    transition: all 0.2s ease;
    opacity: 0;
    pointer-events: none;
}

.toolbar-toggle-btn.visible {
    opacity: 1;
    pointer-events: auto;
}

.toolbar-toggle-btn:hover {
    background: var(--app-primary);
    color: white;
}

.chat-actions-toolbar button {
    background-color: transparent;
    color: var(--app-primary); /* Blue to match layout */
    border: none; /* Remove border/outline */
    border-radius: 6px; /* Sharper corners */
    height: 32px; /* Smaller height */
    font-size: 12px; /* Smaller font */
    font-weight: 500;
    display: flex;
    align-items: center;
    justify-content: center;
    cursor: pointer;
    transition: all 0.2s ease;
    padding: 0 12px;
    white-space: nowrap;
    gap: 6px;
    box-shadow: none; /* Remove shadow */
    outline: none; /* Remove focus outline */
    z-index: 100;
}

.chat-actions-toolbar button span {
    font-size: 12px;
    font-weight: 500;
}

.chat-actions-toolbar button:hover {
    background-color: rgba(10, 132, 255, 0.15);
    color: #fff;
    transform: none; /* Remove scale effect */
}

.chat-actions-toolbar button:disabled {
    display: none;
}

.chat-actions-toolbar button.active {
    background-color: rgba(10, 132, 255, 0.2);
    color: #fff;
}

.chat-actions-toolbar button.inactive {
    background-color: transparent;
    color: var(--app-primary);
    opacity: 0.7;
}

/* Specific styling for destructive actions (Stop) */
.chat-actions-toolbar button#stopVideo,
.chat-actions-toolbar button#stopAudio,
.chat-actions-toolbar button#stopScreenShare {
    color: #ef4444;
}

.chat-actions-toolbar button#stopVideo:hover,
.chat-actions-toolbar button#stopAudio:hover,
.chat-actions-toolbar button#stopScreenShare:hover {
    background-color: rgba(239, 68, 68, 0.1);
    color: #ef4444;
}

/* Timer Dropdown Styling - Match toolbar buttons */
.timer-dropdown-container {
    display: flex;
    align-items: center;
    background-color: transparent;
    border: none;
    border-radius: 6px;
    height: 32px;
    padding: 0 8px;
    gap: 6px;
}

.timer-dropdown-container:hover {
    background-color: rgba(10, 132, 255, 0.15);
}

.timer-icon {
    display: flex;
    align-items: center;
    color: var(--app-primary);
}

.timer-icon svg {
    stroke: currentColor;
    width: 16px;
    height: 16px;
}

.timer-select {
    background: transparent;
    border: none;
    color: var(--app-primary);
    font-size: 12px;
    font-weight: 500;
    height: 100%;
    cursor: pointer;
    outline: none;
}

.timer-select:hover {
    color: #fff;
}

.timer-select option {
    background-color: #1e1e1e;
    color: #fff;
}

/* Message Search Styles */
.message-search-container {
    display: flex;
    align-items: center;
    gap: 8px;
}

/* Search button specific fix - match toolbar button height */
.message-search-container #toggleSearchBtn {
    height: 32px;
    min-height: 32px;
}

.search-input-wrapper {
    display: flex;
    align-items: center;
    gap: 4px;
    background-color: var(--app-card-bg);
    border-radius: 20px;
    padding: 4px 12px;
    border: 1px solid var(--app-border);
}

.search-input-wrapper input {
    background: transparent;
    border: none;
    color: var(--app-text-primary);
    font-size: 14px;
    width: 150px;
    outline: none;
}

.search-input-wrapper input::placeholder {
    color: var(--app-text-secondary);
}

.search-result-count {
    font-size: 12px;
    color: var(--app-text-secondary);
    white-space: nowrap;
    min-width: 50px;
    text-align: center;
}

.search-nav-btn {
    background: transparent !important;
    border: none !important;
    color: var(--app-text-secondary) !important;
    cursor: pointer;
    padding: 2px 6px !important;
    font-size: 12px !important;
    border-radius: 4px !important;
    height: auto !important;
    min-width: auto !important;
}

.search-nav-btn:hover {
    color: var(--app-primary) !important;
    background: rgba(255,255,255,0.1) !important;
    transform: none !important;
}

.search-nav-btn:disabled {
    opacity: 0.3 !important;
    cursor: not-allowed !important;
}

.search-close-btn {
    background: transparent !important;
    border: none !important;
    color: var(--app-text-secondary) !important;
    cursor: pointer;
    padding: 2px 6px !important;
    font-size: 14px !important;
    border-radius: 4px !important;
    height: auto !important;
    min-width: auto !important;
}

.search-close-btn:hover {
    color: var(--app-error) !important;
    background: rgba(255,255,255,0.1) !important;
    transform: none !important;
}

/* Highlight for search matches */
.message.search-highlight,
.file-message.search-highlight {
    background-color: rgba(255, 193, 7, 0.3) !important;
    border-left: 3px solid #ffc107;
    animation: searchPulse 0.5s ease-out;
}

.message.search-current,
.file-message.search-current {
    background-color: rgba(255, 193, 7, 0.5) !important;
    border-left: 3px solid #ff9800;
}

@keyframes searchPulse {
    0% { transform: scale(1.02); }
    100% { transform: scale(1); }
}

/* Modal styling */
.modal {
    position: fixed;
    top: 0;
    left: 0;
    width: 100%;
    height: 100%;
    background-color: rgba(0, 0, 0, 0.75);
    display: none;
    align-items: center;
    justify-content: center;
    z-index: 10000; /* Above videos (9000) */
    backdrop-filter: blur(4px);
    -webkit-backdrop-filter: blur(4px);
}

.modal-content {
    position: relative;
    background-color: var(--app-card-bg);
    border-radius: var(--app-border-radius);
    padding: 25px;
    width: 90%;
    max-width: 600px;
    max-height: 90vh;
    overflow-y: auto;
    box-shadow: 0 10px 30px rgba(0, 0, 0, 0.3);
}

.close-modal {
    position: absolute;
    top: 10px;
    right: 10px;
    background: none;
    border: none;
    font-size: 24px;
    color: var(--app-text-secondary);
    cursor: pointer;
    transition: color 0.2s;
}

.close-modal:hover {
    color: var(--app-text-primary);
}

/* File transfer modal specific */
#fileTransferModal .file-controls {
    display: flex;
    flex-direction: column;
    gap: 10px;
}

/* Iframe modal specific */
#iframeModal .iframe-controls {
    display: flex;
    gap: 10px;
    margin-bottom: 15px;
}

#iframeModal .iframe-config-actions {
    display: flex;
    gap: 10px;
    margin-bottom: 15px;
}

.config-settings {
    display: flex;
    align-items: center;
    gap: 10px;
    margin-top: 10px;
    padding: 10px;
    background: rgba(255, 255, 255, 0.05);
    border-radius: 5px;
    border: 1px solid rgba(100, 149, 237, 0.3);
}

.config-settings label {
    color: #fff;
    font-size: 14px;
    white-space: nowrap;
}

.config-select {
    background: #2c5aa0;
    color: white;
    border: 1px solid #6495ed;
    border-radius: 5px;
    padding: 8px 12px;
    font-size: 14px;
    outline: none;
    cursor: pointer;
}

.config-select:hover {
    background: #3a6bb8;
}

.config-select:focus {
    border-color: #87ceeb;
    box-shadow: 0 0 5px rgba(135, 206, 235, 0.5);
}

/* Settings Modal Styles */
.settings-modal-content {
    max-width: 600px;
    max-height: 80vh;
    overflow-y: auto;
}

.modal-header {
    display: flex;
    justify-content: space-between;
    align-items: center;
    margin-bottom: 20px;
    padding-bottom: 10px;
    border-bottom: 1px solid rgba(100, 149, 237, 0.3);
}

.modal-header h3 {
    margin: 0;
    color: #fff;
}

.close-modal {
    background: none;
    border: none;
    color: #fff;
    font-size: 24px;
    cursor: pointer;
    padding: 0;
    width: 30px;
    height: 30px;
    display: flex;
    align-items: center;
    justify-content: center;
    border-radius: 50%;
    transition: background-color 0.3s ease;
}

.close-modal:hover {
    background-color: rgba(255, 255, 255, 0.1);
}

.settings-sections {
    display: flex;
    flex-direction: column;
    gap: 25px;
}

.settings-section {
    background: rgba(255, 255, 255, 0.05);
    border-radius: 8px;
    padding: 20px;
    border: 1px solid rgba(100, 149, 237, 0.2);
}

.settings-section h4 {
    margin: 0 0 15px 0;
    color: #87ceeb;
    font-size: 16px;
}

.setting-item {
    margin-bottom: 15px;
    display: flex;
    flex-direction: column;
    gap: 8px;
}

.setting-item:last-child {
    margin-bottom: 0;
}

.setting-item label {
    color: #fff;
    font-size: 14px;
    font-weight: 500;
}

.setting-description {
    color: #ccc;
    font-size: 12px;
    margin: 0;
    line-height: 1.4;
}

/* Help Modal Styles */
.help-modal-content {
    max-width: 700px;
    max-height: 80vh;
    overflow-y: auto;
}

.help-sections {
    display: flex;
    flex-direction: column;
    gap: 25px;
}

.help-section {
    background: rgba(255, 255, 255, 0.05);
    border-radius: 8px;
    padding: 20px;
    border: 1px solid rgba(100, 149, 237, 0.2);
}

.help-section h4 {
    margin: 0 0 12px 0;
    color: #87ceeb;
    font-size: 16px;
}

.help-section p {
    color: #fff;
    line-height: 1.5;
    margin: 0 0 12px 0;
}

.help-section ul {
    color: #ccc;
    margin: 0;
    padding-left: 20px;
}

.help-section ul li {
    margin-bottom: 8px;
    line-height: 1.4;
}

.help-section ul li strong {
    color: #87ceeb;
}

#iframeModal .iframe-controls input {
    flex-grow: 1;
}

#iframeModal #iframeContainer {
    position: relative;
    height: 400px;
    border-radius: var(--app-border-radius);
    overflow: hidden;
}

#iframeModal iframe {
    width: 100%;
    height: 100%;
    border: none;
    background-color: white;
}

/* User menu styling */
.user-menu {
    position: relative;
    z-index: 101;
}

.user-menu-button {
    background-color: rgba(26, 35, 48, 0.8);
    color: var(--app-text-primary);
    border: none;
    border-radius: 20px;
    padding: 6px 12px;
    font-size: 14px;
    display: flex;
    align-items: center;
    gap: 6px;
    cursor: pointer;
    box-shadow: 0 2px 5px rgba(0,0,0,0.2);
    transition: all 0.2s ease;
    backdrop-filter: blur(8px);
    -webkit-backdrop-filter: blur(8px);
}

.user-menu-button:hover {
    background-color: rgba(42, 59, 77, 0.9);
    transform: translateY(-1px);
}

.user-menu-button:active {
    transform: translateY(0);
}

.dropdown-arrow {
    font-size: 10px;
    transition: transform 0.2s ease;
}

.user-menu-button.active .dropdown-arrow {
    transform: rotate(180deg);
}

.user-menu-dropdown {
    position: absolute;
    right: 0;
    top: 100%;
    margin-top: 5px;
    background-color: var(--app-card-bg);
    border-radius: var(--app-border-radius);
    box-shadow: 0 3px 10px rgba(0,0,0,0.2);
    padding: 5px 0;
    min-width: 180px;
    z-index: 10000; /* Above videos (9000) */
}

.menu-item {
    padding: 10px 15px;
    display: flex;
    align-items: center;
    gap: 10px;
    cursor: pointer;
    transition: background-color 0.2s ease;
    color: var(--app-text-primary);
}

.menu-item:hover {
    background-color: var(--app-card-secondary);
}

.menu-icon {
    font-size: 16px;
}

/* Chat section */
.chat-header {
    display: flex;
    justify-content: space-between;
    align-items: center;
    margin-bottom: 16px;
    padding-bottom: 12px;
    border-bottom: 1px solid rgba(255, 255, 255, 0.1);
}

.chat-header h3 {
    margin: 0;
    color: var(--app-primary);
    font-size: 18px;
    font-weight: 600;
    letter-spacing: -0.3px;
}

.encryption-badge {
    display: flex;
    align-items: center;
    gap: 5px;
    background-color: #222d3e;
    padding: 5px 10px;
    border-radius: 5px;
}

.badge-icon {
    font-size: 14px;
}

.badge-text {
    font-size: 12px;
}



.message {
    margin-bottom: 16px;
    padding: 12px 16px;
    border-radius: 18px;
    max-width: 80%;
    word-wrap: break-word;
    box-shadow: 0 2px 6px rgba(0, 0, 0, 0.1);
    position: relative;
    animation: messageAppear 0.3s ease-out;
}

@keyframes messageAppear {
    from { opacity: 0; transform: translateY(10px); }
    to { opacity: 1; transform: translateY(0); }
}

.message.local {
    background-color: #0056b3; /* Darker blue instead of bright #0A84FF */
    color: white;
    align-self: flex-end;
    margin-left: auto;
    border-bottom-right-radius: 4px;
}

.message.local::after {
    content: '';
    position: absolute;
    bottom: 0;
    right: -8px;
    width: 16px;
    height: 16px;
    background-color: #0056b3; /* Match the darker bubble color */
    border-bottom-left-radius: 16px;
    z-index: -1;
}

.message.remote {
    background-color: var(--app-card-bg);
    color: var(--app-text-primary);
    align-self: flex-start;
    border-bottom-left-radius: 4px;
}

.message.remote::after {
    content: '';
    position: absolute;
    bottom: 0;
    left: -8px;
    width: 16px;
    height: 16px;
    background-color: var(--app-card-bg);
    border-bottom-right-radius: 16px;
    z-index: -1;
}

.message.system {
    background-color: rgba(58, 74, 93, 0.6);
    color: var(--app-text-primary);
    align-self: center;
    max-width: 90%;
    margin-left: auto;
    margin-right: auto;
    font-style: italic;
    text-align: center;
    border-radius: 16px;
    backdrop-filter: blur(4px);
    -webkit-backdrop-filter: blur(4px);
}

.outgoing {
    background-color: #1e457b;
    color: #e0e0e0;
    margin-left: auto;
}

.incoming {
    background-color: #2a3b4d;
    color: #e0e0e0;
    margin-right: auto;
}

.message-input-container {
    display: flex;
    gap: 12px;
    position: relative;
}

.message-input-container input {
    flex: 1;
    padding: 18px 20px;
    border-radius: 28px;
    border: 2px solid rgba(58, 74, 93, 0.3);
    background-color: var(--app-card-secondary);
    color: var(--app-text-primary);
    font-size: 16px;
    transition: all 0.3s;
    outline: none;
    min-height: 56px;
    touch-action: manipulation;
}

.message-input-container input:focus {
    border-color: var(--app-primary);
    box-shadow: 0 0 0 2px rgba(10, 132, 255, 0.3);
}

.message-input-container button {
    background-color: var(--app-primary);
    color: white;
    border: none;
    width: 56px;
    height: 56px;
    border-radius: 50%;
    cursor: pointer;
    display: flex;
    align-items: center;
    justify-content: center;
    transition: all 0.3s;
    box-shadow: none;
    touch-action: manipulation;
}

.message-input-container button::after {
    content: '↑';
    font-size: 20px;
    transform: rotate(45deg);
}

.message-input-container button:hover {
    background-color: #007AFF;
    transform: translateY(-2px);
    box-shadow: none;
}

.message-input-container button:active {
    transform: translateY(0);
    box-shadow: none;
}

/* File transfer section */
.file-transfer-section {
    flex: 0 0 auto;
    background-color: var(--app-card-bg);
    border-radius: var(--app-border-radius);
    padding: 20px;
    margin-bottom: 20px;
    box-shadow: 0 8px 20px rgba(0, 0, 0, 0.15);
}

.section-header {
    display: flex;
    justify-content: space-between;
    align-items: center;
    margin-bottom: 16px;
    padding-bottom: 12px;
    border-bottom: 1px solid rgba(255, 255, 255, 0.1);
}

.section-header h3 {
    color: var(--app-primary);
    margin: 0;
    font-size: 18px;
    font-weight: 600;
    letter-spacing: -0.3px;
}

.file-controls {
    display: flex;
    gap: 12px;
    margin-bottom: 16px;
    flex-wrap: wrap;
}

.file-controls input[type="file"] {
    flex: 1;
    padding: 12px;
    background-color: var(--app-card-secondary);
    border-radius: 12px;
    border: 1px solid rgba(58, 74, 93, 0.3);
    color: var(--app-text-primary);
    min-width: 200px;
}

.file-controls input[type="file"]::-webkit-file-upload-button {
    background-color: rgba(10, 132, 255, 0.2);
    color: var(--app-primary);
    border: none;
    padding: 8px 14px;
    border-radius: 8px;
    margin-right: 10px;
    cursor: pointer;
    font-weight: 500;
    transition: all 0.2s;
}

.file-controls input[type="file"]::-webkit-file-upload-button:hover {
    background-color: rgba(10, 132, 255, 0.3);
}

.file-controls button {
    background-color: var(--app-primary);
    color: white;
    border: none;
    padding: 12px 18px;
    border-radius: 12px;
    cursor: pointer;
    font-weight: 600;
    transition: all 0.2s;
    box-shadow: 0 4px 10px rgba(10, 132, 255, 0.3);
}

.file-controls button:hover {
    background-color: #007AFF;
    transform: translateY(-2px);
    box-shadow: 0 6px 14px rgba(10, 132, 255, 0.4);
}

/* AI Config Toggle Button */
.ai-config-toggle-btn {
    padding: 4px 8px;
    background: #6b7280;
    color: white;
    border: none;
    border-radius: 4px;
    font-size: 11px;
    cursor: pointer;
    transition: background-color 0.2s;
}

.ai-config-toggle-btn.active {
    background: #ef4444; /* Red to indicate an active/destructive state */
    font-weight: bold;
    box-shadow: 0 0 5px rgba(239, 68, 68, 0.7);
}

.file-controls button:active {
    transform: translateY(0);
    box-shadow: 0 2px 8px rgba(10, 132, 255, 0.3);
}

#fileInfo, #fileInfo {
    margin-bottom: 16px;
    padding: 14px;
    background-color: var(--app-card-secondary);
    border-radius: 12px;
    font-size: 14px;
    line-height: 1.5;
}

#fileProgress {
    height: 12px;
    background-color: var(--app-card-secondary);
    border-radius: 6px;
    overflow: hidden;
    margin-bottom: 16px;
    box-shadow: inset 0 1px 3px rgba(0, 0, 0, 0.2);
}

#fileProgress .progress-bar {
    height: 100%;
    background: linear-gradient(90deg, var(--app-primary), var(--app-secondary));
    width: 0%;
    transition: width 0.3s;
    border-radius: 6px;
    box-shadow: 0 0 8px rgba(10, 132, 255, 0.5);
}

/* Detach section */
.peer-count {
    background-color: #222d3e;
    padding: 5px 10px;
    border-radius: 5px;
    font-size: 14px;
}

#detachButton {
    background-color: #2a3b4d;
    color: #e0e0e0;
    border: none;
    padding: 10px 15px;
    border-radius: 5px;
    cursor: pointer;
    margin-bottom: 10px;
}

#detachButton:hover {
    background-color: #3a4a5d;
}

#detachStatus {
    padding: 10px;
    background-color: #222d3e;
    border-radius: 5px;
    margin-top: 10px;
}

/* Iframe section */
.iframe-section {
    flex: 0 0 auto;
    background-color: var(--app-card-bg);
    border-radius: var(--app-border-radius);
    padding: 20px;
    margin-bottom: 20px;
    box-shadow: 0 8px 20px rgba(0, 0, 0, 0.15);
}

.iframe-controls {
    display: flex;
    gap: 12px;
    margin-bottom: 16px;
}

.iframe-controls input {
    flex: 1;
    padding: 10px;
    border-radius: 5px;
    border: 1px solid #3a4a5d;
    background-color: #222d3e;
    color: #e0e0e0;
}

.iframe-controls button {
    background-color: #4a90e2;
    color: white;
    border: none;
    padding: 10px 15px;
    border-radius: 5px;
    cursor: pointer;
}

#iframeContainer {
    position: relative;
    height: 500px;
    background-color: #222d3e;
    border-radius: 8px;
    overflow: hidden;
}

.iframe-loading {
    position: absolute;
    top: 0;
    left: 0;
    width: 100%;
    height: 100%;
    display: flex;
    justify-content: center;
    align-items: center;
    background-color: #222d3e;
    color: #e0e0e0;
    z-index: 2;
}

#sharedIframe {
    width: 100%;
    height: 100%;
    border: none;
    border-radius: 8px;
}

/* Profile section */
.profile-section {
    background-color: #1a2330;
    border-radius: 10px;
    padding: 20px;
}

.profile-section h3 {
    color: #4a90e2;
    margin-bottom: 20px;
}

.profile-info {
    background-color: #222d3e;
    border-radius: 8px;
    padding: 20px;
}

.profile-item {
    margin-bottom: 15px;
    display: flex;
    align-items: center;
}

.profile-label {
    width: 120px;
    font-weight: 500;
    color: #999;
}

.profile-value {
    color: #e0e0e0;
    flex: 1;
}

.profile-security-status {
    display: flex;
    align-items: center;
    gap: 10px;
}

/* Add any custom styles for the recording UI */
.recording-ui button {
    background-color: #1a2330;
    color: #4a90e2;
    border: 1px solid #4a90e2;
    padding: 8px 15px;
    border-radius: 5px;
    margin-right: 10px;
    cursor: pointer;
    transition: background-color 0.2s;
}

.recording-ui button:hover {
    background-color: #2a3b4d;
}

/* Modal styles */
.modal {
    position: fixed;
    top: 0;
    left: 0;
    width: 100%;
    height: 100%;
    background-color: rgba(0, 0, 0, 0.7);
    display: flex;
    justify-content: center;
    align-items: center;
    /* Modals must outrank the top header bar (`.app-title` is z-index 100
     * and `position: sticky`). 10500 leaves headroom both above the
     * .app-title (100) / .room-header (9999) layer AND below the call
     * fullscreen overlay (100000) so a user-initiated call still beats
     * a stale modal. `!important` is defensive against any later
     * stylesheet (e.g. styles2.css overrides) accidentally lowering
     * this — without it, the user reported the modal's top edge
     * sliding under .app-title on desktop, which made the close-X
     * button unreachable.
     *
     * `isolation: isolate` creates a fresh stacking context so the
     * modal can never be inadvertently re-anchored by an ancestor
     * gaining a `transform`/`filter`/`will-change` (any of those would
     * promote that ancestor to the containing block of `position:
     * fixed` descendants and trap the modal inside its z-index space).
     * Belt-and-suspenders against future regressions. */
    z-index: 10500 !important; /* Above .app-title (100) and room-header (9999) */
    isolation: isolate;
}

/* Hide videos when modal is open - very high specificity */
body .video-container.modal-active,
#videos.modal-active {
    display: none !important;
    visibility: hidden !important;
    opacity: 0 !important;
    pointer-events: none !important;
    z-index: -9999 !important;
}

.modal-content {
    background-color: #1a2330;
    padding: 25px;
    border-radius: 10px;
    width: 90%;
    max-width: 500px;
    box-shadow: 0 5px 15px rgba(0, 0, 0, 0.3);
    color: #e0e0e0;
}

.modal-content h3 {
    margin-top: 0;
    margin-bottom: 20px;
    color: #4a90e2;
}

.modal .input-group {
    margin-bottom: 20px;
}

.modal label {
    display: block;
    margin-bottom: 8px;
    font-weight: 500;
}

.modal input {
    width: 100%;
    padding: 10px;
    border-radius: 5px;
    border: 1px solid #3a4a5d;
    background-color: #222d3e;
    color: #e0e0e0;
    font-size: 16px;
}

.modal-buttons {
    display: flex;
    justify-content: flex-end;
    gap: 15px;
    margin-top: 20px;
}

.modal button.primary-btn {
    background-color: #4a90e2;
    color: white;
    padding: 10px 20px;
    border: none;
    border-radius: 5px;
    cursor: pointer;
    font-weight: 500;
}

.modal button.secondary-btn {
    background-color: #3a4a5d;
    color: white;
    padding: 10px 20px;
    border: none;
    border-radius: 5px;
    cursor: pointer;
}

.security-note {
    font-size: 12px;
    color: #999;
    margin-top: 5px;
    margin-bottom: 0;
}

/* =====================================================================
 * Manage Members modal — row + status dot + icon-only remove button
 * ---------------------------------------------------------------------
 * Why these styles exist
 *   The previous _renderManageMembersList in app.js / app2.js applied
 *   inline styles directly to each created element (`row.style.cssText
 *   = '...'`, `removeBtn.textContent = '🚫 削除'`). That coupled layout
 *   to the JS, gave us no theming hooks (the hard-coded
 *   `rgba(255,255,255,0.08)` border didn't match the v2 cream theme),
 *   and the remove button was a text-and-emoji combo instead of a
 *   compact icon. Centralising the CSS here means:
 *     - v1 (styles.css base) and v2 (styles2.css overrides via CSS
 *       variables) both render the modal correctly without per-build
 *       JS forks.
 *     - The "Connecting…" → "Offline member" fix in JS gets a proper
 *       visual companion: dim status dot for offline, sage-green for
 *       online, plus a clear divider between rows.
 *
 * Class shape (set by _renderManageMembersList):
 *     <div class="manage-members-row is-online | is-offline">
 *         <span class="manage-members-status-dot is-online"></span>
 *         <span class="manage-members-name">Display name</span>
 *         <button class="manage-members-remove-btn"
 *                 aria-label="Remove member" title="Remove member">
 *             <span aria-hidden="true">🗑️</span>
 *         </button>
 *     </div>
 *
 * Theming
 *   All colors come from CSS custom properties so the v2 override layer
 *   in styles2.css can rebrand the row to walnut/cream by changing the
 *   tokens once. Where a property doesn't exist in v1's :root, we
 *   fall back to a reasonable hard-coded value via the CSS var
 *   `var(--name, fallback)` syntax — that keeps the rule self-contained.
 *
 * Accessibility
 *   - The trash glyph carries `aria-hidden="true"` (set in JS) so screen
 *     readers fall through to the button's `aria-label`. Without that,
 *     a screen reader would announce "wastebasket" emoji + the label,
 *     which is noisy.
 *   - Focus-visible ring uses the same blue Apple system uses (#0A84FF
 *     at 60% alpha) for consistency with the rest of the modal.
 *   - Disabled state turns the button into a low-opacity icon tile
 *     instead of removing the visual entirely, so the user still sees
 *     "this row HAD a remove button, it's just running right now".
 * ===================================================================== */
.manage-members-row {
    display: flex;
    align-items: center;
    gap: 10px;
    padding: 10px 4px;
    border-bottom: 1px solid var(--app-border-subtle, rgba(255, 255, 255, 0.08));
    min-height: 44px;             /* iOS HIG min tap target */
}
.manage-members-row:last-child {
    border-bottom: none;
}

.manage-members-empty {
    opacity: 0.7;
    text-align: center;
    padding: 24px 8px;
    margin: 0;
    font-size: 13px;
    color: var(--app-text-secondary, #999);
}

/* Status dot. 8x8 circle with a 2px halo so it reads as a dot at low
   contrast on cream and as a glow on dark. Online = sage-green
   (var(--app-success) on v2; iOS-blue green-tinted on v1's fallback);
   offline = neutral grey. The halo is a box-shadow rather than an
   actual border so the inner colored disc isn't shrunk by 2px on
   each side. */
.manage-members-status-dot {
    flex-shrink: 0;
    width: 8px;
    height: 8px;
    border-radius: 50%;
    background: var(--app-text-secondary, #999);
    opacity: 0.45;
    box-shadow: 0 0 0 2px rgba(0, 0, 0, 0.04);
}
.manage-members-status-dot.is-online {
    background: var(--app-success, #34C759);
    opacity: 1;
    box-shadow: 0 0 0 2px rgba(52, 199, 89, 0.18);
}

/* Display name. flex:1 so it takes the remaining row width; truncates
   with ellipsis when it overflows so a long pubkey-prefix offline
   row doesn't wrap and double the row height. */
.manage-members-name {
    flex: 1;
    min-width: 0;                /* enables ellipsis inside flex */
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
    color: var(--app-text-primary, #fff);
    font-size: 14px;
    line-height: 1.3;
}
.manage-members-row.is-offline .manage-members-name {
    color: var(--app-text-secondary, rgba(255, 255, 255, 0.6));
}

/* Icon-only remove button. 32x32 circle with the trash glyph centered.
   Idle state is a low-opacity destructive tint; hover bumps the alpha
   so the button "lights up" on intent without moving its layout box.
   Active (mousedown) presses the button slightly into the row so the
   click feels physical. Focus-visible adds the system blue ring for
   keyboard navigation. */
.manage-members-remove-btn {
    flex-shrink: 0;
    width: 32px;
    height: 32px;
    border-radius: 50%;
    border: 1px solid rgba(220, 53, 69, 0.25);
    background: rgba(220, 53, 69, 0.08);
    color: #ff6b6b;
    cursor: pointer;
    padding: 0;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    font-size: 15px;
    line-height: 1;
    transition: background 0.15s ease, border-color 0.15s ease,
                transform 0.1s ease, opacity 0.15s ease;
    -webkit-tap-highlight-color: transparent;
}
.manage-members-remove-btn:hover {
    background: rgba(220, 53, 69, 0.18);
    border-color: rgba(220, 53, 69, 0.45);
}
.manage-members-remove-btn:active {
    transform: scale(0.94);
    background: rgba(220, 53, 69, 0.28);
}
.manage-members-remove-btn:focus-visible {
    outline: 2px solid rgba(10, 132, 255, 0.6);
    outline-offset: 2px;
}
.manage-members-remove-btn:disabled,
.manage-members-remove-btn[aria-busy="true"] {
    cursor: progress;
    opacity: 0.55;
    pointer-events: none;       /* block accidental double-clicks */
}
/* Glyph wrapper inside the button — handles the slight optical balance
   shift the trash emoji needs to look centered. The trash 🗑️ codepoint
   includes whitespace baked into its bounding box; -1px nudge brings
   the visible portion to the geometric center of the 32x32 circle. */
.manage-members-remove-btn > span {
    display: inline-block;
    transform: translateY(-1px);
}

/* Create Contact / Create Group mode toggle (rendered at the top of the
   #createRoomModal). Two segmented buttons that swap visibility of the
   group-only fields. Pattern is intentionally light so it visually nests
   inside the modal without competing with .modal-buttons at the bottom. */
.create-mode-toggle {
    display: flex;
    gap: 6px;
    margin: 0 0 14px 0;
    padding: 4px;
    background: rgba(255, 255, 255, 0.04);
    border: 1px solid rgba(255, 255, 255, 0.08);
    border-radius: 8px;
}

.create-mode-btn {
    flex: 1 1 0;
    background: transparent;
    color: var(--app-text-secondary, #b8b8c0);
    border: none;
    border-radius: 6px;
    padding: 8px 12px;
    font-size: 14px;
    font-weight: 500;
    cursor: pointer;
    transition: background 0.15s ease, color 0.15s ease;
}

.create-mode-btn:hover {
    background: rgba(255, 255, 255, 0.06);
    color: var(--app-text-primary, #fff);
}

.create-mode-btn.active {
    background: var(--app-primary, #4a90e2);
    color: #fff;
    box-shadow: 0 1px 2px rgba(0, 0, 0, 0.25);
}

.create-mode-btn.active:hover {
    background: var(--app-primary, #4a90e2);
    color: #fff;
}

/* Room items */
.room-item {
    display: flex;
    justify-content: space-between;
    align-items: center;
    margin-bottom: 12px;
    padding: 16px;
    background-color: var(--app-card-secondary);
    border-radius: 16px;
    cursor: pointer;
    transition: all 0.2s;
    box-shadow: 0 2px 8px rgba(0, 0, 0, 0.1);
    position: relative;
    overflow: hidden;
}

.room-item::after {
    content: '';
    position: absolute;
    right: 15px;
    top: 50%;
    transform: translateY(-50%);
    width: 8px;
    height: 8px;
    border-top: 2px solid var(--app-text-secondary);
    border-right: 2px solid var(--app-text-secondary);
    transform: translateY(-50%) rotate(45deg);
}

.room-item:hover {
    background-color: rgba(53, 75, 99, 0.8);
    transform: translateY(-2px);
    box-shadow: 0 4px 12px rgba(0, 0, 0, 0.15);
}

.room-info {
    display: flex;
    flex-direction: column;
    flex-grow: 1;
    padding-right: 20px;
}

.room-nickname {
    font-weight: 600;
    font-size: 16px;
    margin-bottom: 4px;
    color: var(--app-text-primary);
    letter-spacing: -0.3px;
}

.room-code {
    font-size: 13px;
    color: var(--app-text-secondary);
    font-family: -apple-system, BlinkMacSystemFont, 'SF Mono', monospace;
}

/* CONTACT-LIST PREVIEW SNIPPET (and unread count badge).
 *
 * The DOM nodes are created in `app.js > updateRoomsList`. Two states:
 *
 *   - `.room-preview-snippet`               read state — shows the most
 *                                           recent message in the room's
 *                                           history. Subdued grey so it
 *                                           reads as ambient context, not
 *                                           a notification.
 *
 *   - `.room-preview-snippet.has-pending`   unread state — same row, but
 *                                           in the brand-blue accent so
 *                                           the user can scan unread
 *                                           contacts at a glance. Paired
 *                                           with `.unread-count-badge`
 *                                           on the nickname row.
 *
 * Previously these styles were inline on the elements (cssText); moving
 * them into class rules lets v2 (styles2.css) override them via the
 * cream-grey palette without battling !important inline declarations. */
.room-preview-snippet {
    font-size: 12px;
    color: var(--app-text-secondary);
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
    margin-top: 4px;
}
.room-preview-snippet.has-pending {
    color: #0A84FF;          /* iOS-style blue accent for unread state */
}
.room-preview-snippet strong {
    /* Sender name is implicitly bolder via <strong> but we still want to
       inherit the surrounding color rather than the UA's default black. */
    font-weight: 600;
    color: inherit;
}

.unread-count-badge {
    display: inline-block;
    background: #0A84FF;
    color: white;
    border-radius: 10px;
    padding: 2px 6px;
    margin-left: 8px;
    font-size: 11px;
    font-weight: bold;
    line-height: 1.2;
}

/* Secure room code styles */
.room-code-container {
    display: flex;
    align-items: center;
    gap: 8px;
    margin-top: 4px;
}

.secure-badge {
    color: #30D158;
    font-size: 12px;
    font-weight: 600;
    background-color: rgba(48, 209, 88, 0.1);
    padding: 3px 8px;
    border-radius: 10px;
    display: inline-flex;
    align-items: center;
}

.secure-badge::before {
    content: '🔒';
    font-size: 10px;
    margin-right: 4px;
}

/* =============================================================================
 * CONTACT-LIST TYPE INDICATORS
 * -----------------------------------------------------------------------------
 * Three visual states distinguish contact types at a glance:
 *
 *   • Regular peer         — default styling (no modifier class)
 *   • Off-grid P2P peer    — .room-item-offgrid    (cyan left accent)
 *   • WebRTC API Bridge    — .room-item-bridge     (purple left accent + pill)
 *   • Bridge w/ LLM        — .room-item-bridge.is-llm (magenta pill variant)
 *
 * The accent is drawn as a ::before pseudo-element (4px left edge) rather than
 * border-left so it doesn't disturb the item's existing padding/layout math
 * (the `.room-item` has `position:relative` + `overflow:hidden` which the
 * pseudo-element piggybacks on for clean rounded corners).
 *
 * Off-grid contacts already carry a "📡 " emoji prefix inside the nickname
 * text itself (seeded by OffGridManager); the left accent complements that
 * prefix with a color-coded edge, tying the visual language together.
 *
 * Bridge contacts have no text prefix, so in addition to the accent we append
 * a small "🌉 Bridge" / "🌉 LLM" pill (see `.bridge-badge` below) next to the
 * nickname. The pill uses the same rounded pattern as `.secure-badge` for
 * visual consistency.
 * ============================================================================ */

/* Off-grid P2P peer: cyan left accent. The color #00BCD4 matches the
 * existing "📡 Off-Grid P2P" status indicator used in message status
 * (see app.js status-offgrid-p2p rendering) so the user sees the same
 * signal color both in the contact list and in message metadata. */
.room-item-offgrid::before {
    content: '';
    position: absolute;
    left: 0;
    top: 0;
    bottom: 0;
    width: 4px;
    background: linear-gradient(180deg, #00BCD4 0%, #0097A7 100%);
    border-top-left-radius: 16px;
    border-bottom-left-radius: 16px;
}

/* WebRTC API Bridge (non-LLM): purple accent. Picked for a distinct hue
 * from both the offgrid cyan and the LLM magenta so the three types are
 * unambiguous at a glance. */
.room-item-bridge::before {
    content: '';
    position: absolute;
    left: 0;
    top: 0;
    bottom: 0;
    width: 4px;
    background: linear-gradient(180deg, #A855F7 0%, #7E22CE 100%);
    border-top-left-radius: 16px;
    border-bottom-left-radius: 16px;
}

/* Bridge with LLM endpoint: switch the accent to magenta so the user can
 * tell a chat-capable bridge from a plain HTTP bridge without reading the
 * pill text (important at small sizes / fast scanning). */
.room-item-bridge.is-llm::before {
    background: linear-gradient(180deg, #EC4899 0%, #BE185D 100%);
}

/* Hover tints: subtly match the accent color so the whole row "agrees"
 * with its type instead of fighting the default blue hover background. */
.room-item-offgrid:hover {
    background-color: rgba(0, 188, 212, 0.12);
}
.room-item-bridge:hover {
    background-color: rgba(168, 85, 247, 0.12);
}
.room-item-bridge.is-llm:hover {
    background-color: rgba(236, 72, 153, 0.12);
}

/* Generic type-badge pill. Shares the rounded-pill geometry of .secure-badge
 * but sits INLINE with the nickname rather than beneath it, so long names
 * simply wrap with the pill instead of creating a vertical gap. The pill is
 * small (11px) so it doesn't compete with the nickname for attention.
 *
 * Note on flex: the parent `.room-nickname` is a block (not flex) — we rely
 * on `display:inline-flex` here so the pill aligns its emoji + text
 * baselines with each other while still flowing inline with the preceding
 * nickname text node. */
.room-type-badge {
    display: inline-flex;
    align-items: center;
    font-size: 11px;
    font-weight: 600;
    padding: 2px 8px;
    border-radius: 10px;
    margin-left: 6px;
    letter-spacing: 0.2px;
    vertical-align: middle;
    /* Never break inside the pill — keeps the emoji glued to its label. */
    white-space: nowrap;
}

/* Bridge pill (non-LLM): purple to match the left accent. */
.bridge-badge {
    color: #A855F7;
    background-color: rgba(168, 85, 247, 0.15);
    border: 1px solid rgba(168, 85, 247, 0.35);
}

/* Bridge pill (LLM variant): magenta to match the LLM accent. */
.bridge-badge.is-llm {
    color: #EC4899;
    background-color: rgba(236, 72, 153, 0.15);
    border: 1px solid rgba(236, 72, 153, 0.35);
}

/* =============================================================================
 * CONTACT-LIST CONNECTION STATUS DOT
 * -----------------------------------------------------------------------------
 * Small status dot prepended to each `.room-item` showing the contact's
 * current reachability:
 *
 *   • p2p-direct      green, solid          — direct WebRTC, no relay
 *   • p2p-turn        amber, solid          — WebRTC via TURN relay
 *   • p2p-connecting  blue, slow pulse      — handshaking, not yet open
 *   • relay-only      orange, slow pulse    — server relay only (peer offline / not reachable)
 *   • offgrid         cyan, solid           — off-grid local-network P2P
 *   • offline         grey, no animation    — not connected at all
 *
 * The dot sits at the leading edge of the row (positioned absolutely) so it
 * doesn't disturb the existing avatar/info/buttons flex layout. The padding
 * adjustment on `.room-item` ensures the avatar isn't covered by the dot on
 * narrow viewports. */
.room-item .room-status-dot {
    position: absolute;
    top: 50%;
    left: 6px;
    transform: translateY(-50%);
    width: 8px;
    height: 8px;
    border-radius: 50%;
    background: #999;
    box-shadow: 0 0 0 2px rgba(0, 0, 0, 0.25);
    pointer-events: none;     /* tooltip works on hover; clicks pass through */
    z-index: 2;               /* above the ::before accent line */
    transition: background-color 0.2s, box-shadow 0.2s;
}

/*
 * Palette rationale (updated):
 * The dot now reflects WHETHER THE CONTACT CAN BE REACHED, not the
 * specific transport flavour. Anything reachable — direct P2P, P2P via
 * TURN relay, or server relay — paints GREEN so the contact list looks
 * "alive" whenever the local socket is up. Only a genuinely disconnected
 * state (no socket to the signalling server) goes orange. The tooltip
 * still reveals the nuanced transport for users who want the detail.
 *
 * Previous behaviour tinted server-relay-only as orange-pulsing and true
 * offline as a faint grey, which users read as "everyone is offline" —
 * because in the common case the peer isn't actively in-room yet, so the
 * contact list only ever showed the orange state.
 */
.room-item.connection-p2p-direct .room-status-dot {
    background: #4CAF50;
    box-shadow: 0 0 6px rgba(76, 175, 80, 0.55);
}
.room-item.connection-p2p-turn .room-status-dot {
    /* Still green (reachable) but with an amber glow so the tooltip's
     * "via TURN" detail has a subtle visual cue for advanced users. */
    background: #4CAF50;
    box-shadow: 0 0 6px rgba(255, 152, 0, 0.55);
}
.room-item.connection-p2p-connecting .room-status-dot {
    background: #2196F3;
    animation: room-status-pulse 1.4s infinite ease-in-out;
}
.room-item.connection-relay-only .room-status-dot {
    /* Reachable via server relay — this is the common case when both
     * users are online but haven't opened the shared chat yet. Paint
     * green so the contact list reflects "online" rather than the
     * previous orange-pulsing which looked like a problem state. */
    background: #4CAF50;
    box-shadow: 0 0 6px rgba(76, 175, 80, 0.45);
}
.room-item.connection-offgrid .room-status-dot {
    background: #00BCD4;
    box-shadow: 0 0 6px rgba(0, 188, 212, 0.55);
}
.room-item.connection-offline .room-status-dot {
    /* Local socket down — we're genuinely unable to reach anyone until
     * the signalling connection comes back. Orange + slow pulse is the
     * "attention, reconnect pending" signal the user's eye picks up. */
    background: #FF9800;
    box-shadow: 0 0 6px rgba(255, 152, 0, 0.55);
    animation: room-status-pulse 2s infinite ease-in-out;
}

@keyframes room-status-pulse {
    0%, 100% { opacity: 1;   transform: translateY(-50%) scale(1); }
    50%      { opacity: 0.5; transform: translateY(-50%) scale(0.85); }
}

/* Make space for the status dot at the start of each row. The avatar
 * normally sits flush with the left padding; the dot sits in that 12px
 * gutter we add here. */
.room-item {
    padding-left: 22px;
}

.secure-room-code {
    font-family: -apple-system, BlinkMacSystemFont, 'SF Mono', monospace;
    background: rgba(0, 0, 0, 0.2);
    padding: 3px 6px;
    border-radius: 6px;
    letter-spacing: 0.5px;
}

.code-toggle-btn {
    background-color: rgba(48, 70, 101, 0.8);
    border: none;
    color: #fff;
    padding: 4px 10px;
    border-radius: 10px;
    font-size: 12px;
    cursor: pointer;
    transition: all 0.2s;
    backdrop-filter: blur(4px);
    -webkit-backdrop-filter: blur(4px);
}

.code-toggle-btn:hover {
    background-color: rgba(61, 91, 133, 0.9);
    transform: translateY(-1px);
}

.code-toggle-btn:active {
    transform: translateY(0);
}

.delete-room-btn {
    background-color: var(--app-card-secondary);
    color: var(--app-text-secondary);
    border: none;
    border-radius: 50%;
    width: 30px;
    height: 30px;
    display: flex;
    align-items: center;
    justify-content: center;
    font-size: 20px;
    font-weight: bold;
    cursor: pointer;
    transition: all 0.2s;
    margin-left: 10px;
    flex-shrink: 0;
    z-index: 5;
}

.delete-room-btn:hover {
    background-color: #FF3B30;
    color: white;
}

.regenerate-code-btn {
    background-color: #4a90e2;
    color: white;
    border: none;
    border-radius: 50%;
    width: 30px;
    height: 30px;
    display: flex;
    align-items: center;
    justify-content: center;
    font-size: 16px;
    cursor: pointer;
    transition: all 0.2s;
    margin-left: 10px;
    flex-shrink: 0;
    z-index: 5;
}

.regenerate-code-btn:hover {
    background-color: #357abd;
    transform: scale(1.1);
}

/* Utility Classes */
.hidden {
    display: none !important;
}

/* UI Hidden Mode Styles */
body.ui-hidden .room-header,
body.ui-hidden .chat-wrapper,
body.ui-hidden .room-controls-bar,
body.ui-hidden .additional-features,
body.ui-hidden .message-input-container,
body.ui-hidden .chat-actions-toolbar {
    opacity: 0;
    pointer-events: none;
    transition: opacity 0.3s ease;
    visibility: hidden;
}

/* Hide-UI must also collapse the contact-menu sidebar — without this rule
 * a user inside a contact room who clicks Hide UI keeps seeing the contact
 * list panel even though the chat surface disappeared. display:none rather
 * than visibility:hidden so dual-pane layout reclaims the space. The two
 * #rooms-list-section selectors below (plain + `.hidden` variant) match the
 * specificity of the dual-pane forced-visible rules near line 8313 so the
 * later-cascade wins when both `ui-hidden` and `dual-pane-enabled` are
 * present on <body>. */
body.ui-hidden #rooms-list-section,
body.ui-hidden #rooms-list-section.hidden,
body.ui-hidden #sidebarResizeHandle,
body.ui-hidden .sidebar-resize-handle {
    display: none !important;
}

body.ui-hidden .app-title {
    background-color: transparent;
    backdrop-filter: none;
    -webkit-backdrop-filter: none;
    box-shadow: none;
    padding: 10px;
}

body.ui-hidden .room-body {
    padding: 0;
}

/* File Transfer UI Styles */
.file-sent .file-header {
    background: linear-gradient(135deg, #e8f5e8, #f1f9f1) !important;
}

.file-received .file-header {
    background: linear-gradient(135deg, #e3f2fd, #f0f8ff) !important;
}

.file-action {
    font-size: 12px;
    font-weight: 600;
    padding: 2px 8px;
    border-radius: 12px;
    margin-left: 8px;
    text-transform: uppercase;
    letter-spacing: 0.5px;
}

.file-sent .file-action {
    background: #4CAF50;
    color: white;
}

.file-received .file-action {
    background: #2196F3;
    color: white;
}

/* File Name Text Styling for Completed Transfers */
.file-header .file-name {
    font-weight: 700;
    color: #1a252f !important;
    text-shadow: 0 1px 2px rgba(255, 255, 255, 0.8);
    margin: 0 8px;
}

/* Additional text elements in file headers */
.file-header .file-size {
    font-size: 12px;
    color: #4a5568 !important;
    margin-left: 8px;
}

/* Ensure all text in file headers is readable */
.file-header {
    color: #1a252f !important;
}

.file-header * {
    color: inherit;
}

/* Enhanced File Transfer Progress UI */
.file-progress-message {
    display: flex;
    align-items: center;
    gap: 12px;
    padding: 12px;
    background: linear-gradient(135deg, #f8f9fa, #e9ecef);
    border-radius: 12px;
    border-left: 4px solid #666;
    margin: 8px 0;
}

.file-progress-message.sending {
    border-left-color: #4CAF50;
    background: linear-gradient(135deg, #e8f5e8, #f1f9f1);
}

.file-progress-message.receiving {
    border-left-color: #2196F3;
    background: linear-gradient(135deg, #e3f2fd, #f0f8ff);
}

.file-progress-message .file-icon {
    font-size: 24px;
    min-width: 32px;
    text-align: center;
}

.progress-details {
    flex: 1;
    min-width: 0;
}

.progress-details .file-name {
    font-weight: 700;
    color: #1a252f;
    text-shadow: 0 1px 2px rgba(255, 255, 255, 0.8);
    margin-bottom: 4px;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

.transfer-status {
    display: flex;
    justify-content: space-between;
    align-items: center;
    margin-bottom: 8px;
    font-size: 12px;
}

.transfer-type {
    font-weight: 700;
    text-transform: uppercase;
    letter-spacing: 0.5px;
    text-shadow: 0 1px 2px rgba(255, 255, 255, 0.8);
}

.file-progress-message.sending .transfer-type {
    color: #2e7d32;
}

.file-progress-message.receiving .transfer-type {
    color: #1565c0;
}

.transfer-speed {
    background: rgba(255, 255, 255, 0.95);
    padding: 3px 10px;
    border-radius: 8px;
    font-weight: 700;
    color: #1a252f;
    border: 1px solid rgba(0, 0, 0, 0.2);
    text-shadow: 0 1px 1px rgba(255, 255, 255, 0.8);
}

.progress-bar-container {
    position: relative;
    background: rgba(0, 0, 0, 0.1);
    border-radius: 8px;
    height: 20px;
    overflow: hidden;
}

.progress-bar {
    height: 100%;
    background: linear-gradient(90deg, #666, #888);
    border-radius: 8px;
    transition: width 0.3s ease;
    position: relative;
}

.progress-bar.sending {
    background: linear-gradient(90deg, #4CAF50, #66BB6A);
}

.progress-bar.receiving {
    background: linear-gradient(90deg, #2196F3, #42A5F5);
}

.progress-text {
    position: absolute;
    top: 50%;
    left: 50%;
    transform: translate(-50%, -50%);
    font-size: 11px;
    font-weight: 600;
    color: white;
    text-shadow: 1px 1px 2px rgba(0, 0, 0, 0.5);
    z-index: 1;
}
.file-transfer-progress {
    background: rgba(74, 144, 226, 0.1);
    border: 1px solid rgba(74, 144, 226, 0.3);
    border-radius: 8px;
    padding: 10px;
    margin: 5px 0;
}

.file-progress-message {
    display: flex;
    align-items: center;
    gap: 10px;
}

.file-icon {
    font-size: 24px;
    flex-shrink: 0;
}

.progress-details {
    flex-grow: 1;
}

.file-name {
    font-weight: 600;
    color: var(--app-text-primary);
    margin-bottom: 5px;
}

.progress-bar-container {
    position: relative;
    background-color: rgba(0, 0, 0, 0.2);
    border-radius: 10px;
    height: 20px;
    overflow: hidden;
}

.progress-bar {
    height: 100%;
    background: linear-gradient(90deg, #4a90e2, #357abd);
    border-radius: 10px;
    transition: width 0.3s ease;
}

.progress-text {
    position: absolute;
    top: 50%;
    left: 50%;
    transform: translate(-50%, -50%);
    font-size: 12px;
    font-weight: 600;
    color: white;
    text-shadow: 1px 1px 2px rgba(0, 0, 0, 0.5);
}

.file-message {
    background: rgba(52, 73, 94, 0.1);
    border: 1px solid rgba(52, 73, 94, 0.3);
    border-radius: 8px;
    padding: 12px;
    margin: 5px 0;
}

.file-received {
    display: flex;
    flex-direction: column;
    gap: 10px;
}

.file-header {
    display: flex;
    align-items: center;
    gap: 10px;
    flex-wrap: wrap;
}

.file-name {
    font-weight: 600;
    color: var(--app-text-primary);
    flex-grow: 1;
}

.file-size {
    color: var(--app-text-secondary);
    font-size: 12px;
}

.download-btn {
    background: linear-gradient(135deg, #4a90e2, #357abd);
    color: white;
    text-decoration: none;
    padding: 6px 12px;
    border-radius: 15px;
    font-size: 12px;
    font-weight: 500;
    transition: all 0.3s ease;
}

.download-btn:hover {
    background: linear-gradient(135deg, #357abd, #2a5d8f);
    transform: translateY(-1px);
}

.file-preview {
    display: flex;
    justify-content: center;
    padding: 10px;
    background: rgba(0, 0, 0, 0.05);
    border-radius: 6px;
}

.file-preview img, .file-preview video, .file-preview audio {
    border-radius: 6px;
}

/* Custom Video Controls */
.video-preview {
    position: relative;
}

.preview-video {
    max-width: 400px;
    max-height: 300px;
    width: 100%;
    border-radius: 8px;
    background: #000;
}

/* CRITICAL: Completely disable all native video controls */
.preview-video::-webkit-media-controls {
    display: none !important;
}

.preview-video::-webkit-media-controls-enclosure {
    display: none !important;
}

.preview-video::-webkit-media-controls-panel {
    display: none !important;
}

.preview-video::-webkit-media-controls-play-button {
    display: none !important;
}

.preview-video::-webkit-media-controls-timeline {
    display: none !important;
}

.preview-video::-webkit-media-controls-current-time-display {
    display: none !important;
}

.preview-video::-webkit-media-controls-time-remaining-display {
    display: none !important;
}

.preview-video::-webkit-media-controls-mute-button {
    display: none !important;
}

.preview-video::-webkit-media-controls-volume-slider {
    display: none !important;
}

.preview-video::-webkit-media-controls-fullscreen-button {
    display: none !important;
}

video::-webkit-media-controls-start-playback-button {
    display: none !important;
}

.custom-video-controls {
    display: flex;
    align-items: center;
    gap: 10px;
    padding: 10px;
    background: rgba(0, 0, 0, 0.7);
    border-radius: 0 0 8px 8px;
    margin-top: -4px;
}

.video-play-btn,
.video-fullscreen-btn {
    background: transparent;
    border: none;
    color: white;
    font-size: 18px;
    cursor: pointer;
    padding: 5px;
    transition: transform 0.2s;
}

.video-play-btn:hover,
.video-fullscreen-btn:hover {
    transform: scale(1.2);
}

.video-seek {
    flex: 1;
    height: 5px;
    border-radius: 5px;
    outline: none;
    background: rgba(255, 255, 255, 0.3);
    appearance: none;
    -webkit-appearance: none;
}

.video-seek::-webkit-slider-thumb {
    -webkit-appearance: none;
    width: 15px;
    height: 15px;
    border-radius: 50%;
    background: #4a90e2;
    cursor: pointer;
}

.video-seek::-moz-range-thumb {
    width: 15px;
    height: 15px;
    border-radius: 50%;
    background: #4a90e2;
    cursor: pointer;
    border: none;
}

.video-time {
    color: white;
    font-size: 12px;
    white-space: nowrap;
    font-family: monospace;
}

/* Image Preview with Zoom */
.preview-image {
    max-width: 400px;
    max-height: 300px;
    border-radius: 8px;
    transition: all 0.3s ease;
}

.preview-image:hover {
    opacity: 0.9;
}

.preview-image.preview-fullsize {
    max-width: 90vw;
    max-height: 90vh;
    position: fixed;
    top: 50%;
    left: 50%;
    transform: translate(-50%, -50%);
    z-index: 10000;
    cursor: zoom-out !important;
    box-shadow: 0 0 50px rgba(0, 0, 0, 0.8);
}

/* Text File Preview */
.text-preview {
    max-height: 200px;
    overflow-y: auto;
    background: rgba(0, 0, 0, 0.03);
    border-radius: 6px;
}

.text-preview-content {
    margin: 0;
    padding: 10px;
    font-size: 12px;
    font-family: 'Courier New', monospace;
    white-space: pre-wrap;
    word-wrap: break-word;
    color: var(--app-text-primary);
}

/* Audio Preview */
.preview-audio {
    width: 100%;
    max-width: 400px;
}

/* Time Estimate in Progress */
.time-estimate {
    color: #4CAF50;
    font-weight: 600;
    font-size: 11px;
    margin-left: 8px;
}

.time-estimate-line {
    color: #4CAF50;
    font-weight: 700;
    font-size: 13px;
    margin: 4px 0;
    padding: 4px 8px;
    background: rgba(76, 175, 80, 0.1);
    border-radius: 4px;
    text-align: center;
}

/* File container without borders */
.file-sent-container,
.file-received-container {
    display: flex;
    flex-direction: column;
    gap: 10px;
}

body.ui-hidden .video-container {
    /* Keep original position but expand slightly */
    position: absolute; /* Not fixed - keeps relative positioning */
    top: 10px;
    right: 20px;
    width: 480px; /* Keep original width */
    z-index: 100;
    display: flex;
    flex-direction: column;
    gap: 10px;
    /* No background color change */
}

body.ui-hidden .video-wrapper {
    /* Keep original dimensions */
    width: 480px;
    height: 270px;
    position: relative;
    border-radius: var(--app-border-radius);
    overflow: hidden;
    box-shadow: 0 4px 12px rgba(0,0,0,0.5);
}

body.ui-hidden .video-wrapper video {
    width: 100%;
    height: 100%;
    object-fit: contain;
}

/* Hold-to-open dropdown wrapper around the Hide-UI button.
 *
 * The wrapper has `position: relative` (see .ui-toggle-wrapper below) so
 * the dropdown can be positioned absolutely against it. When ui-hidden is
 * active we move the WRAPPER (not just the button) to the bottom-right
 * corner so the dropdown stays anchored to the visible button — if we left
 * the position-fixed on the button itself, the wrapper would stay in the
 * (now invisible) header and the dropdown would appear miles away from
 * the actual button the user can see. */
body.ui-hidden #toggleUIWrapper {
    position: fixed;
    bottom: 20px;
    right: 20px;
    /* v106 (Jun 2026) — Fix #3C: match the `.ui-toggle-wrapper`
     * z-index (9100) so the floating "Show UI" pill stays above
     * `.video-container` (z-index 9000) and can always be clicked
     * to bring the UI back. The previous 2000 left it buried under
     * the video grid once a call started. */
    z-index: 9100;
}

body.ui-hidden #toggleUI {
    opacity: 0.7;
    transition: opacity 0.3s;
    background-color: rgba(10, 132, 255, 0.7);
}

body.ui-hidden #toggleUI:hover {
    opacity: 1;
}

/* When UI is hidden, the wrapper is pinned to the bottom of the viewport,
 * so a dropdown anchored `top: 100%` would extend off-screen. Flip it to
 * open upward in that mode. */
body.ui-hidden .ui-toggle-dropdown {
    top: auto;
    bottom: calc(100% + 6px);
    margin-top: 0;
}

/* ─── Hide-UI long-press dropdown ──────────────────────────────────────
 * Click the Hide-UI button as normal -> toggles UI (legacy behaviour).
 * Hold the button ~500ms on desktop -> opens this dropdown with extra
 * actions (Hide UI / Hide videos / Organize videos). The long-press JS
 * detector lives in app.js / app2.js (_setupToggleUIInteractions) and
 * is suppressed on coarse-pointer devices, mirroring the rule below.
 */
.ui-toggle-wrapper {
    position: relative;
    display: inline-block;
    /* v106 (Jun 2026) — Fix #3C: lift the Hide UI / Show UI button
     * (and its dropdown) above `.video-container`, which is
     * `position: fixed; z-index: 9000` (see styles.css ~1561) and
     * was painting OVER the toggle. The user could no longer click
     * the button to bring the UI back once videos appeared. Position
     * is already `relative` so z-index takes effect. We pick 9100 —
     * just above the video layer but well below modal overlays
     * (10000+) so dialogs still cover everything. The ui-hidden
     * fixed-position override below also gets bumped to match. */
    z-index: 9100;
}

.ui-toggle-dropdown {
    display: none;
    position: absolute;
    top: calc(100% + 6px);
    right: 0;
    min-width: 180px;
    padding: 4px 0;
    background: rgba(20, 25, 35, 0.96);
    border: 1px solid rgba(255, 255, 255, 0.15);
    border-radius: 10px;
    box-shadow: 0 12px 32px rgba(0, 0, 0, 0.45);
    z-index: 2100;
    overflow: hidden;
    -webkit-backdrop-filter: blur(12px);
    backdrop-filter: blur(12px);
}

.ui-toggle-dropdown.open {
    display: block;
}

.ui-toggle-dropdown-item {
    display: block;
    width: 100%;
    padding: 10px 16px;
    margin: 0;
    background: transparent;
    color: #fff;
    border: none;
    text-align: left;
    cursor: pointer;
    font-size: 14px;
    font-family: inherit;
    line-height: 1.3;
    transition: background 0.15s ease;
}

.ui-toggle-dropdown-item:hover,
.ui-toggle-dropdown-item:focus-visible {
    background: rgba(10, 132, 255, 0.25);
    outline: none;
}

.ui-toggle-dropdown-item + .ui-toggle-dropdown-item {
    border-top: 1px solid rgba(255, 255, 255, 0.06);
}

/* (The previous touch-only rule that hid this dropdown is gone — the
 * button now opens the menu on plain click, which works fine on touch
 * just like on desktop. See _setupToggleUIInteractions in app.js for
 * the history of why long-press was abandoned.) */

/* Mobile header toggle. Hidden on desktop; enabled inside the
   @media (max-width: 768px) block below. Pinned top-RIGHT (kebab icon
   is distinct from the chat toolbar's bar-icon so the two can't be
   confused). z-index must sit above the mobile room-header's opaque
   card background (9999); otherwise the room-header paints over the
   toggle and it disappears the moment the user enters a room. A
   follow-up :has() rule hides the toggle when a modal is open so it
   doesn't steal taps meant for a dialog. */
.mobile-header-toggle {
    display: none; /* hidden on desktop */
    position: fixed;
    top: max(env(safe-area-inset-top, 0px), 8px);
    right: max(env(safe-area-inset-right, 0px), 8px);
    width: 40px;
    height: 40px;
    padding: 0;
    border: 1px solid rgba(255, 255, 255, 0.15);
    border-radius: 10px;
    background: rgba(10, 14, 24, 0.72);
    color: #fff;
    cursor: pointer;
    z-index: 10001; /* above room-header (9999) and modals (10000) */
    align-items: center;
    justify-content: center;
    -webkit-backdrop-filter: blur(10px);
    backdrop-filter: blur(10px);
    box-shadow: 0 4px 12px rgba(0, 0, 0, 0.35);
    transition: background 0.2s ease, transform 0.2s ease;
}

/* Hide the toggle whenever a modal dialog or incoming-call banner is
   actively shown (the app opens them by setting inline style
   display:flex / display:block). Uses :has() which is supported in
   Chrome 105+, Safari 15.4+, Firefox 121+ - older browsers just fall
   back to the toggle staying visible, which is harmless because its
   stacking context keeps it cosmetic next to the modal rather than
   breaking any interaction. Attribute selectors enumerate the few
   inline-style patterns the app uses for opening; [style*="none"] is
   intentionally NOT matched so the default hidden state of every
   modal doesn't hide the toggle. */
body:has(.modal[style*="flex"]) .mobile-header-toggle,
body:has(.modal[style*="block"]) .mobile-header-toggle,
body:has(.incoming-call-modal[style*="flex"]) .mobile-header-toggle,
body:has(.incoming-call-modal[style*="block"]) .mobile-header-toggle {
    display: none !important;
}
.mobile-header-toggle:hover {
    background: rgba(10, 132, 255, 0.55);
}
.mobile-header-toggle:active {
    transform: scale(0.95);
}
/* SVG kebab-menu icon for the mobile header toggle. Sized to fit inside
   the 40x40 button with a bit of breathing room. The SVG uses fill via
   currentColor so it picks up the button's color (white). */
.mobile-header-toggle-icon {
    width: 20px;
    height: 20px;
    display: block;
    transition: transform 0.25s ease;
}
/* When the menu is open (.active class toggled from JS) rotate the
   vertical-dot icon 90 degrees so it becomes horizontal dots - a subtle
   but unambiguous "menu is open" cue. */
.mobile-header-toggle.active .mobile-header-toggle-icon {
    transform: rotate(90deg);
}

/* In-room kebab button (lives inside .room-header as a flex child).
   Hidden by default on every viewport; shown by the @media (max-width:
   768px) rule further down when the user is on a phone. Keeping the
   DOM node always-present means JS wiring doesn't need to probe for
   existence at different lifecycle stages. */
.room-header-menu-toggle {
    display: none;
    align-items: center;
    justify-content: center;
    background: transparent;
    border: 1px solid rgba(255, 255, 255, 0.18);
    border-radius: 10px;
    width: 36px;
    height: 36px;
    padding: 0;
    margin-left: 8px;
    color: #fff;
    cursor: pointer;
    flex-shrink: 0;
    transition: background 0.2s ease, transform 0.2s ease, border-color 0.2s ease;
}
.room-header-menu-toggle:hover {
    background: rgba(10, 132, 255, 0.25);
    border-color: rgba(10, 132, 255, 0.6);
}
.room-header-menu-toggle:active {
    transform: scale(0.95);
}
.room-header-menu-toggle svg {
    display: block;
    transition: transform 0.25s ease;
}
/* Mirror the .active rotation used by the floating toggle so both
   kebabs give the same visual "menu is open" cue. */
.room-header-menu-toggle.active svg {
    transform: rotate(90deg);
}
.room-header-menu-toggle.active {
    background: rgba(10, 132, 255, 0.35);
    border-color: rgba(10, 132, 255, 0.8);
}

/* Hide the floating kebab whenever the user is inside a room view on
   any viewport. We key off the inline display of #room-content because
   showRoomContent sets it to 'block'/'flex' and showRoomsList resets
   it to 'none'. This prevents BOTH kebabs being on-screen at once in
   the room view - the in-header one is the canonical choice there
   because it can't overlap the call button. Desktop isn't affected
   because the floating toggle's base display is already 'none' above. */
body:has(#room-content[style*="display: block"]) .mobile-header-toggle,
body:has(#room-content[style*="display:block"]) .mobile-header-toggle,
body:has(#room-content[style*="display: flex"]) .mobile-header-toggle,
body:has(#room-content[style*="display:flex"]) .mobile-header-toggle {
    display: none !important;
}

/* Mobile-First Responsive Design */
@media (max-width: 768px) {
    /* Mobile layout adjustments */
    .app-title {
        padding: calc(var(--app-status-bar-height) + 16px) 16px 16px 16px;
        min-height: 70px;
        /* Hide by default on mobile - completely collapse the section */
        display: none;
    }
    
    /* Show app-title when toggled */
    .app-title.visible {
        display: flex;
        animation: slideDown 0.3s ease-in-out;
    }
    
    /* Slide down animation when showing */
    @keyframes slideDown {
        from {
            transform: translateY(-20px);
            opacity: 0;
        }
        to {
            transform: translateY(0);
            opacity: 1;
        }
    }
    
    /* Mobile header toggle: the .app-title is hidden by default on mobile
       (`display: none` above). This floating button lets the user reveal
       it on demand without any full-screen overlay blocking gestures. */
    .mobile-header-toggle {
        display: flex !important;
    }

    .app-title h1 {
        font-size: 24px;
    }
    
    .app-title-right {
        gap: 12px;
    }
    
    /* Login section mobile optimizations */
    #login-section {
        margin: 16px;
        padding: 24px;
        border-radius: 20px;
        /* Match the tighter 16px margin (32px combined top+bottom) so the
         * card uses as much vertical space as possible before falling back
         * to an inner scrollbar. Same dvh/vh pattern as the desktop rule. */
        max-height: calc(100vh - 32px);
        max-height: calc(100dvh - 32px);
    }
    
    .input-group input {
        font-size: 16px; /* Prevent zoom on iOS */
        padding: 18px;
        border-radius: 14px;
    }
    
    .input-group button {
        font-size: 16px;
        padding: 18px;
        border-radius: 14px;
    }
    
    /* Hide the desktop-only Hide Video button */
    #toggleVideoVisibilityBtn {
        display: none !important;
    }

    /* Keep the Keep Alive button visible but styled compactly */
    #keepAliveBtn {
        font-size: 11px !important;
        padding: 4px 8px !important;
        max-width: 80px;
    }
    
    /* Mobile Adjustment for the contacts header */
    .contacts-user-header {
        max-width: 60%; /* Prevent it from pushing buttons off screen */
    }
    
    .contacts-user-info h3 {
        white-space: nowrap;
        overflow: hidden;
        text-overflow: ellipsis;
    }
    
    /* Tab bar mobile optimizations */
    .app-tabs {
        padding: 12px 0;
        padding-bottom: calc(12px + var(--app-bottom-bar-height));
    }
    
    .tab-button {
        padding: 16px 12px;
        font-size: 15px;
        min-height: 56px;
    }
    
    /* Room list mobile optimizations */
    .rooms-list-section {
        position: fixed;
        top: 0;
        left: 0;
        right: 0;
        bottom: 60px; /* Account for mobile nav */
        margin: 0;
        padding: 15px 15px 10px 15px; /* Reduced padding */
        border-radius: 0;
        display: flex;
        flex-direction: column;
        overflow: hidden;
        background-color: var(--app-card-bg);
        max-height: calc(100dvh - 60px); /* Ensure it doesn't exceed viewport */
    }
    
    /* Make rooms container fill available space and scroll */
    .rooms-list-section .rooms-container {
        flex: 1;
        max-height: none; /* Remove fixed max-height */
        overflow-y: auto;
        margin-bottom: 10px; /* Reduced margin */
        min-height: 100px; /* Ensure some space for scrolling */
    }
    
    .rooms-header {
        flex-direction: row;
        flex-wrap: wrap;
        gap: 12px;
        align-items: center;
        justify-content: space-between;
        flex-shrink: 0; /* Don't shrink */
        margin-bottom: 15px; /* Reduced from default */
        padding-bottom: 10px; /* Reduced from default */
    }
    
    .create-room-btn {
        min-width: 140px;
        padding: 12px 20px;
        font-size: 15px;
        border-radius: 20px;
    }
    
    /* MOBILE: hide the contacts-tab join-room bar entirely. The same
       functionality (typing an invite code, scanning a QR) is now also
       reachable via the 3rd tab ("Join") inside the Create Contact modal,
       so showing the bar here on phones just eats list real-estate that
       could be used to surface more contacts. Desktop keeps the bar
       (see the un-prefixed `.join-room-section` rules higher up in this
       stylesheet) because there's plenty of room. The child rules below
       are kept (commented intent) so re-enabling on mobile is a one-line
       revert of this `display: none`. */
    .join-room-section {
        display: none;
    }
    
    /* Room item mobile optimizations */
    .room-item {
        padding: 18px 16px;
        border-radius: 16px;
        margin-bottom: 12px;
    }
    
    .room-info {
        padding-right: 40px;
    }
    
    .room-nickname {
        font-size: 17px;
        margin-bottom: 6px;
    }
    
    .room-code {
        font-size: 13px;
    }
    
    /* Mobile room header - compact and visible.
       Padding returned to baseline 8px 12px. The kebab menu is now a
       flex child of this header (.room-header-menu-toggle) instead of
       a floating fixed-position overlay, so we don't need to carve
       out a right-side gutter anymore. */
    .room-header {
        display: flex !important; /* Ensure visible on mobile */
        padding: 8px 12px;
        position: fixed;
        top: 0;
        left: 0;
        right: 0;
        z-index: 9999; /* Above everything except modals */
        background: var(--app-card-bg);
        border-bottom: 1px solid rgba(255, 255, 255, 0.1);
    }

    /* Reveal the in-header kebab on mobile. It takes over from the
       floating #mobileHeaderToggle (which gets hidden via the body:has
       rule above) so the user still has one-tap access to the
       settings/header overlay while inside a room, but without the
       overlap risk on the call button. */
    .room-header-menu-toggle {
        display: inline-flex;
    }
    
    .room-header h3 {
        font-size: 15px !important;
        white-space: nowrap;
        overflow: hidden;
        text-overflow: ellipsis;
        /* Use the parent container's available width (which is now
           shrinkable thanks to min-width: 0 on .room-name-container)
           rather than a fixed 200px cap. On wider mobiles the name
           still has plenty of room; on iPhone-SE-class viewports
           it now shrinks gracefully and ellipsises so the trailing
           kebab is never pushed off the right edge. */
        max-width: 100%;
        min-width: 0;
        flex: 0 1 auto;
    }
    
    .back-button {
        width: 32px !important;
        height: 32px !important;
        font-size: 18px !important;
        margin-right: 8px !important;
    }
    
    .edit-nickname-btn {
        font-size: 12px !important;
        padding: 4px 8px !important;
        margin-left: 6px !important;
    }
    
    .connection-status {
        font-size: 11px;
        white-space: nowrap;
        /* Don't grow into space the trailing call/kebab buttons need;
           shrink before they do if the row overflows. */
        flex: 0 1 auto;
        min-width: 0;
    }
}

/* Very-narrow viewport rules: hide the verbose connection-status
   label ('Server Relay' / 'Connected') so the small status dot is
   the only thing left from .connection-status. Frees roughly 80px
   of horizontal real-estate which on iPhone-SE-class screens (375px
   and below) is exactly what was getting eaten by the kebab being
   pushed off the right edge. The dot itself remains as the visual
   transport indicator, so users still get the at-a-glance status. */
@media (max-width: 480px) {
    .room-header .connection-status .status-text {
        display: none;
    }
}

/* Re-open the existing 768px media-query block since we closed it
   above to insert the 480px rule. The remaining rules below were
   originally inside it. */
@media (max-width: 768px) {
    
    /* Room body mobile adjustments - account for fixed header */
    .room-body {
        flex-direction: column;
        padding: 16px;
        padding-top: 60px; /* Space for fixed header */
        min-height: calc(100vh - 160px); /* Mobile: fill viewport minus header/footer space */
        height: auto; /* Mobile: allow dynamic height growth beyond min-height */
        overflow: visible; /* Mobile: allow content to flow naturally */
    }
    
    /* Video container mobile adjustments - dynamic sizing */
    .video-container {
        position: relative;
        width: 100%;
        margin: 0;
        gap: 16px;
        order: 1;
        min-height: 0; /* No minimum height by default */
       display: none;/*  Hidden by default */
    }
    /*
    .video-container:not(:empty) {
        display: block; /* Only show when videos are present */
       /* margin: 0 0 20px 0;
        min-height: 180px;  Height for single video */
   /* }*/

    /* ADD THIS NEW RULE */
.video-container:has(.video-wrapper) {
	display:block;
    /* These styles apply ONLY if the container has a video inside it */
    margin: 0 0 20px 0;
    min-height: 180px;
}
    
    /* Increase height for multiple videos to accommodate 2x2 grid 
    .video-container:has(.video-wrapper:nth-child(3)),
    .video-container:has(.video-wrapper:nth-child(4)) {*/
    /*    min-height: 350px;  Height for bottom row: 177px + 157px + 16px padding 
    }*/

    /* Increase container heights to accommodate controls above and below */
    .video-container:has(.video-wrapper) {
        min-height: 280px; /* 157px video + 45px top + 55px bottom + margins */
    }
    
    .video-container:has(.video-wrapper:nth-child(3)) {
        min-height: 550px; /* Accommodate two rows with controls */
    }
    
    .video-wrapper {
        position: absolute;
        /* REMOVED fixed dimensions to allow JavaScript control */
        /* width: 280px; */
        /* height: 157px; */
        margin-top: 45px !important; /* Keep space for recording controls */
        margin-bottom: 55px !important; /* Keep space for drawing controls */
        /* REMOVED fixed positioning - JavaScript will handle layout */
        /* top: 10px; */
        /* left: 10px; */
        cursor: grab;
        /* z-index is managed dynamically by JavaScript - removed hardcoded value */
    }
    
    /* DISABLED: nth-child positioning to allow JavaScript control */
    /* .video-wrapper:nth-child(2) {
        top: 10px;
        left: 50%;
        transform: translateX(-50%);
    }
    
    .video-wrapper:nth-child(3) {
        top: 177px;
        left: 10px;
    }
    
    .video-wrapper:nth-child(4) {
        top: 177px;
        left: 50%;
        transform: translateX(-50%);
    } */
    
    .video-wrapper video {
        object-fit: contain; /* Maintain aspect ratio on mobile */
    }
    
    /* Fullscreen button - smaller on mobile, stays inside video */
    .fullscreen-button {
        top: 4px !important;
        right: 4px !important;
        width: 28px !important;
        height: 28px !important;
        font-size: 12px !important;
    }
    
    /* PiP button - smaller on mobile, positioned below fullscreen */
    .pip-button {
        top: 36px !important; /* Below fullscreen button (4px + 28px + 4px spacing) */
        right: 4px !important;
        width: 28px !important;
        height: 28px !important;
        font-size: 11px !important;
    }
    
    /* Bottom controls container on mobile */
    .video-controls-bottom {
        bottom: -45px !important; /* Position below video */
    }
    
    /* Focus button - smaller on mobile */
    .focus-button {
        padding: 4px 8px !important;
        font-size: 11px !important;
        min-width: 70px !important;
        height: auto !important;
    }
    
    /* Video label - smaller on mobile */
    .video-label {
        bottom: 4px !important;
        left: 4px !important;
        font-size: 11px !important;
        padding: 3px 6px !important;
    }
    
    /* Drawing controls adjustments for mobile */
    .drawing-controls {
        bottom: -50px; /* Adjusted for mobile */
        padding: 3px;
        gap: 2px;
    }
    
    /* Drawing control buttons - smaller on mobile */
    .drawing-control-btn {
        padding: 2px 4px !important;
        margin: 0 !important;
        font-size: 9px !important;
        border-radius: 3px !important;
        min-width: 35px !important;
        border-width: 1px !important;
    }
    
    /* Recording controls adjustments for mobile */
    .recording-controls {
        top: -45px; /* Adjusted for mobile */
        padding: 3px;
        gap: 2px;
    }
    
    /* Recording control buttons - smaller on mobile */
    .recording-control-btn, .record-btn, .stop-btn {
        padding: 2px 4px !important;
        margin: 0 !important;
        font-size: 9px !important;
        border-radius: 3px !important;
        min-width: 35px !important;
        border-width: 1px !important;
    }
    
    /* Recording status and timer - smaller on mobile */
    .recording-status, .recording-timer {
        font-size: 8px !important;
        padding: 2px 4px !important;
        min-width: auto !important;
        height: auto !important;
        line-height: 1.1 !important;
        white-space: nowrap !important;
    }
    
    /* Specific buttons that should be even smaller */
    .clear-btn {
        padding: 1px 2px !important;
        font-size: 10px !important; /* Emoji can be slightly larger */
        min-width: 16px !important;
    }
    
    .tracking-toggle-btn {
        padding: 1px 2px !important;
        font-size: 7px !important;
        max-width: 50px !important;
        overflow: hidden !important;
        text-overflow: ellipsis !important;
    }
    
    .mode-3d-btn,
    .mode-btn {
        padding: 1px 2px !important;
        font-size: 7px !important;
        max-width: 35px !important;
        overflow: hidden !important;
        text-overflow: ellipsis !important;
    }
    
    /* REC and STOP buttons - make them extra small */
    .record-btn,
    .stop-btn {
        padding: 1px 2px !important;
        font-size: 7px !important;
        max-width: 25px !important;
        overflow: hidden !important;
        text-overflow: ellipsis !important;
        margin: 1px !important;
    }
    
    /* Recording status and timer text - make much smaller */
    .recording-status{    
        bottom: 50px !important;
        padding: 1px 3px !important;
        margin: 1px !important;
        font-size: 7px !important;
        border-radius: 2px !important;
        line-height: 1.1 !important;
        max-width: 40px !important;
        overflow: hidden !important;
        text-overflow: ellipsis !important;
    }

    .recording-timer {
        padding: 1px 3px !important;
        margin: 1px !important;
        font-size: 7px !important;
        border-radius: 2px !important;
        line-height: 1.1 !important;
        max-width: 40px !important;
        overflow: hidden !important;
        text-overflow: ellipsis !important;
    }
    
    /* Hide native video controls that create vignette overlay on mobile */
    .video-wrapper video::-webkit-media-controls {
        display: none !important;
        opacity: 0 !important;
        visibility: hidden !important;
    }
    
    .video-wrapper video::-webkit-media-controls-panel {
        display: none !important;
        background: transparent !important;
    }
    
    /* Hide all individual video control elements on mobile */
    .video-wrapper video::-webkit-media-controls-play-button,
    .video-wrapper video::-webkit-media-controls-volume-slider-container,
    .video-wrapper video::-webkit-media-controls-volume-slider,
    .video-wrapper video::-webkit-media-controls-mute-button,
    .video-wrapper video::-webkit-media-controls-timeline,
    .video-wrapper video::-webkit-media-controls-current-time-display,
    .video-wrapper video::-webkit-media-controls-time-remaining-display,
    .video-wrapper video::-webkit-media-controls-fullscreen-button {
        display: none !important;
        opacity: 0 !important;
        visibility: hidden !important;
    }
    
    /* Ensure video resize handle remains visible and functional on mobile */
    .video-container::after {
        display: flex !important;
        z-index: 1000 !important;
        pointer-events: auto !important;
        opacity: 0.8 !important;
        width: 32px !important; /* Larger for easier mobile interaction */
        height: 32px !important;
        font-size: 20px !important;
        background-color: rgba(0, 0, 0, 0.7) !important;
        border: 2px solid rgba(255, 255, 255, 0.3) !important;
    }
    
    /* Make resize handle more visible on touch */
    .video-container:hover::after,
    .video-container:active::after {
        opacity: 1 !important;
        background-color: rgba(10, 132, 255, 0.8) !important;
        border-color: rgba(255, 255, 255, 0.6) !important;
        transform: scale(1.1) !important;
    }
    
    /* Chat wrapper mobile optimizations */
    .chat-wrapper {
        margin: 0 0 20px 0;
        padding: 16px;
        border-radius: 16px;
        width: 100%;
        order: 2;
        flex: 1;
    }
    
    .messages-container {
        flex: 1; /* Maintain flexbox behavior on mobile */
        min-height: 0; /* Important for flexbox behavior */
        overflow-y: auto; /* Ensure scroll is maintained on mobile */
        padding: 16px;
        border-radius: 16px;
        -webkit-overflow-scrolling: touch; /* Smooth scrolling on mobile */
    }
    
    .message {
        padding: 14px 16px;
        border-radius: 20px;
        max-width: 85%;
    }
    
    .message-input-container {
        gap: 12px;
    }
    
    .message-input-container input {
        padding: 16px 18px;
        border-radius: 25px;
        font-size: 16px;
    }
    
    .message-input-container button {
        width: 52px;
        height: 52px;
    }
    
    /* Controls mobile optimizations */
    .controls {
        display: grid;
        grid-template-columns: 1fr 1fr;
        gap: 16px;
        padding: 20px;
        margin: 0;
    }
    
    .controls button {
        padding: 16px 12px;
        font-size: 14px;
        min-height: 52px;
        width: 100%;
        border-radius: 12px;
        white-space: nowrap;
        overflow: hidden;
        text-overflow: ellipsis;
    }
    
    /* File transfer mobile optimizations */
    .file-controls {
        flex-direction: column;
        gap: 12px;
    }
    
    .file-controls input[type="file"],
    .file-controls button {
        width: 100%;
        min-height: 48px;
    }
    
    /* Modal mobile optimizations */
    .modal-content {
        margin: 16px;
        padding: 24px;
        border-radius: 20px;
        max-height: 85vh;
    }
    
    /* User menu mobile adjustments */
    .user-menu-button {
        padding: 8px 14px;
        font-size: 15px;
    }
    
    .user-menu-dropdown {
        right: 16px;
        min-width: 200px;
        border-radius: 16px;
    }
    
    .menu-item {
        padding: 16px 20px;
        font-size: 16px;
    }
    
    /* Additional features mobile layout */
    .additional-features {
        margin: 0;
        gap: 20px;
        order: 3;
    }
    
    .additional-features > div {
        padding: 20px;
        border-radius: 16px;
        margin-bottom: 16px;
    }
    
    /* Room controls bar mobile */
    .room-controls-bar {
        position: static;
        background: none;
        padding: 0;
        margin: 20px 0;
        order: 4;
    }
    
    .room-controls-bar .controls {
        background-color: var(--app-card-bg);
        border-radius: 16px;
        margin: 0;
    }
}

/* LLM Message Formatting */
.message-content pre {
    white-space: pre-wrap;
    word-wrap: break-word;
    max-width: 100%;
    font-family: 'SF Mono', Monaco, 'Courier New', monospace;
    background: rgba(0, 0, 0, 0.1);
    padding: 10px;
    border-radius: 6px;
    margin: 5px 0;
    overflow-x: auto;
}

.message-content code {
    font-family: 'SF Mono', Monaco, 'Courier New', monospace;
    font-size: 0.9em;
    background: rgba(0, 0, 0, 0.1);
    padding: 2px 4px;
    border-radius: 3px;
}

.message-content strong {
    font-weight: 600;
    color: #e0e0e0;
}

.message-content em {
    font-style: italic;
}

.message.remote .message-content,
.message.bot-message .message-content {
    white-space: pre-wrap;
    word-break: break-word;
    line-height: 1.5;
}

/* Highlight AI responses */
.message.bot-message {
    background-color: rgba(74, 144, 226, 0.1);
    border-left: 3px solid #4a90e2;
    margin: 5px 0;
    border-radius: 0 8px 8px 0;
}

/* Desktop and large screens - restore original behavior */
@media (min-width: 769px) {
    /* Desktop video container - span full width for grid layout */
    .video-container {
        /* Keep position: absolute so videos float over chat */
        position: absolute !important;
        top: 80px !important;
        left: 20px !important;          /* Start from left edge */
        right: 20px !important;         /* Extend to right edge */
        width: auto !important;         /* Auto-calculate between left and right */
        min-height: 400px !important;
        height: auto !important;
        z-index: 101 !important;
        display: block !important;
        pointer-events: none !important; /* Clicks pass through to chat below */
    }
    
    .video-container > * {
        pointer-events: auto !important; /* But videos themselves are clickable */
    }
    
    /* REMOVED: Redundant rule that was setting min-height: auto */
    /* .video-container:not(:empty) {
        display: block !important;
        margin: 0 !important;
        min-height: auto !important;
    } */
    
    /* Desktop video wrappers - JavaScript controls size and position */
    .video-wrapper {
        position: absolute !important;
        /* Allow JavaScript to fully control dimensions - no hardcoded width/height */
        margin: 0 !important;
        cursor: grab !important;
        /* z-index removed to allow JS sorting */
    }
    
    /* DISABLED: nth-child positioning to allow JavaScript control */
    /* .video-wrapper:nth-child(2):not([data-dragging="true"]) {
        top: 90px;
        right: 30px;
    }
    
    .video-wrapper:nth-child(3):not([data-dragging="true"]) {
        top: 100px;
        right: 40px;
    }
    
    .video-wrapper:nth-child(4):not([data-dragging="true"]) {
        top: 110px;
        right: 50px;
    } */
    
    /* Ensure dragged videos can be positioned anywhere */
    .video-wrapper[data-dragging="true"] {
        position: absolute !important;
        /* z-index removed so the 'bringToFront' counter persists */
    }
    
    .video-wrapper video {
        object-fit: cover !important; /* Desktop uses cover for better display */
    }
    
    /* Restore original room body desktop layout */
    .room-body {
        flex-direction: row !important;
        padding: 5px !important;
        height: calc(100vh - 120px) !important;
        overflow: hidden !important;
    }
    
    /* Restore original chat wrapper desktop layout */
    .chat-wrapper {
        flex-grow: 1 !important;
        width: calc(100% - 30px) !important;
        margin: 0 !important;
        padding: 15px !important;
        order: unset !important;
        border-radius: var(--app-border-radius) !important;
    }
    
    /* Restore desktop controls layout */
    .controls {
        display: flex !important;
        flex-wrap: wrap !important;
        gap: 15px !important;
        padding: 0 !important;
        margin: 0 !important;
        justify-content: flex-start !important;
    }
    
    .controls button {
        padding: 16px 24px !important;
        font-size: 16px !important;
        min-height: 56px !important;
        min-width: 120px !important;
        width: auto !important;
        border-radius: 28px !important;
    }
    
    /* Additional features desktop layout */
    .additional-features {
        margin: 0 !important;
        gap: 15px !important;
        order: unset !important;
    }
    
    .additional-features > div {
        padding: 15px !important;
        border-radius: var(--app-border-radius) !important;
        margin-bottom: 15px !important;
    }
}

/* Large mobile devices and tablets */
/* @media (max-width: 1024px) and (min-width: 769px) {
    .video-container {
        width: 380px !important;
        right: 0px !important;
    }
    
    .video-wrapper {
        width: 380px !important;
        height: 214px !important;
    }
    
    .room-body {
        padding: 12px !important;
    }
   
    .chat-wrapper {
        margin-right: 400px !important;  Make room for floating video 
    }
}*/

/* Configuration initialization error styles */
.config-init-error button {
    background: #4a90e2;
    color: white;
    border: none;
    padding: 10px 20px;
    border-radius: 5px;
    margin-top: 15px;
    cursor: pointer;
    font-size: 16px;
}

.config-init-error button:hover {
    background: #357abd;
}

.config-init-error ul {
    text-align: left;
    margin: 15px 0;
}

/* Argon2 Loading Screen Styles */
.loading-overlay {
    position: fixed;
    top: 0;
    left: 0;
    width: 100%;
    height: 100%;
    background: linear-gradient(135deg, #1a2330, #2a3441);
    display: flex;
    justify-content: center;
    align-items: center;
    z-index: 10001;
    backdrop-filter: blur(10px);
}

.loading-content {
    text-align: center;
    color: white;
    padding: 40px;
    border-radius: 20px;
    background: rgba(26, 35, 48, 0.9);
    border: 1px solid rgba(74, 144, 226, 0.3);
    box-shadow: 0 8px 32px rgba(0, 0, 0, 0.3);
    max-width: 400px;
    width: 90%;
}

.loading-content h2 {
    margin: 20px 0 10px 0;
    font-size: 24px;
    font-weight: 600;
    color: #4a90e2;
}

.loading-content p {
    margin: 10px 0 20px 0;
    color: #b8c5d6;
    font-size: 16px;
}

.loading-details {
    margin-top: 20px;
    padding: 15px;
    background: rgba(0, 0, 0, 0.2);
    border-radius: 10px;
    border-left: 4px solid #4a90e2;
}

.loading-details span {
    color: #ccc;
    font-size: 14px;
    font-style: italic;
}

/* Progress bar (determinate + indeterminate) shown inside the loading
   overlay so slow devices get visible motion and a real percentage
   instead of only a static status line. */
.loading-progress-wrap {
    margin-top: 18px;
    width: 100%;
}

.loading-progress-bar {
    position: relative;
    width: 100%;
    height: 10px;
    background: rgba(255, 255, 255, 0.08);
    border-radius: 6px;
    overflow: hidden;
    border: 1px solid rgba(74, 144, 226, 0.25);
}

.loading-progress-fill {
    height: 100%;
    width: 0%;
    background: linear-gradient(90deg, #4a90e2, #6aa8ed);
    border-radius: 6px;
    transition: width 0.35s ease;
    box-shadow: 0 0 12px rgba(74, 144, 226, 0.55);
}

/* Indeterminate mode: ignore fill width, run a sliding highlight across
   the track so users always see motion even when no percentage is known. */
.loading-progress-bar.indeterminate .loading-progress-fill {
    width: 40%;
    position: absolute;
    left: -40%;
    animation: loading-indeterminate 1.6s ease-in-out infinite;
}

@keyframes loading-indeterminate {
    0%   { left: -40%; }
    100% { left: 100%; }
}

.loading-progress-percent {
    margin-top: 8px;
    font-size: 12px;
    font-weight: 600;
    color: #b8c5d6;
    text-align: right;
    min-height: 16px; /* reserve space so status line doesn't jump */
}

/* Spinner Animation */
.loading-spinner {
    width: 60px;
    height: 60px;
    border: 4px solid rgba(74, 144, 226, 0.3);
    border-top: 4px solid #4a90e2;
    border-radius: 50%;
    animation: spin 1s linear infinite;
    margin: 0 auto 20px auto;
}

@keyframes spin {
    0% { transform: rotate(0deg); }
    100% { transform: rotate(360deg); }
}

/* Mobile responsiveness for loading screen */
@media (max-width: 768px) {
    .loading-content {
        padding: 30px 20px;
        margin: 20px;
    }
    
    .loading-content h2 {
        font-size: 20px;
    }
    
    .loading-spinner {
        width: 50px;
        height: 50px;
    }
}

/* Message username styling */
.message-username {
    font-size: 12px;
    font-weight: 600;
    margin-bottom: 4px;
    opacity: 0.8;
}

.message.local .message-username {
    color: rgba(255, 255, 255, 0.9);
    text-align: left;
}

.message.remote .message-username {
    color: #4a90e2;
}

/* Message body container for content and copy button */
.message-body {
    display: flex;
    align-items: flex-start;
    gap: 8px;
    position: relative;
}

.message-content {
    font-size: 14px;
    font-weight: 400;
    line-height: 1.4;
    margin-bottom: 2px;
    flex: 1;
    /* Enable text selection for message content */
    -webkit-user-select: text;
    -moz-user-select: text;
    -ms-user-select: text;
    user-select: text;
}

/* Copy button styling */
.message-copy-btn {
    background: rgba(255, 255, 255, 0.1);
    border: none;
    border-radius: 4px;
    padding: 4px 6px;
    font-size: 12px;
    cursor: pointer;
    opacity: 0;
    transition: opacity 0.2s ease;
    flex-shrink: 0;
    min-width: 24px;
    height: 24px;
    display: flex;
    align-items: center;
    justify-content: center;
}

.message:hover .message-copy-btn {
    opacity: 0.7;
}

.message-copy-btn:hover {
    opacity: 1 !important;
    background: rgba(255, 255, 255, 0.2);
    transform: scale(1.1);
}

/* Drag and drop styling */
.drag-over {
    background-color: rgba(10, 132, 255, 0.1) !important;
    border: 2px dashed var(--app-primary) !important;
    border-radius: 16px !important;
}

.drag-over::before {
    content: 'Drop files here to send';
    position: absolute;
    top: 50%;
    left: 50%;
    transform: translate(-50%, -50%);
    background: rgba(10, 132, 255, 0.9);
    color: white;
    padding: 12px 24px;
    border-radius: 8px;
    font-weight: 600;
    pointer-events: none;
    z-index: 1000;
}

/* Message status and metadata styles */
.message-meta {
    display: flex;
    align-items: center;
    gap: 4px;
    margin-top: 2px;
    font-size: 9px;
    color: inherit; /* Use parent color */
}

.message.local .message-meta {
    color: rgba(255, 255, 255, 0.9); /* White text for local messages */
    text-align: right;
}

.message.remote .message-meta {
    color: rgba(255, 255, 255, 0.7); /* Slightly dimmed for remote */
}

.message-timestamp {
    color: inherit;
}

.message-status {
    color: inherit;
    font-weight: 500;
}

.message-status.status-pending {
    color: #FFA500 !important;
}

.message-status.status-delivered {
    color: #4CAF50 !important;
}

.message-status.status-failed {
    color: #FF3B30 !important;
}

.message-received-time {
    color: inherit;
}

.resend-btn {
    background-color: #FF3B30;
    color: white;
    border: none;
    padding: 4px 8px;
    border-radius: 12px;
    font-size: 11px;
    cursor: pointer;
    margin-left: 8px;
    transition: all 0.2s;
}

.resend-btn:hover {
    background-color: #E03024;
    transform: scale(1.05);
}

.resend-btn:active {
    transform: scale(0.95);
}

/* Image selection dropdown */
.image-dropdown {
    position: absolute;
    bottom: 60px;
    left: 0;
    right: 0;
    background: #1a2332;
    border: 1px solid #3b82f6;
    border-radius: 8px;
    max-height: 300px;
    overflow-y: auto;
    z-index: 10000; /* Above videos (9000) */
    box-shadow: 0 4px 12px rgba(0, 0, 0, 0.3);
}

.dropdown-header {
    padding: 10px 15px;
    background: #3b82f6;
    color: white;
    font-weight: bold;
    font-size: 14px;
}

.image-options {
    max-height: 200px;
    overflow-y: auto;
}

.image-option {
    display: flex;
    align-items: center;
    padding: 10px 15px;
    border-bottom: 1px solid #374151;
    cursor: pointer;
    transition: background-color 0.2s;
}

.image-option:hover {
    background-color: #374151;
}

.image-option.selected {
    background-color: #3b82f6;
}

.image-option img {
    width: 40px;
    height: 40px;
    object-fit: cover;
    border-radius: 4px;
    margin-right: 10px;
}

.image-option-info {
    flex: 1;
    color: #d1d5db;
}

.image-option-name {
    font-size: 13px;
    font-weight: bold;
}

.image-option-meta {
    font-size: 11px;
    color: #9ca3af;
}

.dropdown-actions {
    display: flex;
    gap: 10px;
    padding: 10px 15px;
    background: #2d3748;
}

.dropdown-actions button {
    flex: 1;
    padding: 8px 16px;
    border: none;
    border-radius: 4px;
    cursor: pointer;
    font-size: 13px;
}

#confirm-image-selection {
    background: #10b981;
    color: white;
}

#cancel-image-selection {
    background: #6b7280;
    color: white;
}

.message-input-container {
    position: relative !important;
    display: flex;
    flex-direction: column;
    width: 100%;
}

/* Device selection modal specific styles */
#deviceSelectionModal .modal-content {
    max-width: 500px;
}

/* Styled dropdowns matching app theme */
#videoDeviceSelect,
#audioDeviceSelect,
#resolutionSelect {
    font-size: 14px;
    color: var(--app-text-primary);
    background-color: var(--app-card-secondary);
    border: 1px solid rgba(142, 142, 147, 0.3);
    border-radius: 8px;
    padding: 12px 16px;
    width: 100%;
    cursor: pointer;
    transition: all 0.2s ease;
    appearance: none;
    -webkit-appearance: none;
    -moz-appearance: none;
    background-image: url("data:image/svg+xml;charset=UTF-8,%3csvg xmlns='http://www.w3.org/2000/svg' width='12' height='12' viewBox='0 0 12 12'%3e%3cpath fill='%230A84FF' d='M6 9L1 4h10z'/%3e%3c/svg%3e");
    background-repeat: no-repeat;
    background-position: right 12px center;
    background-size: 12px;
    padding-right: 36px;
}

#videoDeviceSelect:hover,
#audioDeviceSelect:hover,
#resolutionSelect:hover {
    border-color: rgba(10, 132, 255, 0.5);
    background-color: rgba(44, 44, 46, 0.8);
}

#videoDeviceSelect:focus,
#audioDeviceSelect:focus,
#resolutionSelect:focus {
    outline: none;
    border-color: var(--app-primary);
    box-shadow: 0 0 0 3px rgba(10, 132, 255, 0.2);
    background-color: var(--app-card-secondary);
}

/* Style the dropdown options */
#videoDeviceSelect option,
#audioDeviceSelect option,
#resolutionSelect option {
    background-color: var(--app-card-bg);
    color: var(--app-text-primary);
    padding: 10px;
}

/* Style the labels */
#videoDeviceSection label,
#audioDeviceSection label,
#resolutionSection label {
    color: var(--app-text-secondary);
    font-size: 13px;
    font-weight: 600;
    text-transform: uppercase;
    letter-spacing: 0.5px;
}

/* Resolution indicator overlay */
.resolution-indicator {
    position: absolute;
    top: 8px;
    right: 8px;
    background-color: rgba(0, 0, 0, 0.8);
    color: #0A84FF;
    padding: 4px 10px;
    border-radius: 4px;
    font-size: 11px;
    font-weight: 600;
    font-family: 'SF Mono', 'Courier New', monospace;
    z-index: 25;
    pointer-events: none;
    border: 1px solid rgba(10, 132, 255, 0.3);
    box-shadow: 0 2px 6px rgba(0, 0, 0, 0.4);
}


/* === Multiline message input & formatting tweaks (added) === */
.message-input-container textarea {
    flex: 1;
    padding: 18px 20px;
    border-radius: 28px;
    border: 2px solid rgba(58, 74, 93, 0.3);
    background-color: var(--app-card-secondary);
    color: var(--app-text-primary);
    font-size: 16px;
    transition: all 0.3s;
    outline: none;
    min-height: 56px;
    max-height: 200px;
    line-height: 1.4;
    resize: vertical;
    overflow-y: auto;
    touch-action: manipulation;
}

.message-input-container textarea:focus {
    border-color: var(--app-primary);
    box-shadow: 0 0 0 2px rgba(10, 132, 255, 0.3);
}

.message-input-container textarea::placeholder {
    color: var(--app-text-secondary);
}

/* Preserve line breaks for locally sent messages too */
.message.local .message-content {
    white-space: pre-wrap;
    word-break: break-word;
    line-height: 1.5;
}

/* ========== EMOJI PICKER STYLES ========== */
#emojiPickerModal .modal-content {
    overflow-y: visible; /* Disable outer scrollbar for emoji picker */
}

.emoji-picker-content {
    max-width: 450px;
    max-height: 85vh;
    display: flex;
    flex-direction: column;
}

.emoji-search-input {
    width: calc(100% - 24px);
    margin: 12px 12px 0 12px;
    padding: 10px 16px;
    background: rgba(255, 255, 255, 0.05);
    border: 2px solid rgba(10, 132, 255, 0.3);
    border-radius: 8px;
    color: var(--app-text-primary);
    font-size: 14px;
    outline: none;
    transition: all 0.2s ease;
}

.emoji-search-input:focus {
    border-color: var(--app-primary);
    background: rgba(255, 255, 255, 0.08);
}

.emoji-search-input::placeholder {
    color: rgba(255, 255, 255, 0.4);
}

.emoji-categories {
    display: flex;
    gap: 8px;
    padding: 12px;
    border-bottom: 1px solid rgba(255, 255, 255, 0.1);
    overflow-x: auto;
}

.emoji-category-btn {
    background: transparent;
    border: 2px solid transparent;
    border-radius: 8px;
    padding: 8px 12px;
    font-size: 24px;
    cursor: pointer;
    transition: all 0.2s ease;
    min-width: 48px;
    height: 48px;
}

.emoji-category-btn:hover {
    background: rgba(10, 132, 255, 0.1);
}

.emoji-category-btn.active {
    border-color: var(--app-primary);
    background: rgba(10, 132, 255, 0.2);
}

.emoji-grid {
    display: grid;
    grid-template-columns: repeat(8, 1fr);
    gap: 8px;
    padding: 16px;
    flex: 1;
    min-height: 0; /* Important for flex children with overflow */
    overflow-y: auto;
}

/* Custom scrollbar for emoji picker */
.emoji-grid::-webkit-scrollbar {
    width: 10px;
}

.emoji-grid::-webkit-scrollbar-track {
    background: rgba(255, 255, 255, 0.05);
    border-radius: 5px;
}

.emoji-grid::-webkit-scrollbar-thumb {
    background: rgba(10, 132, 255, 0.4);
    border-radius: 5px;
}

.emoji-grid::-webkit-scrollbar-thumb:hover {
    background: rgba(10, 132, 255, 0.6);
}

/* Firefox scrollbar */
.emoji-grid {
    scrollbar-width: thin;
    scrollbar-color: rgba(10, 132, 255, 0.4) rgba(255, 255, 255, 0.05);
}

.emoji-item {
    background: transparent;
    border: none;
    border-radius: 8px;
    padding: 8px;
    font-size: 28px;
    cursor: pointer;
    transition: all 0.2s ease;
    display: flex;
    align-items: center;
    justify-content: center;
    min-width: 44px;
    min-height: 44px;
}

.emoji-item:hover {
    background: rgba(10, 132, 255, 0.2);
    transform: scale(1.2);
}

/* ========== MESSAGE INPUT ROW ========== */
.input-row {
    display: flex;
    gap: 8px;
    align-items: flex-end;
    width: 100%;
}

.input-row #messageInput {
    flex: 1;
    min-width: 0;
}

.emoji-btn {
    background: rgba(10, 132, 255, 0.1);
    border: none;
    border-radius: 50%;
    padding: 12px;
    font-size: 20px;
    cursor: pointer;
    transition: all 0.2s ease;
    min-width: 48px;
    min-height: 48px;
    display: flex;
    align-items: center;
    justify-content: center;
    flex-shrink: 0;
    box-shadow: none;
}

.emoji-btn:hover {
    background: rgba(10, 132, 255, 0.2);
    transform: scale(1.1);
    box-shadow: none;
}

/* ========== ATTACH BUTTONS (voice / image) ==========
 * Sit between the emoji button and the message textarea. Visually paired with
 * the emoji button (same circular shape + size) so the composer reads as
 * "emoji • voice • image • [text input] • send" left-to-right. They're
 * always visible (per UX request) regardless of P2P state — the underlying
 * chat-message transport layer routes via P2P or relay as available. */
.attach-btn {
    background: rgba(10, 132, 255, 0.1);
    border: none;
    border-radius: 50%;
    padding: 12px;
    font-size: 18px;
    cursor: pointer;
    transition: all 0.2s ease;
    min-width: 48px;
    min-height: 48px;
    display: flex;
    align-items: center;
    justify-content: center;
    flex-shrink: 0;
    box-shadow: none;
    line-height: 1;
}

.attach-btn:hover {
    background: rgba(10, 132, 255, 0.2);
    transform: scale(1.1);
}

.attach-voice-btn:hover {
    background: rgba(255, 87, 87, 0.18);
}

.attach-image-btn:hover {
    background: rgba(122, 229, 163, 0.18);
}

.attach-btn:disabled {
    opacity: 0.5;
    cursor: not-allowed;
    transform: none;
}

/* ========== VOICE RECORDER MODAL ========== */
.voice-record-modal {
    max-width: 420px;
}

.voice-record-help {
    font-size: 13px;
    color: var(--app-text-secondary);
    margin: 0 0 16px;
    line-height: 1.45;
}

.voice-record-stage > div {
    text-align: center;
}

.voice-record-big-btn,
.voice-record-stop-btn {
    font-size: 16px;
    padding: 14px 28px;
    display: inline-flex;
    align-items: center;
    gap: 10px;
}

.voice-record-icon {
    color: #ff5757;
    font-size: 14px;
    line-height: 1;
}

.voice-record-stop-btn .voice-record-icon {
    color: #fff;
}

.voice-record-stop-btn {
    background: #ff5757;
}

.voice-record-stop-btn:hover {
    background: #e94545;
}

.voice-record-timer {
    font: 600 28px/1 system-ui, -apple-system, sans-serif;
    font-variant-numeric: tabular-nums;
    color: var(--app-text-primary);
    margin-bottom: 12px;
}

.voice-record-quality-label {
    display: flex;
    justify-content: space-between;
    align-items: baseline;
    font-size: 12px;
    font-weight: 600;
    color: var(--app-text-secondary);
    margin: 4px 0 4px;
    letter-spacing: 0.02em;
    text-transform: uppercase;
}

.voice-record-quality-label #voiceQualityValue {
    font-variant-numeric: tabular-nums;
    font-weight: 700;
    color: var(--app-text-primary);
    text-transform: none;
}

.voice-record-segments {
    font-size: 12px;
    color: var(--app-text-secondary);
    margin: 8px 0 14px;
    text-align: center;
}

.voice-record-segments #voiceSegmentCount {
    font-weight: 700;
    color: var(--app-text-primary);
}

.voice-record-meter {
    width: 100%;
    height: 8px;
    background: rgba(255, 255, 255, 0.08);
    border-radius: 4px;
    overflow: hidden;
    margin-bottom: 18px;
}

.voice-record-meter-fill {
    height: 100%;
    width: 0%;
    background: linear-gradient(90deg, #4CAF50, #ff9800 70%, #ff5757);
    transition: width 0.1s linear;
}

.voice-record-preview audio {
    width: 100%;
    margin-bottom: 12px;
}

.voice-record-meta {
    font-size: 12px;
    color: var(--app-text-secondary);
    margin-bottom: 14px;
}

.voice-record-actions,
.image-attach-actions {
    display: flex;
    gap: 10px;
    justify-content: center;
}

.voice-record-error-msg {
    color: #ff7b7b;
    margin: 8px 0 16px;
    font-size: 14px;
}

/* ========== IMAGE ATTACH MODAL ========== */
.image-attach-modal {
    max-width: 460px;
}

.image-attach-help {
    font-size: 13px;
    color: var(--app-text-secondary);
    margin: 0 0 16px;
    line-height: 1.45;
}

.image-attach-preview-wrap {
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: 8px;
    margin-bottom: 16px;
}

#imageAttachPreview {
    max-width: 100%;
    max-height: 50vh;
    border-radius: 8px;
    background: rgba(0, 0, 0, 0.2);
    object-fit: contain;
}

.image-attach-meta {
    font-size: 12px;
    color: var(--app-text-secondary);
    text-align: center;
}

/* Inline message attachments (audio + image) embedded in chat bubbles. */
.message .message-attachment-audio {
    display: block;
    width: 220px;
    max-width: 100%;
    margin-top: 6px;
}

.message .message-attachment-image {
    display: block;
    max-width: 280px;
    max-height: 320px;
    border-radius: 8px;
    margin-top: 6px;
    cursor: zoom-in;
    background: rgba(0, 0, 0, 0.2);
}

.message .message-attachment-meta {
    display: block;
    font-size: 11px;
    color: var(--app-text-secondary);
    margin-top: 4px;
    opacity: 0.8;
}

.secondary-btn {
    background: rgba(255, 255, 255, 0.1);
    color: var(--app-text-primary);
    border: 1px solid rgba(255, 255, 255, 0.2);
    border-radius: 10px;
    padding: 10px 18px;
    cursor: pointer;
    font-weight: 600;
    transition: background 0.15s, border-color 0.15s;
}

.secondary-btn:hover {
    background: rgba(255, 255, 255, 0.18);
    border-color: rgba(255, 255, 255, 0.32);
}

/* ========== REPLY PREVIEW ========== */
.reply-preview {
    background: rgba(10, 132, 255, 0.1);
    border-left: 4px solid var(--app-primary);
    border-radius: 8px;
    padding: 12px;
    margin-bottom: 12px;
}

.reply-preview-header {
    display: flex;
    justify-content: space-between;
    align-items: center;
    margin-bottom: 6px;
}

.reply-preview-label {
    font-size: 12px;
    color: var(--app-text-secondary);
}

.reply-preview-label strong {
    color: var(--app-primary);
}

.cancel-reply-btn {
    background: transparent;
    border: none;
    color: var(--app-text-secondary);
    font-size: 24px;
    cursor: pointer;
    padding: 0;
    width: 24px;
    height: 24px;
    display: flex;
    align-items: center;
    justify-content: center;
    transition: all 0.2s ease;
}

.cancel-reply-btn:hover {
    color: #FF3B30;
    transform: scale(1.2);
}

.reply-preview-message {
    font-size: 13px;
    color: var(--app-text-primary);
    opacity: 0.8;
    max-width: 100%;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

/* ========== MESSAGE ACTIONS (REACTION & REPLY BUTTONS) ========== */
.message-actions {
    display: flex;
    gap: 6px;
    margin-top: 0;
    max-height: 0;
    overflow: hidden;
    opacity: 0;
    transition: all 0.2s ease;
}

.message:hover .message-actions,
.message.actions-visible .message-actions {
    opacity: 1;
    max-height: 40px;
    margin-top: 6px;
}

.message-action-btn {
    background: rgba(255, 255, 255, 0.1);
    border: 1px solid rgba(255, 255, 255, 0.2);
    border-radius: 12px;
    padding: 4px 10px;
    font-size: 12px;
    cursor: pointer;
    transition: all 0.2s ease;
    color: var(--app-text-primary);
    display: flex;
    align-items: center;
    gap: 4px;
}

.message-action-btn:hover {
    background: rgba(10, 132, 255, 0.3);
    border-color: var(--app-primary);
    transform: translateY(-2px);
}

/* ========== MESSAGE REACTIONS ========== */
.message-reactions {
    display: flex;
    flex-wrap: wrap;
    gap: 6px;
    margin-top: 8px;
}

.reaction-item {
    background: rgba(10, 132, 255, 0.1);
    border: 1px solid rgba(10, 132, 255, 0.3);
    border-radius: 16px;
    padding: 4px 10px;
    font-size: 14px;
    cursor: pointer;
    transition: all 0.2s ease;
    display: flex;
    align-items: center;
    gap: 4px;
}

.reaction-item:hover {
    background: rgba(10, 132, 255, 0.2);
    border-color: var(--app-primary);
    transform: scale(1.1);
}

.reaction-item.own-reaction {
    background: rgba(10, 132, 255, 0.3);
    border-color: var(--app-primary);
}

/* Non-clickable reactions from other users */
.reaction-item:not(.own-reaction) {
    opacity: 0.8;
}

.reaction-item:not(.own-reaction):hover {
    transform: none; /* Don't scale on hover for others' reactions */
    background: rgba(10, 132, 255, 0.1); /* Keep original background */
}

.reaction-emoji {
    font-size: 16px;
}

.reaction-count {
    font-size: 12px;
    font-weight: 600;
    color: var(--app-text-primary);
}

/* ========== REPLIED MESSAGE INDICATOR ========== */
.message-reply-to {
    background: rgba(142, 142, 147, 0.1);
    border-left: 3px solid var(--app-primary);
    border-radius: 6px;
    padding: 8px 10px;
    margin-bottom: 8px;
    font-size: 12px;
}

.reply-to-username {
    color: var(--app-primary);
    font-weight: 600;
    margin-bottom: 4px;
}

.reply-to-content {
    color: var(--app-text-secondary);
    opacity: 0.9;
    max-width: 100%;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

/* Highlight replied-to message when scrolled to */
.message.highlight-reply {
    animation: highlightPulse 1s ease-out;
}

@keyframes highlightPulse {
    0%, 100% {
        background-color: transparent;
    }
    50% {
        background-color: rgba(10, 132, 255, 0.2);
    }
}

/* Mobile optimizations */
@media (max-width: 768px) {
    /* Center login screen on mobile */
    .app-container {
        justify-content: center;
    }
    
    #login-section {
        width: 90%;
        margin: auto;
        align-self: center;
    }
    
    .emoji-grid {
        grid-template-columns: repeat(6, 1fr);
    }
    
    .emoji-item {
        font-size: 24px;
        min-width: 40px;
        min-height: 40px;
    }
    
    /* On mobile, message actions shown via long-press (actions-visible class) */
    .message.actions-visible .message-actions {
        opacity: 1;
        max-height: 40px;
        margin-top: 6px;
    }
}

/* --- Avatar Styles --- */

/* Profile Modal Upload Area */
.profile-image-container {
    display: flex;
    flex-direction: column;
    align-items: center;
    margin-bottom: 20px;
}

.profile-avatar-preview {
    width: 100px;
    height: 100px;
    border-radius: 50%;
    object-fit: cover;
    border: 3px solid var(--app-primary);
    margin-bottom: 10px;
    background-color: var(--app-card-secondary);
}

.profile-upload-btn {
    background: var(--app-card-secondary);
    border: 1px solid rgba(255,255,255,0.2);
    color: white;
    padding: 5px 10px;
    border-radius: 15px;
    font-size: 12px;
    cursor: pointer;
}

/* Avatars in Chat */
.message-header-row {
    display: flex;
    align-items: center;
    gap: 8px;
    margin-bottom: 4px;
}

.message-avatar {
    width: 32px;
    height: 32px;
    border-radius: 50%;
    object-fit: cover;
    background-color: #444;
    flex-shrink: 0;
}

/* Avatars in Contact List */
.room-avatar-container {
    margin-right: 15px;
    position: relative;
}

.room-avatar {
    width: 48px;
    height: 48px;
    border-radius: 50%;
    object-fit: cover;
    background-color: #444;
    border: 2px solid rgba(255,255,255,0.1);
}

/* Avatars in Room Header */
.header-avatar {
    width: 36px;
    height: 36px;
    border-radius: 50%;
    object-fit: cover;
    margin-right: 10px;
    border: 2px solid var(--app-primary);
    cursor: pointer;
    transition: transform 0.2s;
}

.header-avatar:hover {
    transform: scale(1.1);
}

/* Make all avatars clickable */
.message-avatar,
.room-avatar,
.profile-avatar-preview {
    cursor: pointer;
    transition: transform 0.2s;
}

.message-avatar:hover,
.room-avatar:hover,
.profile-avatar-preview:hover {
    transform: scale(1.1);
}

/* Avatar Enlarge Modal */
.avatar-modal {
    display: none;
    position: fixed;
    z-index: 10000;
    left: 0;
    top: 0;
    width: 100%;
    height: 100%;
    background-color: rgba(0, 0, 0, 0.9);
    align-items: center;
    justify-content: center;
}

.avatar-modal.show {
    display: flex;
}

.avatar-modal-content {
    max-width: 90%;
    max-height: 90%;
    border-radius: 8px;
    box-shadow: 0 4px 20px rgba(0, 0, 0, 0.5);
}

.avatar-modal-close {
    position: absolute;
    top: 20px;
    right: 35px;
    color: #f1f1f1;
    font-size: 40px;
    font-weight: bold;
    cursor: pointer;
    transition: 0.3s;
}

.avatar-modal-close:hover,
.avatar-modal-close:focus {
    color: #bbb;
}

/* --- Audio Visualizer Styles --- */
.video-wrapper.audio-only video {
    opacity: 0; /* Hide the black video box but keep it playing for audio */
    position: absolute;
    z-index: 0;
}

.audio-state-overlay {
    position: absolute;
    top: 0;
    left: 0;
    width: 100%;
    height: 100%;
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    background: linear-gradient(135deg, #1c1c1e, #2c2c2e);
    z-index: 1;
}

.audio-avatar-container {
    position: relative;
    width: 80px;
    height: 80px;
    margin-bottom: 15px;
}

.audio-avatar-img {
    width: 100%;
    height: 100%;
    border-radius: 50%;
    object-fit: cover;
    border: 3px solid var(--app-primary);
    box-shadow: 0 0 20px rgba(10, 132, 255, 0.3);
    position: relative;
    z-index: 2;
}

/* Pulse animation behind avatar - subtle effect */
.audio-avatar-pulse {
    position: absolute;
    top: 50%;
    left: 50%;
    transform: translate(-50%, -50%);
    width: 100%;
    height: 100%;
    border-radius: 50%;
    background: rgba(10, 132, 255, 0.2);
    z-index: 1;
    animation: pulse-ring 3s cubic-bezier(0.215, 0.61, 0.355, 1) infinite;
}

@keyframes pulse-ring {
    0% { transform: translate(-50%, -50%) scale(0.9); opacity: 0.3; }
    100% { transform: translate(-50%, -50%) scale(1.6); opacity: 0; }
}

/* Waveform Bars */
.audio-waveform {
    display: flex;
    align-items: center;
    gap: 4px;
    height: 35px; /* Increased to accommodate dynamic heights */
}

.wave-bar {
    width: 4px;
    height: 10px; /* Initial/fallback height */
    background-color: var(--app-primary);
    border-radius: 2px;
    transition: height 0.05s linear; /* Fast, near-instant response to audio */
}

/* Ensure labels and controls sit on top */
.video-wrapper.audio-only .video-label,
.video-wrapper.audio-only .fullscreen-button,
.video-wrapper.audio-only .pip-button {
    z-index: 200 !important; /* Increased to sit above overlay */
}

.video-wrapper.audio-only .focus-button {
    z-index: 300 !important; /* Higher than other controls */
}

/* --- Markdown Styling for Chat --- */
.message-content h1, .message-content h2, .message-content h3, 
.message-content h4, .message-content h5, .message-content h6 {
    margin: 16px 0 8px 0;
    font-weight: 600;
    color: #93c5fd;
}

.message-content ul, .message-content ol {
    margin: 8px 0;
    padding-left: 20px;
    color: inherit;
}

.message-content li {
    margin-bottom: 4px;
}

/* Markdown Tables */
.message-content table {
    border-collapse: collapse;
    margin: 12px 0;
    width: 100%;
    max-width: 100%;
    background-color: rgba(0, 0, 0, 0.2);
    border-radius: 4px;
    overflow: hidden;
}

.message-content th {
    border: 1px solid rgba(255, 255, 255, 0.1);
    padding: 10px;
    background-color: rgba(255, 255, 255, 0.05);
    font-weight: 600;
    text-align: left;
    color: #93c5fd;
}

.message-content td {
    border: 1px solid rgba(255, 255, 255, 0.1);
    padding: 10px;
}

.message-content tr:nth-child(even) {
    background-color: rgba(255, 255, 255, 0.02);
}

/* --- Enhanced Code Block Styling --- */

/* The main container */
.code-block {
    margin: 16px 0;
    background-color: #1e1e1e; /* Dark background matching Prism Tomorrow */
    border-radius: 8px;
    border: 1px solid #333;
    overflow: hidden; /* Ensures content stays inside rounded corners */
    position: relative;
    font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif;
    box-shadow: 0 4px 6px rgba(0, 0, 0, 0.2);
}

/* The Header Bar (Gray bar at top) */
.code-header {
    display: flex;
    justify-content: space-between;
    align-items: center;
    background-color: #2d2d2d;
    padding: 6px 12px;
    border-bottom: 1px solid #404040;
    height: 36px; /* Fixed height to prevent layout jumps */
}

/* Language Label (e.g. "HTML", "JAVASCRIPT") */
.code-language {
    color: #a0a0a0;
    font-size: 12px;
    font-weight: 600;
    text-transform: lowercase;
    font-family: 'SFMono-Regular', Consolas, 'Liberation Mono', Menlo, monospace;
}

/* Container for buttons on the right */
.code-actions {
    display: flex;
    align-items: center;
    gap: 8px;
}

/* The Buttons (Copy / Run) */
.header-btn {
    background-color: transparent;
    border: 1px solid #565656;
    color: #ccc;
    font-size: 11px;
    padding: 3px 10px;
    border-radius: 4px;
    cursor: pointer;
    transition: all 0.2s ease;
    display: flex;
    align-items: center;
    gap: 4px;
    line-height: 1.4;
    height: 24px;
}

.header-btn:hover {
    background-color: rgba(255, 255, 255, 0.1);
    color: #fff;
    border-color: #888;
}

/* Specific style for Run button */
.header-btn.preview-btn {
    border-color: #4a90e2;
    color: #4a90e2;
}

.header-btn.preview-btn:hover {
    background-color: rgba(74, 144, 226, 0.15);
}

/* --- Prism.js Overrides --- */
/* These ensure the code area fits snugly against the header */

.code-block pre[class*="language-"] {
    margin: 0 !important;
    padding: 16px !important;
    background: transparent !important; /* Use container bg */
    border: none !important;
    border-radius: 0 0 8px 8px !important; /* Only round bottom corners */
    text-shadow: none !important;
    overflow: auto;
}

.code-block code {
    font-family: 'SFMono-Regular', Consolas, 'Liberation Mono', Menlo, monospace !important;
    font-size: 13px;
    line-height: 1.5;
}

/* --- Fix: Artifact / HTML Preview Modal --- */
.html-preview-overlay {
    position: fixed;
    top: 0;
    left: 0;
    width: 100vw;
    height: 100vh;
    background-color: rgba(0, 0, 0, 0.85);
    /* Use max integer value to ensure it sits on top of everything, including sticky headers */
    z-index: 2147483647 !important; 
    display: flex;
    align-items: center;
    justify-content: center;
    backdrop-filter: blur(5px);
    box-sizing: border-box;
    padding: 20px; /* Ensures the container doesn't touch the screen edges */
}

.html-preview-container {
    width: 95%;
    height: 90vh; /* Fixed height relative to viewport */
    max-width: 1200px;
    background-color: #1e1e1e;
    border-radius: 8px;
    display: flex;
    flex-direction: column;
    box-shadow: 0 0 50px rgba(0,0,0,0.8);
    border: 1px solid #4a90e2;
    overflow: hidden; /* Prevents container scrollbars */
}

.html-preview-header {
    display: flex;
    justify-content: space-between;
    align-items: center;
    padding: 12px 20px;
    background-color: #2c3e50;
    border-bottom: 1px solid #4a90e2;
    border-radius: 8px 8px 0 0;
    flex-shrink: 0; /* Prevents header from collapsing */
    z-index: 2;
}

.html-preview-title {
    color: white;
    font-weight: 600;
}

.html-preview-close {
    background: none;
    border: none;
    color: #ccc;
    font-size: 20px;
    cursor: pointer;
}

.html-preview-close:hover {
    color: white;
}

.html-preview-iframe {
    flex-grow: 1; /* Takes up all remaining space */
    width: 100%;
    height: 100%; /* Important: Fills the flex container */
    border: none;
    background-color: white;
}

/* --- Feature: User Message "Read More" --- */
.message-content.collapsed {
    max-height: 150px; /* Show about 6-8 lines */
    overflow: hidden;
    position: relative;
    mask-image: linear-gradient(180deg, #000 60%, transparent); /* Fade out effect */
    -webkit-mask-image: linear-gradient(180deg, #000 60%, transparent);
}

.read-more-btn {
    display: block;
    margin-top: 8px;
    background: rgba(255,255,255,0.1);
    border: 1px solid rgba(255,255,255,0.2);
    color: #fff;
    padding: 4px 12px;
    border-radius: 12px;
    font-size: 12px;
    cursor: pointer;
    width: fit-content;
}

.read-more-btn:hover {
    background: rgba(255,255,255,0.2);
}

/* --- Feature: LLM Jump Controls (Hover) --- */
.message.bot-message {
    position: relative; /* Anchor for absolute buttons */
}

/* --- Updated LLM Jump Controls (Sticky) --- */
.jump-controls {
    position: sticky; /* Stick to the view */
    top: 10px;        /* Distance from top of scroll area */
    float: right;     /* Push to the right side */
    display: flex;
    flex-direction: column;
    gap: 5px;
    opacity: 0;       /* Hidden by default */
    transition: opacity 0.2s ease;
    z-index: 90;
    margin-left: 10px; /* Space from text */
    margin-bottom: 10px;
}

/* Show on hover over the message */
.message.bot-message:hover .jump-controls {
    opacity: 1;
}

.jump-btn {
    background: rgba(44, 62, 80, 0.9); /* Semi-transparent dark background */
    border: 1px solid #4a90e2;
    color: #fff;
    padding: 4px 10px;
    border-radius: 12px; /* Rounded pill shape */
    font-size: 11px;
    cursor: pointer;
    white-space: nowrap;
    box-shadow: 0 2px 5px rgba(0,0,0,0.3);
    text-align: center;
    backdrop-filter: blur(2px);
}

.jump-btn:hover {
    background: #4a90e2;
    transform: translateY(-1px);
}

/* Style for the new Copy button */
.jump-btn.copy-all-btn {
    border-color: #10b981; /* Green border for copy */
    color: #a7f3d0;
}

.jump-btn.copy-all-btn:hover {
    background: #10b981;
    color: white;
}

/* --- Updated Stop Generation Button --- */
.stop-generation-controls {
    display: flex;
    justify-content: center;
    gap: 10px;
    margin: 4px 0; /* Reduced margin */
    width: 100%;
}

.stop-gen-btn {
    /* Muted Blue Ghost Style */
    background-color: rgba(59, 130, 246, 0.15); 
    color: #93c5fd; /* Soft light blue text */
    border: 1px solid rgba(59, 130, 246, 0.3);
    
    /* Smaller Size */
    border-radius: 12px; /* Pill shape looks better for small actions */
    padding: 2px 10px;
    font-size: 10px;
    font-weight: 500;
    text-transform: uppercase;
    letter-spacing: 0.5px;
    
    cursor: pointer;
    display: flex;
    align-items: center;
    gap: 4px;
    transition: all 0.2s ease;
    z-index: 50;
    opacity: 0.8; /* Slightly transparent by default */
}

.stop-gen-btn:hover {
    background-color: rgba(59, 130, 246, 0.3);
    border-color: rgba(59, 130, 246, 0.6);
    color: #ffffff;
    opacity: 1;
}

.stop-gen-btn:disabled {
    background-color: rgba(148, 163, 184, 0.2);
    color: #94a3b8;
    border-color: transparent;
    cursor: not-allowed;
}

/* Ensure container handles the absolute positioning of controls if needed */
.message.bot-message {
    position: relative; 
}

/* --- Mobile PWA & Tab Layout --- */

/* Hide mobile nav on desktop */
.mobile-nav {
    display: none;
}

@media (max-width: 768px) {
    /* 1. Reset Layout for full height */
    body, html {
        height: 100dvh; /* Dynamic Viewport Height */
        overflow: hidden;
    }

    .app-container, #app-section, #app-content {
        height: 100%;
        overflow: hidden;
    }

    /* 1. Chat Wrapper: Full screen container (behind mobile nav) */
    .chat-wrapper {
        position: fixed !important;
        top: 52px; /* Below fixed header (50px + 2px buffer) */
        left: 0;
        right: 0;
        bottom: 60px; /* Stop exactly at the nav bar */
        width: 100% !important;
        height: auto !important; /* Let top/bottom define height */
        margin: 0 !important;
        
        /* Rounded corners for the whole chat card */
        border-radius: 16px !important;
        
        display: flex !important;
        flex-direction: column;
        padding: 0 !important;
        overflow: hidden; /* Contains the children */
        background-color: var(--app-card-bg);
        z-index: 10;
    }

    /* Controls bar at top of chat */
    .chat-actions-toolbar {
        flex-shrink: 0; /* Don't shrink */
        z-index: 10;
        background-color: var(--app-card-bg);
        border-bottom: 1px solid rgba(255,255,255,0.1);
        padding-top: 8px; /* Extra padding to ensure buttons are fully visible */
    }

    /* 3. Messages Container: Fill space */
    .messages-container {
        flex-grow: 1;
        height: auto !important;
        overflow-y: auto;
        /* Add padding at bottom so text isn't hidden behind input bar */
        padding: 15px 15px 90px 15px !important;
        margin-bottom: 0 !important;
        border-radius: 0 !important;
    }

    /* 2. Input Container: Pinned to bottom of wrapper */
    .message-input-container {
        position: absolute !important;
        bottom: 0;
        left: 0;
        width: 100%;
        background-color: var(--app-card-bg);
        padding: 10px;
        z-index: 20;
        border-top: 1px solid rgba(255,255,255,0.1);
        display: flex;
        gap: 10px;
        box-shadow: 0 -2px 10px rgba(0,0,0,0.2);
        margin-bottom: 0 !important;
        
        /* Round bottom corners to match wrapper */
        border-radius: 0 0 16px 16px !important;
    }

    /* 2. Video Container: Allow free movement */
    .video-container {
        display: none !important;
        position: fixed !important;
        top: 50px; /* Below fixed header (50px) */
        left: 0;
        width: 100% !important;
        height: calc(100dvh - 110px) !important; /* Subtract header (50px) + nav bar (60px) */
        background: #000;
        z-index: 9000; /* Below modals (10000) and header (9999) but above chat */
        /* Enable pointer events for interaction */
        pointer-events: auto !important;
        /* Restore rounded corners */
        border-radius: 16px 16px 0 0 !important;
        /* Allow items to be positioned absolutely within - visible to allow resize handles */
        overflow-y: auto; /* Allow vertical scrolling for stacked videos */
        overflow-x: hidden; /* Prevent horizontal scroll */
    }

    /* 5. Video Wrapper: Allow absolute positioning for drag/resize */
    .video-wrapper {
        /* Default position for stack, but allows override by JS for drag */
        position: absolute !important;
        /* REMOVED !important from width/height to allow JS focus scaling */
        width: 95%; /* Default width - can be overridden by JS */
        height: 250px; /* Default height - can be overridden by JS */
        /* Restore rounded corners */
        border-radius: 12px !important;
        /* FIX: Visible overflow allows controls (focus btn, resize handle) to be seen */
        overflow: visible !important;
        touch-action: none; /* Critical: prevents screen scrolling while dragging video */
    }
    
    /* Add visible resize handle for mobile */
    .video-wrapper::after {
        content: '';
        position: absolute;
        bottom: 0;
        right: 0;
        width: 40px;
        height: 40px;
        background: linear-gradient(135deg, transparent 50%, rgba(255,255,255,0.3) 50%);
        border-bottom-right-radius: 12px;
        pointer-events: none; /* Visual only - touch events handled by JS */
    }

    /* 6. Active States for Tabs */
    /* Default: Show contacts list, hide everything else */
    .chat-wrapper { display: none !important; }
    .video-container { display: none !important; }
    #profile-content { display: none !important; }
    #rooms-list-section { display: flex !important; } /* Show contacts by default */
    #rooms-list-section.hidden { display: none !important; } /* But respect hidden class */
    
    /* When Chat Tab is active (and in a room) */
    body.tab-chat .chat-wrapper { display: flex !important; }
    body.tab-chat .video-container { display: none !important; }
    body.tab-chat #profile-content { display: none !important; }
    body.tab-chat #rooms-list-section { display: none !important; } /* Hide contacts when in chat */

    /* When Video Tab is active */
    body.tab-video .chat-wrapper { display: none !important; }
    body.tab-video .video-container { 
        display: flex !important; 
        flex-direction: column;
        z-index: 9000 !important; /* Ensure z-index is set for video tab */
    }
    body.tab-video #profile-content { display: none !important; }
    body.tab-video #rooms-list-section { display: none !important; } /* Hide contacts when in video */

    /* When Profile Tab is active */
    body.tab-profile .chat-wrapper { display: none !important; }
    body.tab-profile .video-container { display: none !important; }
    body.tab-profile #profile-content { 
        display: block !important;
        padding: 10px; /* Reduced from 20px */
        height: calc(100dvh - 60px);
        overflow-y: auto;
    }
    body.tab-profile #rooms-list-section { display: none !important; } /* Hide contacts when in profile */
    
    /* Remove room-body min-height when profile tab is active on mobile */
    body.tab-profile .room-body {
        min-height: 0 !important;
    }

    /* 5. Mobile Bottom Navigation Styling */
    .mobile-nav {
        display: flex;
        position: fixed;
        bottom: 0;
        left: 0;
        width: 100%;
        height: 50px; /* Slimmer */
        background-color: #000000;
        border-top: 1px solid #333;
        z-index: 1000;
        padding-bottom: env(safe-area-inset-bottom);
    }

    .mobile-nav-btn {
        flex: 1;
        background: none;
        border: none;
        color: rgba(10, 132, 255, 0.5); /* Dimmed blue for inactive */
        display: flex;
        flex-direction: column;
        align-items: center;
        justify-content: center;
        font-size: 9px;
        cursor: pointer;
        outline: none;
        transition: color 0.2s ease;
    }

    .mobile-nav-btn .nav-icon {
        display: flex;
        align-items: center;
        justify-content: center;
        margin-bottom: 2px;
    }

    .mobile-nav-btn .nav-icon svg {
        width: 20px;
        height: 20px;
        stroke: currentColor;
    }

    .mobile-nav-btn.active {
        color: var(--app-primary); /* Blue to match layout */
    }

    /* Hide desktop controls that interfere */
    .app-title { display: none; }
    .chat-actions-toolbar { 
        overflow-x: auto; 
        white-space: nowrap; 
        padding-bottom: 5px;
    }
}

/* --- Profile Tab Styling --- */
#profile-content {
    padding: 0 !important;
    background-color: #000; /* Match mobile dark theme */
    color: #fff;
}

.profile-header-card {
    background-color: var(--app-card-bg);
    padding: 30px 20px;
    display: flex;
    flex-direction: column;
    align-items: center;
    border-bottom: 1px solid rgba(255,255,255,0.1);
}

.profile-avatar-container {
    position: relative;
    margin-bottom: 15px;
}

.profile-large-avatar {
    width: 100px;
    height: 100px;
    border-radius: 50%;
    object-fit: cover;
    border: 3px solid var(--app-primary);
}

.profile-edit-badge {
    position: absolute;
    bottom: 0;
    right: 0;
    background-color: var(--app-primary);
    width: 32px;
    height: 32px;
    border-radius: 50%;
    display: flex;
    align-items: center;
    justify-content: center;
    cursor: pointer;
    border: 2px solid var(--app-card-bg);
}

.profile-details h2 {
    margin: 0;
    font-size: 22px;
    text-align: center;
}

.profile-id {
    color: #8E8E93;
    font-size: 13px;
    margin: 5px 0 0 0;
    font-family: monospace;
}

.settings-list {
    padding: 20px;
}

.settings-list h3 {
    color: #8E8E93;
    font-size: 13px;
    text-transform: uppercase;
    margin-bottom: 10px;
    padding-left: 10px;
}

.setting-row {
    background-color: var(--app-card-bg);
    padding: 15px;
    margin-bottom: 1px; /* Separator line effect */
    display: flex;
    justify-content: space-between;
    align-items: center;
}

.setting-row:first-of-type { border-radius: 12px 12px 0 0; }
.setting-row:last-of-type { border-radius: 0 0 12px 12px; margin-bottom: 20px; }

.setting-info {
    display: flex;
    align-items: center;
    gap: 12px;
    font-size: 16px;
}

.setting-icon { font-size: 20px; }
.chevron { color: #8E8E93; font-weight: bold; font-size: 20px; }

.setting-row.clickable { cursor: pointer; }
.setting-row.clickable:active { background-color: rgba(255,255,255,0.1); }

.logout-row {
    margin-top: 20px;
    border-radius: 12px !important;
    color: #FF3B30;
}

/* Ensure overlay controls stay visible on mobile */
.video-wrapper .recording-ui, 
.video-wrapper .drawing-controls {
    z-index: 200 !important; /* Force above video */
    display: flex !important; /* Prevent hiding */
    opacity: 1 !important;
}

.video-wrapper .focus-button {
    z-index: 300 !important; /* Higher than all other controls */
    display: inline-block !important; /* Prevent hiding */
    opacity: 1 !important;
}

/* Fix Profile Spacing */
.profile-section {
    margin-top: 0 !important; /* Remove top gap */
    padding: 15px !important; /* Compact padding */
    background: #1a2330;
    border-radius: 10px;
}

.settings-section {
    margin-top: 10px !important; /* Small gap between sections */
    background: #1a2330;
    border-radius: 10px;
    padding: 15px !important; /* Compact padding */
}

/* Ensure content fits without scrolling parent unnecessarily */
#profile-content {
    background-color: #000;
}

/* Override desktop profile styles for mobile */
@media (max-width: 768px) {
    .profile-section h3 {
        margin-top: 0 !important;
        margin-bottom: 15px !important;
    }
    
    /* Show mobile back button on mobile only */
    .mobile-back-btn {
        display: flex !important;
        background: var(--app-primary) !important;
        color: white !important;
        border: none;
        padding: 8px 12px;
        border-radius: 8px;
        font-weight: 600;
        align-items: center;
        gap: 5px;
        white-space: nowrap;
    }
}

/* Hide mobile back button on desktop */
.mobile-back-btn {
    display: none;
}

/* ============================================
   Safety Number Verification Styles
   ============================================ */

/* Verify Button in Toolbar - inherits toolbar button styles */
.chat-actions-toolbar .verify-identity-btn {
    color: #10b981;
}

.chat-actions-toolbar .verify-identity-btn:hover {
    background-color: rgba(16, 185, 129, 0.15);
    color: #10b981;
}

/* Delete button in message context menu */
.message-action-btn.delete-btn {
    color: #ff6b6b;
    border-color: rgba(255, 107, 107, 0.3);
}

.message-action-btn.delete-btn:hover {
    background-color: rgba(255, 107, 107, 0.1);
    border-color: #ff6b6b;
}

.message-action-btn.delete-btn svg {
    stroke: currentColor;
    width: 14px;
    height: 14px;
}

/* TTL Indicator for disappearing messages */
.ttl-indicator {
    display: inline-flex;
    align-items: center;
    gap: 4px;
    font-size: 11px;
    color: #4a90e2;
    margin-left: 8px;
    background: rgba(74, 144, 226, 0.1);
    padding: 1px 6px;
    border-radius: 4px;
}

.ttl-indicator svg {
    stroke: currentColor;
    width: 12px;
    height: 12px;
}

/* Verification Modal Styling */
.verification-modal-content {
    max-width: 320px;
    width: 90%;
    text-align: center;
    padding: 12px;
    margin-top: 60px; /* Clear top bar */
    max-height: calc(100vh - 100px);
    overflow-x: hidden;
    overflow-y: auto;
    box-sizing: border-box;
}

.verification-modal-content .modal-header {
    display: flex;
    justify-content: space-between;
    align-items: center;
    margin-bottom: 10px;
}

.verification-modal-content .modal-header h3 {
    margin: 0;
    font-size: 16px;
}

.verification-intro {
    color: #b8c5d6;
    margin-bottom: 12px;
    font-size: 12px;
    line-height: 1.4;
}

.safety-number-grid {
    display: grid;
    grid-template-columns: repeat(2, 1fr); /* Original 2 columns */
    gap: 12px;
    margin-bottom: 15px;
    background: rgba(0, 0, 0, 0.2);
    padding: 15px;
    border-radius: 10px;
    border: 1px solid rgba(255, 255, 255, 0.1);
    box-sizing: border-box;
}

.safety-block {
    font-family: 'SF Mono', 'Courier New', monospace;
    font-size: 20px;
    font-weight: 700;
    color: #4a90e2; /* Blue */
    letter-spacing: 2px;
    text-align: center;
}

.verification-footer {
    margin-top: 8px;
}

.verification-footer .security-note {
    font-size: 11px;
    color: #888;
    margin-bottom: 10px;
}

.verification-footer .primary-btn {
    padding: 4px 12px;
    font-size: 11px;
    min-width: auto;
    width: auto;
}

/* Header Avatar */
.header-avatar {
    width: 36px;
    height: 36px;
    border-radius: 50%;
    object-fit: cover;
    margin-right: 10px;
}

/* --- LLM Thinking/Reasoning Section --- */
.llm-thinking-section {
    background-color: rgba(74, 144, 226, 0.06);
    border: 1px solid rgba(74, 144, 226, 0.2);
    border-radius: 6px;
    margin-bottom: 8px;
    overflow: hidden;
}

.llm-thinking-header {
    cursor: pointer;
    padding: 5px 10px;
    background-color: rgba(74, 144, 226, 0.1);
    display: flex;
    align-items: center;
    gap: 6px;
    font-size: 12px;
    font-weight: 600;
    color: #93c5fd;
    user-select: none;
    list-style: none;
}

.llm-thinking-header::-webkit-details-marker {
    display: none;
}

.llm-thinking-header::before {
    content: '▶';
    font-size: 9px;
    margin-right: 4px;
    transition: transform 0.2s ease;
    flex-shrink: 0;
}

.llm-thinking-section[open] > .llm-thinking-header::before {
    transform: rotate(90deg);
}

.llm-thinking-chars {
    font-size: 11px;
    color: #7aa2d4;
    font-weight: 400;
}

.llm-thinking-status {
    font-size: 11px;
    font-weight: 400;
    margin-left: auto;
}

.llm-thinking-content {
    padding: 6px 10px;
    font-size: 13px;
    color: #b0bec5;
    max-height: 400px;
    overflow-y: auto;
    line-height: 1.45;
    white-space: pre-wrap;
    word-break: break-word;
}

.llm-thinking-content::-webkit-scrollbar {
    width: 6px;
}

.llm-thinking-content::-webkit-scrollbar-thumb {
    background: rgba(74, 144, 226, 0.3);
    border-radius: 3px;
}

/* ============================================
   Invite Dialog Section Ordering
   ============================================
   Controls the visual order of the three sections (Secure Link / QR Code /
   Invite Code) in showCopyCodeDialog() and showRegeneratedCodeDialog().
   The DOM order is fixed (link, divider, qr, divider, code) but CSS `order`
   lets us reorder visually per-platform:

     DESKTOP (>= 769px):  Link -> OR -> Code -> OR -> QR
     MOBILE  (<= 768px):  QR   -> OR -> Code -> OR -> Link

   Rationale: desktop users copy/paste text so the link is the primary
   action; mobile users scan QRs with their camera so the QR belongs up top.
   The "Invite Code" sits in the middle both ways as a fallback that works
   on every platform.
   ============================================ */
.invite-sections {
    display: flex;
    flex-direction: column;
    /* Matches the old block-level ~15px collapsed-margin spacing between
       sections. Combined with the margin override below, total inter-item
       spacing is exactly 15px regardless of each child's inline margins. */
    gap: 15px;
    /* Preserve the ~20px buffer before the "Enter Room" / "Done" button
       that used to come from the code section's `margin: 20px 0`. */
    margin-bottom: 20px;
}

/* Flex doesn't collapse adjacent margins, so the inline `margin: 15px 0`
   (on sections) and `margin: 10px 0` (on OR dividers) would stack on top
   of the container's gap and produce 25-30px of space between children.
   Zero the vertical inline margins so `gap` is the sole source of spacing
   between children. `!important` is required to beat the inline styles. */
.invite-sections > .invite-section,
.invite-sections > .invite-divider {
    margin-top: 0 !important;
    margin-bottom: 0 !important;
}

/* Desktop default ordering */
.invite-sections .invite-link    { order: 1; }
.invite-sections .invite-divider-1 { order: 2; }
.invite-sections .invite-code    { order: 3; }
.invite-sections .invite-divider-2 { order: 4; }
.invite-sections .invite-qr      { order: 5; }

@media (max-width: 768px) {
    /* Mobile: QR first, then Code, then Link - same dividers stay between */
    .invite-sections .invite-qr      { order: 1; }
    .invite-sections .invite-divider-1 { order: 2; }
    .invite-sections .invite-code    { order: 3; }
    .invite-sections .invite-divider-2 { order: 4; }
    .invite-sections .invite-link    { order: 5; }
}

/* =====================================================================================
   BRIDGE INTEGRATION: iframe-mode view for connecting to a WebRTC API Bridge as a contact.
   The container fills the room-content area; the status strip pins to the top with a lock
   icon to convey end-to-end encryption (Double Ratchet + ML-KEM). The iframe is sandboxed
   and full-bleed beneath the strip. The disconnect overlay surfaces if the bridge goes away.
   ===================================================================================== */
.bridge-mode-container {
    display: none;             /* Toggled to flex by app.js when entering bridge mode */
    flex-direction: column;
    position: absolute;
    inset: 0;
    z-index: 50;               /* Above chat surface, below modal overlays */
    background: var(--background-primary, #0e0f12);
}

/* SINGLE-COLUMN BRIDGE FIX (Dec 2025):
 * In single-column (default, dual-pane OFF) mode, _enterBridgeMode hides the
 * standard chat surfaces (.room-header and .room-body via _toggleChatUiForBridge)
 * so the bridge container has the viewport to itself. But .bridge-mode-container
 * uses `position: absolute; inset: 0`, and absolutely-positioned children DO
 * NOT contribute to their parent's height. With the chat surfaces hidden,
 * `#room-content` had no flow content and collapsed to height: 0 — making the
 * bridge container `inset: 0` of a 0-tall box, i.e. invisible. The user saw
 * a blank black/transparent area instead of the bridge UI.
 *
 * Dual-pane mode wasn't affected because its media query already gives
 * `#room-content` `display: flex !important; flex: 1 1 auto;`, which keeps
 * the box sized by flex chain even when all children are absolute/hidden.
 *
 * Fix: when `body.bridge-mode-active` is set (toggled by _enterBridgeMode /
 * _exitBridgeMode), give the same flex sizing to `#room-content` in
 * single-column mode. Scoped with `:not(.dual-pane-enabled)` so we don't
 * fight the dual-pane row layout (which uses `flex-direction: row`).
 *
 * Why the body class (not just CSS targeting `.bridge-mode-container`):
 * applying flex layout to `#room-content` is a layout-shape change that
 * other code paths (room switch, message rendering) should NOT see unless
 * we're actually in bridge mode. The class is added/removed atomically
 * around the bridge entry/exit so we don't disturb normal chat layout.
 */
body.bridge-mode-active:not(.dual-pane-enabled) #chats-content.tab-content,
body.bridge-mode-active:not(.dual-pane-enabled) #chats-content.tab-content.active {
    display: flex !important;
    flex-direction: column;
    height: 100%;
}

body.bridge-mode-active:not(.dual-pane-enabled) #room-content {
    flex: 1 1 auto !important;
    height: auto !important;
    min-height: 0;
}

.bridge-status-strip {
    display: flex;
    align-items: center;
    gap: 10px;
    padding: 8px 14px;
    border-bottom: 1px solid rgba(255,255,255,0.08);
    background: rgba(20, 22, 28, 0.92);
    color: rgba(255,255,255,0.92);
    font: 500 13px/1.2 system-ui, -apple-system, "Segoe UI", sans-serif;
    user-select: none;
    flex-shrink: 0;
}

.bridge-status-strip .bridge-icon {
    font-size: 16px;
    opacity: 0.85;
}

.bridge-status-strip .bridge-name {
    flex: 0 1 auto;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
    max-width: 50%;
}

.bridge-status-strip .bridge-lock-icon {
    font-size: 14px;
    color: #41d27c;
    opacity: 0.95;
}

.bridge-status-strip .bridge-status-text {
    margin-left: auto;
    font-size: 12px;
    color: rgba(255,255,255,0.65);
}

/* Refresh button on the bridge status strip (non-LLM bridge pages).
   Matches the LlmBridgeView header's ↻ control visually: square icon
   button with a subtle hover tint. Sits AFTER the status text so the
   layout stays "back ← | icon | name | 🔒 | Connected (E2E) | ↻"
   which reads left-to-right as a progression from navigation to state
   to action. */
.bridge-status-strip .bridge-refresh-btn {
    background: transparent;
    border: 1px solid rgba(255,255,255,0.14);
    color: rgba(255,255,255,0.85);
    width: 28px;
    height: 26px;
    border-radius: 6px;
    font-size: 14px;
    line-height: 1;
    cursor: pointer;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    transition: background 0.15s ease, border-color 0.15s ease, transform 0.15s ease;
    padding: 0;
    flex-shrink: 0;
}
.bridge-status-strip .bridge-refresh-btn:hover {
    background: rgba(255,255,255,0.08);
    border-color: rgba(255,255,255,0.28);
}
.bridge-status-strip .bridge-refresh-btn:active {
    transform: rotate(180deg);
}
.bridge-status-strip .bridge-refresh-btn:focus-visible {
    outline: 2px solid rgba(120, 180, 255, 0.6);
    outline-offset: 1px;
}

/* Iframe history navigation buttons sit next to the refresh button. They
   invoke iframe.contentWindow.history.back() / forward() so users can move
   within the bridged app (e.g. open a folder in MediaShelf, then "go back"
   to the previous folder) without losing the secure tunnel.

   Styled identically to .bridge-refresh-btn so the three controls read as a
   single visual cluster. Always-enabled (no :disabled state) — the click
   handler is a no-op if there's no history to navigate, so visually greying
   them out wasn't worth the loss of contrast. The glyphs ❮ ❯ are heavier
   (HEAVY LEFT/RIGHT-POINTING ANGLE QUOTATION MARK ORNAMENT) than ‹ › so
   they have similar visual weight to the ↻ refresh icon. */
.bridge-status-strip .bridge-history-btn {
    background: transparent;
    border: 1px solid rgba(255,255,255,0.14);
    color: rgba(255,255,255,0.85);
    width: 28px;
    height: 26px;
    border-radius: 6px;
    font-size: 14px;
    line-height: 1;
    cursor: pointer;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    transition: background 0.15s ease, border-color 0.15s ease;
    padding: 0;
    flex-shrink: 0;
}
.bridge-status-strip .bridge-history-btn:hover {
    background: rgba(255,255,255,0.08);
    border-color: rgba(255,255,255,0.28);
}
.bridge-status-strip .bridge-history-btn:focus-visible {
    outline: 2px solid rgba(120, 180, 255, 0.6);
    outline-offset: 1px;
}

.bridge-iframe-wrapper {
    position: relative;
    flex: 1 1 auto;
    min-height: 0;             /* Allow iframe to shrink in flex layout */
    background: #000;
}

.bridge-iframe-wrapper #bridge-iframe {
    width: 100%;
    height: 100%;
    border: 0;
    background: #fff;
    display: block;
}

.bridge-disconnect-overlay {
    position: absolute;
    inset: 0;
    display: flex;
    align-items: center;
    justify-content: center;
    background: rgba(10, 11, 14, 0.85);
    backdrop-filter: blur(4px);
    z-index: 5;
    color: #fff;
    font: 500 14px/1.4 system-ui, -apple-system, sans-serif;
    text-align: center;
    padding: 24px;
}

/* Bridge loading overlay: covers the iframe while the encrypted tunnel is being
   established and the remote page is being streamed in. Sits beneath the disconnect
   overlay (z-index 4 vs 5) so a mid-load disconnect still takes visual precedence. */
.bridge-loading-overlay {
    position: absolute;
    inset: 0;
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    gap: 18px;
    background: linear-gradient(135deg, rgba(14, 15, 18, 0.96), rgba(22, 26, 34, 0.96));
    backdrop-filter: blur(6px);
    z-index: 4;
    color: #fff;
    text-align: center;
    padding: 24px;
}

.bridge-loading-overlay .bridge-loading-content {
    max-width: 380px;
    display: flex;
    flex-direction: column;
    gap: 6px;
}

.bridge-loading-overlay .bridge-loading-stage {
    font: 600 15px/1.35 system-ui, -apple-system, sans-serif;
    color: #e7ecf1;
    margin: 0;
}

.bridge-loading-overlay .bridge-loading-sub {
    font: 400 12px/1.55 system-ui, -apple-system, sans-serif;
    color: rgba(255, 255, 255, 0.62);
    margin: 0;
}

/* Determinate progress bar. The JS estimator fills .bridge-loading-progress-fill
   width asymptotically based on stage elapsed time, so the % tries to gauge how
   much of the load remains. Snapped to 100% on the iframe `load` event. */
.bridge-loading-overlay .bridge-loading-progress-wrap {
    width: 280px;
    display: flex;
    flex-direction: column;
    gap: 6px;
}

.bridge-loading-overlay .bridge-loading-progress-bar {
    width: 100%;
    height: 8px;
    background: rgba(255, 255, 255, 0.08);
    border: 1px solid rgba(65, 210, 124, 0.22);
    border-radius: 6px;
    overflow: hidden;
}

.bridge-loading-overlay .bridge-loading-progress-fill {
    height: 100%;
    width: 0%;
    background: linear-gradient(90deg, #41d27c, #7ae5a3);
    border-radius: 6px;
    box-shadow: 0 0 14px rgba(65, 210, 124, 0.55);
    transition: width 0.35s ease-out;
}

.bridge-loading-overlay .bridge-loading-percent {
    font: 600 12px/1.3 system-ui, -apple-system, sans-serif;
    color: rgba(255, 255, 255, 0.82);
    text-align: right;
    font-variant-numeric: tabular-nums; /* keep digit width stable */
    min-height: 16px;
}

.bridge-disconnect-overlay .bridge-disconnect-content {
    max-width: 320px;
}

.bridge-disconnect-overlay .bridge-disconnect-title {
    font-size: 16px;
    margin: 0 0 8px;
    color: #ff7b7b;
}

.bridge-disconnect-overlay .bridge-disconnect-detail {
    margin: 0;
    color: rgba(255,255,255,0.78);
    font-size: 13px;
}

/* Dismiss button on the disconnect overlay. Lets the user close the
   "Bridge connection lost" banner so they can keep interacting with
   whatever the iframe rendered before the tunnel died (cached page
   content, in-flight DOM state). Positioned in the top-right corner,
   matching the visual weight of a system-window close control. */
.bridge-disconnect-overlay .bridge-disconnect-dismiss {
    position: absolute;
    top: 10px;
    right: 12px;
    width: 30px;
    height: 30px;
    border: 1px solid rgba(255, 255, 255, 0.18);
    border-radius: 50%;
    background: rgba(255, 255, 255, 0.08);
    color: #fff;
    font-size: 20px;
    line-height: 1;
    cursor: pointer;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    padding: 0;
    transition: background 0.15s, border-color 0.15s, transform 0.1s;
}

.bridge-disconnect-overlay .bridge-disconnect-dismiss:hover {
    background: rgba(255, 123, 123, 0.22);
    border-color: rgba(255, 123, 123, 0.55);
}

.bridge-disconnect-overlay .bridge-disconnect-dismiss:active {
    transform: scale(0.94);
}

@media (max-width: 768px) {
    .bridge-status-strip {
        padding: 7px 10px;
        gap: 8px;
        font-size: 12px;
    }
    .bridge-status-strip .bridge-name {
        max-width: 40%;
    }
    .bridge-status-strip .bridge-status-text {
        font-size: 11px;
    }
}

/* =============================================================================
 * DESKTOP DUAL-PANE LAYOUT (Microsoft Teams / Slack style)
 * -----------------------------------------------------------------------------
 * Opt-in via the Settings → Appearance "Desktop Dual-Pane Layout" toggle.
 * When enabled the body gets the `dual-pane-enabled` class and, on screens
 * >= 1024px, the contact sidebar AND the chat pane render side-by-side with
 * a draggable resize handle between them. Without the body class — or below
 * 1024px — the original single-column mutex behaviour applies (clicking a
 * contact hides the list and shows the chat). Mobile tabs and tablet
 * single-column flows are untouched in both modes.
 *
 * Layout grammar (only active when `body.dual-pane-enabled` AND >= 1024px):
 *   #chats-content          — flex row container; contains:
 *     #rooms-list-section   — left sidebar (width = --sidebar-width)
 *     #sidebarResizeHandle  — 8px drag handle with embedded collapse button
 *     #room-content         — right chat pane (fills remaining space)
 *
 * `#room-content` is ALWAYS rendered on desktop even when no room is open.
 * In that state it shows the `#roomEmptyState` placeholder. selectRoom()
 * adds `.has-room` to `#room-content`; the empty-state CSS rules flip when
 * that class is present.
 *
 * Collapsed-sidebar state (`body.sidebar-collapsed`): sidebar width clamps
 * to 0, only a slim "peek" strip with the expand button remains visible.
 * A secondary "Show contacts" button inside the empty state provides a
 * touch-friendly alternative entry point.
 *
 * All JS wiring lives in `_initDesktopLayout` + `_initDualPaneToggle`
 * (see app.js).
 * ========================================================================== */

/* Handle + empty state are invisible by default; the desktop media query
 * inside `body.dual-pane-enabled` is the only place that reveals them. With
 * the toggle off (the default) the legacy single-column mutex behaviour
 * applies on every viewport size. */
.sidebar-resize-handle { display: none; }
.room-empty-state { display: none; }

@media (min-width: 1024px) {
    /* All rules in this block are scoped to `body.dual-pane-enabled` so the
     * dual-pane layout is strictly opt-in. The previous version applied
     * these on every >= 1024px viewport, which surprised users who
     * preferred the simpler single-column flow. Toggle lives under
     * Settings → Appearance → "Desktop Dual-Pane Layout". */

    /* #chats-content is the flex parent. We override both the `.tab-content`
     * default (`display: none`) and the `.tab-content.active` override
     * (`display: block`) so the dual-pane flex layout takes effect.
     * `overflow: hidden` ensures each child manages its own scroll rather
     * than inheriting the container's. */
    body.dual-pane-enabled #chats-content.tab-content,
    body.dual-pane-enabled #chats-content.tab-content.active {
        display: flex !important;
        flex-direction: row;
        gap: 0;
        overflow: hidden;
        padding: 12px;
        box-sizing: border-box;
        height: 100%;
    }

    /* Sidebar. Width driven by `--sidebar-width` (persisted in localStorage
     * and set on :root by _initDesktopLayout). `display: flex !important`
     * overrides the `.hidden` class that the single-column code path still
     * adds on room select; on desktop we keep both panels visible. */
    body.dual-pane-enabled #rooms-list-section,
    body.dual-pane-enabled #rooms-list-section.hidden {
        display: flex !important;
        flex: 0 0 var(--sidebar-width, 340px);
        width: var(--sidebar-width, 340px);
        min-width: 0;
        max-height: none;
        margin: 0;
        box-sizing: border-box;
        transition: flex-basis 0.18s ease, width 0.18s ease, padding 0.18s ease;
    }

    /* Resize handle. Vertical strip between sidebar and chat pane. The
     * `::before` pseudo draws the actual 1px line so we can thicken it on
     * hover/drag without changing the 8px hit target. `user-select: none`
     * so drag doesn't accidentally select text in the surrounding rows. */
    body.dual-pane-enabled .sidebar-resize-handle {
        display: flex;
        align-items: center;
        justify-content: center;
        flex: 0 0 8px;
        width: 8px;
        cursor: col-resize;
        position: relative;
        user-select: none;
        background: transparent;
        transition: background 0.15s;
    }
    body.dual-pane-enabled .sidebar-resize-handle::before {
        content: '';
        position: absolute;
        top: 0;
        bottom: 0;
        left: 50%;
        width: 1px;
        background: rgba(255, 255, 255, 0.08);
        transform: translateX(-50%);
        transition: background 0.15s, width 0.15s;
    }
    body.dual-pane-enabled .sidebar-resize-handle:hover::before,
    body.dual-pane-enabled .sidebar-resize-handle.dragging::before {
        background: var(--app-primary);
        width: 2px;
    }

    /* Embedded collapse/expand button. Hidden until the user hovers the
     * handle so it doesn't clutter the layout; always visible when the
     * sidebar is already collapsed (so the user can expand it back). */
    body.dual-pane-enabled .sidebar-collapse-btn {
        position: absolute;
        top: 50%;
        left: 50%;
        transform: translate(-50%, -50%);
        width: 22px;
        height: 42px;
        border-radius: 8px;
        border: 1px solid rgba(255, 255, 255, 0.12);
        background: var(--app-card-bg, #1e1e24);
        color: var(--app-text-primary, #eee);
        font-size: 12px;
        line-height: 1;
        cursor: pointer;
        padding: 0;
        display: flex;
        align-items: center;
        justify-content: center;
        opacity: 0;
        transition: opacity 0.15s, background 0.15s, transform 0.1s;
        z-index: 3;
    }
    body.dual-pane-enabled .sidebar-resize-handle:hover .sidebar-collapse-btn,
    body.dual-pane-enabled .sidebar-collapse-btn:focus-visible {
        opacity: 1;
    }
    body.dual-pane-enabled .sidebar-collapse-btn:hover {
        background: rgba(255, 255, 255, 0.08);
    }
    body.dual-pane-enabled .sidebar-collapse-btn:active {
        transform: translate(-50%, -50%) scale(0.94);
    }

    /* Chat pane. Fills the remaining width regardless of inline
     * `style="display: none"` set by the single-column code path. The
     * `[style*="display: none"]` attribute selectors cover both the with-
     * and without-space variants the code uses. `min-width: 0` is critical
     * for flex children whose content (chat bubbles) can be wider than
     * the available column. */
    body.dual-pane-enabled #room-content,
    body.dual-pane-enabled #room-content[style*="display: none"],
    body.dual-pane-enabled #room-content[style*="display:none"] {
        display: flex !important;
        flex-direction: column;
        flex: 1 1 auto;
        min-width: 0;
        height: 100%;
        margin: 0;
    }

    /* Empty state: fills the chat pane when no contact is selected.
     * selectRoom() adds `.has-room` to #room-content; its absence means
     * "no room open" so the empty state is visible and the header/body
     * are hidden. */
    body.dual-pane-enabled #room-content:not(.has-room) .room-header,
    body.dual-pane-enabled #room-content:not(.has-room) .room-body {
        display: none !important;
    }
    body.dual-pane-enabled #room-content:not(.has-room) .room-empty-state {
        display: flex;
        flex: 1 1 auto;
        align-items: stretch;
        justify-content: stretch;
        padding: 0;
        color: var(--app-text-secondary, #b8b8c0);
        text-align: center;
        position: relative;
        background: linear-gradient(180deg,
            rgba(255, 255, 255, 0.015) 0%,
            rgba(255, 255, 255, 0.0) 100%);
        overflow: hidden;
    }

    /* Faux chat-window placeholder. The empty state is structured as a
     * disabled chat surface: faux header strip at the top, centred
     * message in the middle, faux composer bar at the bottom. Filling
     * the right pane with this scaffold (instead of dropping a small
     * centred card into a 70%-empty void) makes the layout feel
     * coherent — the user sees what a real chat looks like even before
     * picking a contact. Pointer events are disabled so nothing in this
     * scaffold is clickable except the "Show contacts" affordance. */
    body.dual-pane-enabled .room-empty-state::before {
        content: '';
        position: absolute;
        top: 0;
        left: 0;
        right: 0;
        height: 56px;
        background: rgba(255, 255, 255, 0.025);
        border-bottom: 1px solid rgba(255, 255, 255, 0.05);
        pointer-events: none;
    }
    body.dual-pane-enabled .room-empty-state::after {
        content: '';
        position: absolute;
        bottom: 0;
        left: 0;
        right: 0;
        height: 64px;
        background: rgba(255, 255, 255, 0.025);
        border-top: 1px solid rgba(255, 255, 255, 0.05);
        pointer-events: none;
    }
    body.dual-pane-enabled .room-empty-state-content {
        max-width: 420px;
        position: relative;
        z-index: 1;
        margin: auto;
        padding: 24px;
    }
    body.dual-pane-enabled .room-empty-state-icon {
        font-size: 56px;
        margin-bottom: 12px;
        opacity: 0.7;
    }
    body.dual-pane-enabled .room-empty-state-content h3 {
        margin: 0 0 8px 0;
        color: var(--app-text-primary, #eee);
        font-size: 20px;
        font-weight: 600;
    }
    body.dual-pane-enabled .room-empty-state-content p {
        margin: 0 0 16px 0;
        font-size: 14px;
        line-height: 1.5;
        opacity: 0.85;
    }
    /* The "Show contacts" button inside the empty state is only useful
     * when the sidebar is collapsed (drag handle can't bring it back on
     * its own). Default-hidden; shown only when body.sidebar-collapsed. */
    body.dual-pane-enabled .room-empty-state-show-contacts {
        display: none;
    }
    body.dual-pane-enabled.sidebar-collapsed .room-empty-state-show-contacts {
        display: inline-flex;
    }

    /* Collapsed sidebar state. Width collapses to 0; the handle keeps a
     * slim 24px "peek" strip so the embedded expand button stays
     * clickable. We also flip the expand button to always-visible (no
     * hover requirement) because the user can't hover a 0-width panel. */
    body.dual-pane-enabled.sidebar-collapsed #rooms-list-section,
    body.dual-pane-enabled.sidebar-collapsed #rooms-list-section.hidden {
        flex-basis: 0 !important;
        width: 0 !important;
        min-width: 0 !important;
        padding-left: 0 !important;
        padding-right: 0 !important;
        overflow: hidden;
    }
    body.dual-pane-enabled.sidebar-collapsed .sidebar-resize-handle {
        cursor: default;
        flex-basis: 24px;
        width: 24px;
    }
    body.dual-pane-enabled.sidebar-collapsed .sidebar-resize-handle::before {
        display: none;
    }
    body.dual-pane-enabled.sidebar-collapsed .sidebar-collapse-btn {
        opacity: 1;
    }

    /* Selected-row highlight. Purely visual; all the selection state
     * lives on #room-content via the `.has-room` class + currentRoom. */
    body.dual-pane-enabled .room-item.selected {
        background: rgba(10, 132, 255, 0.12);
        outline: 1px solid rgba(10, 132, 255, 0.35);
    }

    /* Wider internal padding so the scrollbar doesn't hug the chat text.
     * The sidebar keeps its inner 20px padding from the global rule. */
    body.dual-pane-enabled #room-content .room-body {
        padding-right: 8px;
    }
}

/* =====================================================================
   CHANNELS (Jun 2026)
   ---------------------------------------------------------------------
   Per-group channel rail + creator-only management modal. The rail is
   a horizontal pill list pinned to the top of .chat-wrapper (above the
   chat-actions-toolbar), revealed by renderChannelRail() only when the
   user is viewing a group with channels OR is that group's creator
   (i.e. needs the "+" admin affordance even on an empty channel list).
   1:1 contacts never see this. The "main" pill always represents the
   parent group itself (currentRoom === parentGroupId); other pills
   represent member-scoped sub-channels (currentRoom === channel.id).
   Active pill is marked with .channel-pill-active so we can highlight
   the selected one. Falls back gracefully on narrow screens via the
   flex-wrap below — no horizontal scroll, the row just stacks.
   ===================================================================== */
.channel-rail {
    flex-shrink: 0;
    display: flex;
    align-items: center;
    gap: 8px;
    padding: 2px 10px;            /* v106: compact when collapsed */
    margin-bottom: 4px;           /* v106: tighter spacing when collapsed */
    background-color: var(--app-card-secondary);
    border-radius: 12px;
    border: 1px solid rgba(255, 255, 255, 0.08);

    /* v106 (Jun 2026) AUTO-COLLAPSE: see styles2.css for full rationale.
       Collapsed by default, expands on hover / focus-within / .is-expanded. */
    max-height: 14px;
    overflow: hidden;
    cursor: pointer;
    position: relative;
    transition: max-height 0.25s ease, padding 0.2s ease, margin-bottom 0.2s ease;
}

.channel-rail::before {
    content: '▾ Channels — hover or tap to expand';
    position: absolute;
    inset: 0;
    display: flex;
    align-items: center;
    justify-content: center;
    font-size: 10px;
    font-weight: 600;
    letter-spacing: 0.02em;
    color: var(--app-text-secondary);
    pointer-events: none;
    opacity: 1;
    transition: opacity 0.15s ease;
}

.channel-rail:hover,
.channel-rail:focus-within,
.channel-rail.is-expanded {
    max-height: 240px;
    padding: 6px 10px;
    margin-bottom: 8px;
    cursor: default;
}

.channel-rail:hover::before,
.channel-rail:focus-within::before,
.channel-rail.is-expanded::before {
    opacity: 0;
}

.channel-rail-list {
    list-style: none;
    margin: 0;
    padding: 0;
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: 6px;
    flex: 1 1 auto;
    min-width: 0;
}

.channel-pill {
    display: inline-flex;
    align-items: center;
    gap: 4px;
    padding: 5px 12px;
    border-radius: 999px;
    background-color: var(--app-card-bg);
    color: var(--app-text-primary);
    font-size: 13px;
    font-weight: 500;
    cursor: pointer;
    user-select: none;
    border: 1px solid transparent;
    transition: background-color 0.15s ease, color 0.15s ease, border-color 0.15s ease;
    max-width: 200px;
    overflow: hidden;
}

.channel-pill:hover {
    background-color: rgba(10, 132, 255, 0.12);
    border-color: rgba(10, 132, 255, 0.25);
}

.channel-pill:focus-visible {
    outline: 2px solid var(--app-primary);
    outline-offset: 2px;
}

.channel-pill-active {
    background-color: var(--app-primary);
    color: #ffffff;
    border-color: var(--app-primary);
}

.channel-pill-active:hover {
    background-color: var(--app-primary);
    color: #ffffff;
    /* keep the same blue on hover so the active state stays unambiguous */
}

.channel-pill-icon {
    opacity: 0.7;
    font-weight: 600;
}

.channel-pill-active .channel-pill-icon {
    opacity: 0.95;
}

.channel-pill-name {
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
    max-width: 160px;
}

.channel-pill-main .channel-pill-name {
    /* "main" reads better as italic so users immediately understand it
       represents the group itself, not a regular sub-channel. */
    font-style: italic;
}

.channel-rail-add-btn {
    flex-shrink: 0;
    width: 28px;
    height: 28px;
    border-radius: 50%;
    border: none;
    background-color: var(--app-primary);
    color: #ffffff;
    font-size: 18px;
    font-weight: 600;
    line-height: 1;
    cursor: pointer;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    transition: transform 0.15s ease, background-color 0.15s ease;
}

.channel-rail-add-btn:hover {
    background-color: #0a84ff;
    transform: scale(1.06);
}

.channel-rail-add-btn:focus-visible {
    outline: 2px solid #ffffff;
    outline-offset: 2px;
}

/* ---------- Channel management modal ---------- */
/* Inherits .modal / .modal-content from the existing modal infrastructure
   (see manageMembersModal as the sister pattern). Only adds the rules
   specific to the channel-management sub-elements. */

#channelManagementModal .channel-mgmt-empty {
    color: var(--app-text-secondary);
    font-style: italic;
    padding: 8px 4px;
}

#channelManagementModal .channel-mgmt-row {
    display: grid;
    grid-template-columns: 1fr auto auto auto;
    gap: 10px;
    align-items: center;
    padding: 10px 12px;
    margin-bottom: 6px;
    background-color: var(--app-card-secondary);
    border-radius: 10px;
}

#channelManagementModal .channel-mgmt-name {
    font-weight: 600;
    color: var(--app-text-primary);
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

#channelManagementModal .channel-mgmt-meta {
    color: var(--app-text-secondary);
    font-size: 12px;
}

#channelManagementModal .channel-mgmt-edit-btn,
#channelManagementModal .channel-mgmt-delete-btn,
#channelManagementModal .channel-mgmt-create-btn {
    border: none;
    border-radius: 8px;
    padding: 6px 12px;
    font-size: 13px;
    font-weight: 500;
    cursor: pointer;
    transition: opacity 0.15s ease, background-color 0.15s ease;
}

#channelManagementModal .channel-mgmt-edit-btn {
    background-color: rgba(10, 132, 255, 0.18);
    color: var(--app-primary);
}

#channelManagementModal .channel-mgmt-edit-btn:hover {
    background-color: rgba(10, 132, 255, 0.28);
}

#channelManagementModal .channel-mgmt-delete-btn {
    background-color: rgba(239, 68, 68, 0.18);
    color: #ef4444;
}

#channelManagementModal .channel-mgmt-delete-btn:hover {
    background-color: rgba(239, 68, 68, 0.28);
}

#channelManagementModal .channel-mgmt-create {
    display: flex;
    flex-direction: column;
    gap: 10px;
}

#channelManagementModal .channel-mgmt-name-input {
    width: 100%;
    padding: 10px 12px;
    border-radius: 10px;
    border: 1px solid rgba(255, 255, 255, 0.12);
    background-color: var(--app-card-secondary);
    color: var(--app-text-primary);
    font-size: 14px;
    box-sizing: border-box;
}

#channelManagementModal .channel-mgmt-name-input:focus {
    outline: none;
    border-color: var(--app-primary);
    box-shadow: 0 0 0 2px rgba(10, 132, 255, 0.25);
}

#channelManagementModal .channel-mgmt-member-label {
    font-weight: 600;
    color: var(--app-text-primary);
    font-size: 13px;
}

#channelManagementModal .channel-mgmt-member-list {
    max-height: 25vh;
    overflow-y: auto;
    background-color: var(--app-card-secondary);
    border-radius: 10px;
    padding: 8px 10px;
    display: flex;
    flex-direction: column;
    gap: 4px;
}

#channelManagementModal .channel-mgmt-member-row {
    display: flex;
    align-items: center;
    gap: 8px;
    padding: 4px 2px;
    cursor: pointer;
    color: var(--app-text-primary);
    font-size: 13px;
}

#channelManagementModal .channel-mgmt-member-row input[type="checkbox"] {
    flex-shrink: 0;
    cursor: pointer;
}

#channelManagementModal .channel-mgmt-create-btn {
    background-color: var(--app-primary);
    color: #ffffff;
    padding: 10px 16px;
    align-self: flex-end;
}

#channelManagementModal .channel-mgmt-create-btn:hover {
    opacity: 0.9;
}

/* Mobile: stack the management rows so the buttons don't get cramped.
   Below 480px the grid columns become too tight for the action buttons
   to keep their padding without crowding the channel name; switch to
   a vertical layout with the actions wrapping below the name. */
@media (max-width: 480px) {
    #channelManagementModal .channel-mgmt-row {
        grid-template-columns: 1fr;
        grid-auto-flow: row;
        gap: 6px;
    }
    #channelManagementModal .channel-mgmt-edit-btn,
    #channelManagementModal .channel-mgmt-delete-btn {
        justify-self: start;
    }
}

/* Channel-mgmt member editor overlay (June 2026 fix for Issue #4)
   ----------------------------------------------------------------
   The "Members" button inside the channel-management modal opens this
   secondary editor. It MUST sit visually above the parent modal
   (#channelManagementModal uses .modal -> z-index: 10500). Without
   these rules the overlay rendered inline at body position 0,0
   beneath the parent modal — clicking Members appeared to do nothing
   and the overlays silently piled up. We give the overlay its own
   fixed-position backdrop at z-index 10600 (above .modal but still
   below the call fullscreen overlay at 100000), and centre an inner
   .channel-mgmt-member-editor card with the same look-and-feel as
   the parent modal so the two read as a single dialog stack. */
.channel-mgmt-member-editor-overlay {
    position: fixed;
    inset: 0;
    background: rgba(0, 0, 0, 0.6);
    z-index: 10600;
    display: flex;
    align-items: center;
    justify-content: center;
    padding: 20px;
    box-sizing: border-box;
    -webkit-backdrop-filter: blur(2px);
    backdrop-filter: blur(2px);
    isolation: isolate;
}

.channel-mgmt-member-editor {
    background-color: var(--app-card, #1c1c1e);
    border: 1px solid rgba(255, 255, 255, 0.1);
    border-radius: 14px;
    box-shadow: 0 12px 40px rgba(0, 0, 0, 0.6);
    padding: 18px;
    width: 100%;
    max-width: 420px;
    max-height: 80vh;
    overflow-y: auto;
    display: flex;
    flex-direction: column;
    gap: 12px;
    color: var(--app-text-primary, #fff);
}

.channel-mgmt-member-editor h3 {
    margin: 0;
    font-size: 16px;
    font-weight: 600;
}

.channel-mgmt-member-editor .channel-mgmt-member-list {
    background-color: var(--app-card-secondary, #2c2c2e);
    border-radius: 10px;
    padding: 8px;
    max-height: 45vh;
    overflow-y: auto;
    display: flex;
    flex-direction: column;
    gap: 4px;
}

.channel-mgmt-member-editor-actions {
    display: flex;
    justify-content: flex-end;
    gap: 8px;
    margin-top: 4px;
}
