/* ==========================================================================
   BosHub — Prototype stylesheet
   UI/layout only, mock data, no external dependencies.
   ========================================================================== */

/* -------------------------------------------------------------------------
   1. Reset & base
   ------------------------------------------------------------------------- */
*, *::before, *::after { box-sizing: border-box; }
html, body { height: 100%; }
/* Any element styled with an explicit `display` (buttons, flex/inline-block
   containers, etc.) otherwise wins over the browser's default [hidden]
   rule, since author styles beat user-agent styles regardless of
   specificity. Restore the expected "hidden means hidden" behavior everywhere. */
[hidden] { display: none !important; }
body {
    margin: 0;
    font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Helvetica, Arial, sans-serif;
    background: var(--bg);
    color: var(--text);
    font-size: 15px;
    line-height: 1.5;
    -webkit-font-smoothing: antialiased;
    /* Inherited by every descendant: a long unbroken string (URL, pasted
       gibberish, long BOS ID) wraps inside its container instead of
       forcing horizontal overflow. Elements that intentionally truncate
       (white-space: nowrap + ellipsis) are unaffected — nowrap wins. */
    overflow-wrap: break-word;
}
img { max-width: 100%; display: block; }
a { color: inherit; text-decoration: none; }
button { font: inherit; cursor: pointer; }
input, textarea, button { font-family: inherit; }
ul { margin: 0; padding: 0; list-style: none; }
h1, h2, h3, p { margin: 0; }

/* -------------------------------------------------------------------------
   2. Design tokens
   ------------------------------------------------------------------------- */
:root {
    --bg: #f5f6f9;
    --surface: #ffffff;
    --border: #e6e8ec;
    --text: #1c2029;
    --text-muted: #6b7280;
    --text-faint: #9aa1ac;

    --primary: #4f5fe0;
    --primary-hover: #4351c9;
    --primary-soft: #eef0fd;

    --online: #22c55e;
    --online-soft: #e7f7ec;
    --offline: #b0b5bd;
    --danger: #e0504f;
    --danger-soft: #fbeaea;
    --warning: #d99a2b;
    --warning-soft: #fbf1de;

    --radius-sm: 8px;
    --radius-md: 12px;
    --radius-lg: 16px;

    --avatar-c1: #6d7ce8;
    --avatar-c2: #4fb0a8;
    --avatar-c3: #dd8a4b;
    --avatar-c4: #c76a9c;
    --avatar-c5: #5b9bd9;
    --avatar-c6: #7bab5a;

    --sidebar-w: 232px;
}

/* -------------------------------------------------------------------------
   3. App shell / layout
   ------------------------------------------------------------------------- */
.app-shell { display: flex; min-height: 100vh; }

.sidebar {
    width: var(--sidebar-w);
    flex-shrink: 0;
    background: var(--surface);
    border-right: 1px solid var(--border);
    position: fixed;
    top: 0; left: 0; bottom: 0;
    display: flex;
    flex-direction: column;
    padding: 18px 12px;
    z-index: 30;
}

.sidebar-brand {
    display: flex;
    align-items: center;
    gap: 10px;
    padding: 6px 10px 20px;
}
.sidebar-brand-mark {
    width: 30px; height: 30px;
    border-radius: 9px;
    background: var(--primary);
    color: #fff;
    display: flex; align-items: center; justify-content: center;
    font-weight: 700;
    font-size: 15px;
    flex-shrink: 0;
}
.sidebar-brand-text { font-weight: 700; font-size: 16.5px; letter-spacing: -0.01em; }

.sidebar-nav { display: flex; flex-direction: column; gap: 2px; flex: 1; }

.nav-item {
    display: flex;
    align-items: center;
    gap: 12px;
    padding: 9px 12px;
    border-radius: var(--radius-sm);
    color: var(--text-muted);
    font-size: 14.5px;
    font-weight: 500;
}
.nav-item:hover { background: #f2f3f7; color: var(--text); }
.nav-item.active { background: var(--primary-soft); color: var(--primary); }
.nav-item-icon { width: 19px; height: 19px; flex-shrink: 0; }

.sidebar-user {
    display: flex;
    align-items: center;
    gap: 10px;
    padding: 12px 10px 6px;
    border-top: 1px solid var(--border);
    margin-top: 8px;
}
.sidebar-user-info { display: flex; flex-direction: column; min-width: 0; }
.sidebar-user-name {
    font-size: 13.5px; font-weight: 600;
    white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
.sidebar-user-id { font-size: 12px; color: var(--text-faint); }

.app-main {
    margin-left: var(--sidebar-w);
    width: calc(100% - var(--sidebar-w));
    display: flex;
    flex-direction: column;
    min-height: 100vh;
}

.topbar {
    height: 58px;
    flex-shrink: 0;
    background: var(--surface);
    border-bottom: 1px solid var(--border);
    display: flex;
    align-items: center;
    justify-content: space-between;
    padding: 0 24px;
    position: sticky;
    top: 0;
    z-index: 20;
}
.topbar-left { display: flex; align-items: center; gap: 10px; }
.topbar-brand-mark { display: none; }
.topbar-title { font-size: 16.5px; font-weight: 700; letter-spacing: -0.01em; }
.topbar-right { display: flex; align-items: center; gap: 14px; }
.topbar-online {
    display: flex; align-items: center; gap: 6px;
    font-size: 13px; color: var(--text-muted); font-weight: 500;
}
.topbar-avatar-link { display: flex; }

.app-content {
    flex: 1;
    padding: 24px;
    max-width: 900px;
    width: 100%;
    margin: 0 auto;
}
.app-content--wide { max-width: 1100px; }
.app-content--nopad { padding: 0; max-width: none; }

.bottom-nav {
    display: none;
    position: fixed;
    bottom: 0; left: 0; right: 0;
    background: var(--surface);
    border-top: 1px solid var(--border);
    z-index: 40;
    padding-bottom: env(safe-area-inset-bottom, 0);
}
.bottom-nav-item {
    flex: 1;
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: 3px;
    padding: 9px 4px 8px;
    font-size: 11px;
    font-weight: 500;
    color: var(--text-faint);
}
.bottom-nav-item.active { color: var(--primary); }
.bottom-nav-icon { width: 21px; height: 21px; }

/* -------------------------------------------------------------------------
   4. Auth shell (login / register / account-status)
   ------------------------------------------------------------------------- */
.auth-page {
    min-height: 100vh;
    display: flex;
    align-items: center;
    justify-content: center;
    background: var(--bg);
    padding: 24px;
}
.auth-card {
    width: 100%;
    max-width: 380px;
    background: var(--surface);
    border: 1px solid var(--border);
    border-radius: var(--radius-lg);
    padding: 32px 30px;
}
.auth-card + .auth-card { margin-top: 20px; }
.auth-brand {
    display: flex;
    align-items: center;
    gap: 10px;
    justify-content: center;
    margin-bottom: 22px;
}
.auth-title { font-size: 19px; font-weight: 700; text-align: center; margin-bottom: 4px; }
.auth-subtitle { font-size: 13.5px; color: var(--text-muted); text-align: center; margin-bottom: 24px; }
.auth-footer { text-align: center; font-size: 13.5px; color: var(--text-muted); margin-top: 18px; }
.auth-footer a { color: var(--primary); font-weight: 600; }
.auth-wrap { max-width: 420px; width: 100%; }
.auth-status-label {
    font-size: 12px; font-weight: 600; letter-spacing: .04em; text-transform: uppercase;
    color: var(--text-faint); margin: 0 0 10px 2px;
}

/* -------------------------------------------------------------------------
   5. Form elements
   ------------------------------------------------------------------------- */
.field { margin-bottom: 16px; }
.field label {
    display: block;
    font-size: 13px;
    font-weight: 600;
    margin-bottom: 6px;
}
.field input,
.field textarea,
.field select {
    width: 100%;
    border: 1px solid var(--border);
    border-radius: var(--radius-sm);
    padding: 10px 12px;
    font-size: 14px;
    background: #fbfbfc;
    color: var(--text);
}
.field input:focus,
.field textarea:focus,
.field select:focus {
    outline: none;
    border-color: var(--primary);
    background: var(--surface);
}
.field textarea { resize: vertical; min-height: 80px; }
.field-help { font-size: 12px; color: var(--text-faint); margin-top: 5px; }
.field-counter { font-size: 12px; color: var(--text-faint); margin-top: 5px; text-align: right; }
.field-counter.is-near-limit { color: var(--warning); }

.btn {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    gap: 8px;
    border: 1px solid transparent;
    border-radius: var(--radius-sm);
    padding: 9px 16px;
    font-size: 14px;
    font-weight: 600;
    background: var(--surface);
    color: var(--text);
    border-color: var(--border);
}
.btn:hover { background: #f2f3f7; }
.btn-primary { background: var(--primary); color: #fff; border-color: var(--primary); }
.btn-primary:hover { background: var(--primary-hover); }
.btn-block { width: 100%; }
.btn-sm { padding: 6px 12px; font-size: 13px; }
.btn-danger { color: var(--danger); border-color: var(--danger-soft); background: var(--danger-soft); }
.btn-danger:hover { background: #f6dcdb; }
.btn-icon { padding: 8px; border-radius: 50%; }
.btn-icon svg { width: 18px; height: 18px; }
.btn:disabled { opacity: .5; cursor: not-allowed; }

/* -------------------------------------------------------------------------
   6. Avatars & status dots
   ------------------------------------------------------------------------- */
.avatar {
    position: relative;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    border-radius: 50%;
    color: #fff;
    font-weight: 700;
    flex-shrink: 0;
    letter-spacing: -0.02em;
}
.avatar-sm { width: 32px; height: 32px; font-size: 12.5px; }
.avatar-md { width: 40px; height: 40px; font-size: 14px; }
.avatar-lg { width: 56px; height: 56px; font-size: 18px; }
.avatar-xl { width: 84px; height: 84px; font-size: 26px; }

.avatar-c1 { background: var(--avatar-c1); }
.avatar-c2 { background: var(--avatar-c2); }
.avatar-c3 { background: var(--avatar-c3); }
.avatar-c4 { background: var(--avatar-c4); }
.avatar-c5 { background: var(--avatar-c5); }
.avatar-c6 { background: var(--avatar-c6); }

.status-dot { width: 8px; height: 8px; border-radius: 50%; display: inline-block; flex-shrink: 0; }
.status-dot--online { background: var(--online); }
.status-dot--offline { background: var(--offline); }
.status-dot--corner {
    position: absolute;
    right: -1px; bottom: -1px;
    border: 2px solid var(--surface);
    width: 11px; height: 11px;
}

.room-icon {
    width: 40px; height: 40px;
    border-radius: var(--radius-sm);
    display: flex; align-items: center; justify-content: center;
    color: #fff; font-weight: 700; font-size: 13px;
    flex-shrink: 0;
}
.room-icon-sm { width: 36px; height: 36px; border-radius: 10px; font-size: 12px; }

/* -------------------------------------------------------------------------
   7. Cards (generic)
   ------------------------------------------------------------------------- */
.card {
    background: var(--surface);
    border: 1px solid var(--border);
    border-radius: var(--radius-md);
    padding: 18px;
}
.card + .card { margin-top: 14px; }
.section-title {
    font-size: 13px;
    font-weight: 700;
    text-transform: uppercase;
    letter-spacing: .04em;
    color: var(--text-faint);
    margin: 26px 0 12px;
}
.section-title:first-child { margin-top: 0; }

/* -------------------------------------------------------------------------
   8. Home — composer & posts
   ------------------------------------------------------------------------- */
.composer {
    background: var(--surface);
    border: 1px solid var(--border);
    border-radius: var(--radius-lg);
    padding: 14px 16px;
    margin-bottom: 18px;
}
.composer-row { display: flex; align-items: center; gap: 12px; }
.composer-fake-input {
    flex: 1;
    background: var(--bg);
    border: 1px solid var(--border);
    border-radius: 999px;
    padding: 10px 16px;
    color: var(--text-faint);
    font-size: 14px;
}
.composer-textarea {
    flex: 1;
    /* A <textarea>'s automatic flex min-width is its intrinsic content
       size, not 0 — without this it resists shrinking to fit next to the
       avatar and can force the row (and the card) wider than the
       viewport on narrow phones. */
    min-width: 0;
    width: 100%;
    background: var(--bg);
    border: 1px solid var(--border);
    border-radius: var(--radius-md);
    padding: 10px 16px;
    color: var(--text);
    font-size: 14px;
    font-family: inherit;
    resize: none;
    min-height: 42px;
    max-height: 220px;
    line-height: 1.45;
}
.composer-textarea:focus { outline: none; border-color: var(--primary); background: var(--surface); }
.composer-textarea::placeholder { color: var(--text-faint); }
.composer-image-preview { position: relative; margin-top: 12px; display: inline-block; }
.composer-image-preview img {
    max-height: 160px;
    max-width: 100%;
    border-radius: var(--radius-md);
    border: 1px solid var(--border);
    display: block;
}
.composer-image-preview .btn-icon {
    position: absolute;
    top: 6px;
    right: 6px;
    background: rgba(17, 20, 28, .55);
    color: #fff;
    border: none;
}
/* Two groups (Photo/Announcement on the left, counter/Post on the right)
   that share one row whenever there's room, and wrap onto their own row
   otherwise — replaces the old single-line flex + spacer, which had no
   way to keep "Photo + Announcement" and "counter + Post" together as
   units once things got tight on narrow phones. */
.composer-actions {
    display: flex;
    align-items: center;
    flex-wrap: wrap;
    row-gap: 10px;
    column-gap: 12px;
    margin-top: 12px;
    padding-top: 12px;
    border-top: 1px solid var(--border);
}
.composer-actions-left {
    display: flex;
    align-items: center;
    flex-wrap: wrap;
    gap: 6px;
    min-width: 0;
}
.composer-actions-right {
    display: flex;
    align-items: center;
    gap: 10px;
    margin-left: auto;
    flex-shrink: 0;
}
.composer-action {
    display: flex;
    align-items: center;
    gap: 7px;
    padding: 7px 12px;
    border-radius: var(--radius-sm);
    font-size: 13px;
    font-weight: 600;
    color: var(--text-muted);
    border: 1px solid transparent;
    cursor: pointer;
}
.composer-action:hover { background: var(--bg); }
.composer-action svg { width: 17px; height: 17px; }

/* -------------------------------------------------------------------------
   Emoji picker (insert-only) — Post Composer, Comment form, Chat composer.
   One shared popup element (see emoji.js), positioned near whichever
   trigger button opened it; sized with min()/auto-fill so it can never
   overflow the viewport or force horizontal scroll on mobile.
   ------------------------------------------------------------------------- */
.emoji-trigger { font-size: 16px; line-height: 1; }
.emoji-picker {
    position: fixed;
    z-index: 60;
    width: min(272px, calc(100vw - 16px));
    max-height: 224px;
    overflow-y: auto;
    overscroll-behavior: contain;
    background: var(--surface);
    border: 1px solid var(--border);
    border-radius: var(--radius-md);
    box-shadow: 0 8px 24px rgba(20, 22, 30, .16);
    padding: 8px;
}
.emoji-picker-grid {
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(36px, 1fr));
    gap: 2px;
}
.emoji-picker-option {
    display: flex;
    align-items: center;
    justify-content: center;
    width: 100%;
    aspect-ratio: 1;
    font-size: 19px;
    line-height: 1;
    border-radius: var(--radius-sm);
    border: 1px solid transparent;
    background: transparent;
    cursor: pointer;
}
.emoji-picker-option:hover { background: var(--bg); }

.timeline-tabs {
    display: flex;
    gap: 18px;
    margin-bottom: 16px;
    border-bottom: 1px solid var(--border);
}
.timeline-tab {
    padding: 10px 2px;
    font-size: 14px;
    font-weight: 600;
    color: var(--text-faint);
    border: none;
    background: none;
    border-bottom: 2px solid transparent;
    margin-bottom: -1px;
}
.timeline-tab:hover { color: var(--text-muted); }
.timeline-tab.active { color: var(--primary); border-bottom-color: var(--primary); }

.post { border-radius: var(--radius-lg); }
.post-announcement {
    border-color: var(--primary-soft);
    background: var(--primary-soft);
}
.post-head { display: flex; align-items: flex-start; gap: 12px; }
.post-head-info { flex: 1; min-width: 0; }
.post-author-row { display: flex; align-items: center; gap: 7px; flex-wrap: wrap; }
.post-author { font-weight: 700; font-size: 14.5px; }
.post-author-id { color: var(--text-faint); font-size: 13px; }
.post-time { color: var(--text-faint); font-size: 12.5px; margin-top: 1px; }
.badge {
    display: inline-flex;
    align-items: center;
    font-size: 11px;
    font-weight: 700;
    text-transform: uppercase;
    letter-spacing: .03em;
    padding: 2px 8px;
    border-radius: 999px;
}
.badge-announcement { background: var(--primary); color: #fff; }
.badge-pending { background: var(--warning-soft); color: var(--warning); }
.badge-approved { background: var(--online-soft); color: var(--online); }
.badge-rejected { background: var(--danger-soft); color: var(--danger); }
.badge-disabled { background: var(--bg); color: var(--text-faint); }
.badge-unread {
    background: var(--primary);
    color: #fff;
    font-size: 11px;
    font-weight: 700;
    min-width: 18px;
    height: 18px;
    border-radius: 999px;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    padding: 0 5px;
}

.post-body { font-size: 14.5px; line-height: 1.55; margin: 10px 0 0; }
.post-image {
    margin-top: 12px;
    border-radius: var(--radius-md);
    aspect-ratio: 16/9;
    background: repeating-linear-gradient(135deg, #eef0f4, #eef0f4 10px, #e6e9ef 10px, #e6e9ef 20px);
    display: flex;
    align-items: center;
    justify-content: center;
    color: var(--text-faint);
    gap: 8px;
    font-size: 13px;
    font-weight: 500;
    border: 1px solid var(--border);
}
.post-image svg { width: 22px; height: 22px; }
.post-image-real {
    margin-top: 12px;
    width: 100%;
    max-height: 480px;
    object-fit: cover;
    border-radius: var(--radius-md);
    border: 1px solid var(--border);
    display: block;
}
/* Timeline: cropped compact preview so tall/portrait images don't stretch the feed. */
.post-image-crop {
    margin-top: 12px;
    width: 100%;
    height: 240px;
    object-fit: cover;
    border-radius: var(--radius-md);
    border: 1px solid var(--border);
    display: block;
}
/* Post Detail: full image, aspect ratio preserved, nothing cropped. */
.post-image-full {
    margin-top: 12px;
    max-width: 100%;
    max-height: 80vh;
    width: auto;
    height: auto;
    object-fit: contain;
    border-radius: var(--radius-md);
    border: 1px solid var(--border);
    display: block;
    margin-left: auto;
    margin-right: auto;
}
.post-detail-link { display: block; }
.post-detail-link:hover .post-body { color: var(--text); }

.post-footer {
    display: flex;
    align-items: center;
    gap: 6px;
    margin-top: 12px;
    padding-top: 10px;
    border-top: 1px solid var(--border);
    font-size: 13px;
    color: var(--text-muted);
}
.post-footer svg { width: 16px; height: 16px; }
.post-footer-link:hover { color: var(--text); }
.post-comments { margin-top: 12px; display: flex; flex-direction: column; gap: 10px; }
.post-comment { display: flex; gap: 10px; align-items: flex-start; }
.post-comment-bubble {
    background: var(--bg);
    border-radius: var(--radius-md);
    padding: 8px 12px;
    font-size: 13.5px;
    flex: 1;
    min-width: 0;
}
.post-comment-meta { display: flex; align-items: baseline; gap: 8px; margin-bottom: 2px; }
.post-comment-author { font-weight: 700; }
.post-comment-time { font-size: 11.5px; color: var(--text-faint); }
.comment-refresh-hint { margin-top: 10px; }
.comment-form {
    display: flex;
    align-items: center;
    gap: 10px;
    margin-top: 12px;
}
.comment-form input {
    flex: 1;
    border: 1px solid var(--border);
    background: var(--bg);
    border-radius: 999px;
    padding: 8px 14px;
    font-size: 13.5px;
    outline: none;
}
.comment-form input:focus { border-color: var(--primary); background: var(--surface); }

/* -------------------------------------------------------------------------
   9. People
   ------------------------------------------------------------------------- */
.search-box {
    display: flex;
    align-items: center;
    gap: 10px;
    background: var(--surface);
    border: 1px solid var(--border);
    border-radius: var(--radius-md);
    padding: 10px 14px;
    margin-bottom: 20px;
    color: var(--text-faint);
}
.search-box svg { width: 18px; height: 18px; flex-shrink: 0; }
.search-box input {
    border: none;
    outline: none;
    background: none;
    font-size: 14px;
    width: 100%;
    color: var(--text);
}

.people-grid {
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(240px, 1fr));
    gap: 12px;
}
.people-card {
    background: var(--surface);
    border: 1px solid var(--border);
    border-radius: var(--radius-md);
    padding: 16px;
    display: flex;
    gap: 12px;
    align-items: flex-start;
}
.people-card:hover { border-color: #d6d9e0; }
.people-card-info { min-width: 0; flex: 1; }
.people-card-name { font-weight: 700; font-size: 14.5px; }
.people-card-id { font-size: 12.5px; color: var(--text-faint); margin-top: 1px; }
.people-card-bio {
    font-size: 13px;
    color: var(--text-muted);
    margin-top: 6px;
    line-height: 1.4;
}
.people-card-status {
    display: flex; align-items: center; gap: 6px;
    font-size: 12px; font-weight: 600; margin-top: 8px;
}
.people-card-status.is-online { color: var(--online); }
.people-card-status.is-offline { color: var(--text-faint); }

/* -------------------------------------------------------------------------
   10. Chat
   ------------------------------------------------------------------------- */
.chat-layout {
    display: flex;
    height: calc(100vh - 58px);
    /* Modern viewport unit accounts for mobile browser chrome (address
       bar) so the composer never ends up hidden below the fold. Browsers
       that don't understand 100dvh simply drop this whole declaration and
       keep the vh value above — no @supports needed. */
    height: calc(100dvh - 58px);
}
.chat-list {
    width: 320px;
    flex-shrink: 0;
    border-right: 1px solid var(--border);
    overflow-y: auto;
    background: var(--surface);
}
.chat-list-search { padding: 14px; border-bottom: 1px solid var(--border); }
.chat-list-search .search-box { margin-bottom: 0; }

.conv-item {
    display: flex;
    align-items: center;
    gap: 12px;
    padding: 12px 16px;
    border-bottom: 1px solid #f1f2f5;
}
.conv-item:hover, .conv-item.active { background: var(--bg); }
.conv-item.active { box-shadow: inset 3px 0 0 var(--primary); }
.conv-item-body { min-width: 0; flex: 1; }
.conv-item-top { display: flex; justify-content: space-between; align-items: baseline; gap: 8px; }
.conv-item-name { font-weight: 700; font-size: 14px; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.conv-item-time { font-size: 11.5px; color: var(--text-faint); flex-shrink: 0; }
.conv-item-preview {
    font-size: 13px;
    color: var(--text-muted);
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
    margin-top: 2px;
    max-width: 100%;
}
.conv-item-bottom { display: flex; justify-content: space-between; align-items: center; gap: 6px; margin-top: 2px; }

.chat-panel {
    flex: 1;
    display: flex;
    flex-direction: column;
    min-width: 0;
    background: var(--bg);
}
.chat-panel-header {
    height: 62px;
    flex-shrink: 0;
    display: flex;
    align-items: center;
    gap: 12px;
    padding: 0 18px;
    border-bottom: 1px solid var(--border);
    background: var(--surface);
}
.chat-panel-header-info { min-width: 0; }
.chat-panel-header-name { font-weight: 700; font-size: 14.5px; }
.chat-panel-header-sub { font-size: 12.5px; color: var(--text-faint); }
.chat-back { display: none; }

.chat-messages {
    flex: 1;
    overflow-y: auto;
    overscroll-behavior: contain;
    padding: 22px;
    display: flex;
    flex-direction: column;
    gap: 4px;
}
.msg-row { display: flex; margin-bottom: 8px; }
.msg-row.is-out { justify-content: flex-end; }
.bubble {
    max-width: 62%;
    padding: 10px 14px;
    border-radius: 16px;
    font-size: 14px;
    line-height: 1.45;
}
.msg-row.is-in .bubble {
    background: var(--surface);
    border: 1px solid var(--border);
    border-bottom-left-radius: 4px;
}
.msg-row.is-out .bubble {
    background: var(--primary);
    color: #fff;
    border-bottom-right-radius: 4px;
}
.chat-date-separator {
    display: flex;
    align-items: center;
    justify-content: center;
    margin: 6px 0 14px;
}
.chat-date-separator span {
    background: var(--surface);
    border: 1px solid var(--border);
    color: var(--text-faint);
    font-size: 11.5px;
    font-weight: 700;
    padding: 4px 12px;
    border-radius: 999px;
}
.bubble-sender {
    display: block;
    font-size: 11px;
    font-weight: 700;
    color: var(--primary);
    margin-bottom: 3px;
}
.bubble-time {
    display: block;
    font-size: 10.5px;
    margin-top: 5px;
    opacity: .65;
}
/* Private Chat read receipt ("Dibaca") — sits next to the timestamp on the
   same line so the bubble never grows taller than a normal bubble. Only
   ever used on the one own-message currently marked as read (see
   includes/chat.php::render_chat_message_html and chat.js::applyReadReceipt). */
.bubble-meta {
    display: flex;
    align-items: center;
    gap: 6px;
    margin-top: 5px;
}
.bubble-meta .bubble-time {
    margin-top: 0;
}
.bubble-read {
    font-size: 10.5px;
    opacity: .65;
}
.bubble-image {
    width: 220px;
    max-width: 100%;
    aspect-ratio: 4/3;
    border-radius: 10px;
    background: repeating-linear-gradient(135deg, #eef0f4, #eef0f4 10px, #e6e9ef 10px, #e6e9ef 20px);
    display: flex;
    align-items: center;
    justify-content: center;
    color: var(--text-faint);
    margin-bottom: 4px;
}
.msg-row.is-in .bubble-image { border: 1px solid var(--border); }
.bubble-image svg { width: 26px; height: 26px; }
.bubble-file {
    display: flex;
    align-items: center;
    gap: 10px;
    background: rgba(255,255,255,.12);
    border-radius: 10px;
    padding: 8px 10px;
}
.msg-row.is-in .bubble-file { background: var(--bg); }
/* The name+size wrapper is the only shrinkable flex child here (the icon
   has flex-shrink:0) — without min-width:0 a long original filename would
   push the bubble (and the page) wider instead of wrapping. */
.bubble-file > span:last-child { min-width: 0; }
.bubble-file-icon {
    width: 34px; height: 34px;
    border-radius: 8px;
    background: var(--danger);
    color: #fff;
    display: flex; align-items: center; justify-content: center;
    flex-shrink: 0;
}
.bubble-file-icon svg { width: 18px; height: 18px; }
.bubble-file-name { font-size: 13px; font-weight: 600; }
.bubble-file-size { font-size: 11.5px; opacity: .75; }

.chat-composer-wrap {
    flex-shrink: 0;
    border-top: 1px solid var(--border);
    background: var(--surface);
    padding-top: 10px;
}
.chat-composer-wrap .composer-image-preview,
.chat-composer-wrap .chat-file-preview { margin: 0 16px 10px; }
.chat-composer-wrap .chat-composer { border-top: none; padding-top: 0; }

.chat-file-preview {
    display: flex;
    align-items: center;
    gap: 10px;
    background: var(--bg);
    border: 1px solid var(--border);
    border-radius: var(--radius-md);
    padding: 8px 10px;
}
.chat-file-preview-info { flex: 1; min-width: 0; }
.chat-file-preview .btn-icon { margin-left: auto; flex-shrink: 0; }

.bubble-image-real {
    display: block;
    max-width: 240px;
    max-height: 240px;
    border-radius: 10px;
    cursor: pointer;
    object-fit: cover;
    margin-bottom: 4px;
}

.chat-composer {
    flex-shrink: 0;
    display: flex;
    align-items: center;
    gap: 10px;
    padding: 12px 16px;
    border-top: 1px solid var(--border);
    background: var(--surface);
}
.chat-composer input {
    flex: 1;
    border: 1px solid var(--border);
    background: var(--bg);
    border-radius: 999px;
    padding: 10px 16px;
    font-size: 14px;
    outline: none;
}
.chat-composer input:focus { border-color: var(--primary); background: var(--surface); }
.chat-send-btn {
    background: var(--primary);
    color: #fff;
    border-color: var(--primary);
}
.chat-send-btn:hover { background: var(--primary-hover); }

.chat-empty-state {
    flex: 1;
    display: flex;
    align-items: center;
    justify-content: center;
    color: var(--text-faint);
    font-size: 14px;
    flex-direction: column;
    gap: 10px;
}

/* -------------------------------------------------------------------------
   11. Profile
   ------------------------------------------------------------------------- */
.profile-header {
    display: flex;
    gap: 20px;
    align-items: center;
}
.profile-info { flex: 1; min-width: 0; }
.profile-name-row { display: flex; align-items: center; gap: 10px; flex-wrap: wrap; }
.profile-name { font-size: 20px; font-weight: 700; }
.profile-id { color: var(--text-faint); font-size: 14px; margin-top: 2px; }
.profile-status { display: flex; align-items: center; gap: 6px; font-size: 13px; font-weight: 600; margin-top: 8px; }
.profile-status.is-online { color: var(--online); }
.profile-status.is-offline { color: var(--text-faint); }
.profile-bio { margin-top: 10px; font-size: 14px; color: var(--text-muted); max-width: 480px; }
.profile-actions { display: flex; gap: 10px; margin-top: 16px; flex-wrap: wrap; }
.profile-extra-link {
    display: flex;
    align-items: center;
    gap: 10px;
    padding: 12px 14px;
    border: 1px solid var(--border);
    border-radius: var(--radius-md);
    margin-top: 10px;
    font-size: 13.5px;
    font-weight: 600;
    color: var(--text-muted);
    background: var(--surface);
}
.profile-extra-link:hover { background: var(--bg); }
.profile-extra-link svg { width: 18px; height: 18px; }

/* -------------------------------------------------------------------------
   12. Admin
   ------------------------------------------------------------------------- */
.admin-layout { display: flex; gap: 24px; align-items: flex-start; }
.admin-subnav {
    width: 190px;
    flex-shrink: 0;
    display: flex;
    flex-direction: column;
    gap: 2px;
    position: sticky;
    top: 82px;
}
.admin-subnav a {
    padding: 9px 12px;
    border-radius: var(--radius-sm);
    font-size: 13.5px;
    font-weight: 600;
    color: var(--text-muted);
}
.admin-subnav a:hover { background: var(--surface); }
.admin-subnav a.active { background: var(--surface); color: var(--primary); border: 1px solid var(--border); }
.admin-content { flex: 1; min-width: 0; }

.stat-grid {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(160px, 1fr));
    gap: 12px;
    margin-bottom: 22px;
}
.stat-card {
    background: var(--surface);
    border: 1px solid var(--border);
    border-radius: var(--radius-md);
    padding: 16px;
}
.stat-value { font-size: 24px; font-weight: 700; letter-spacing: -0.01em; }
.stat-label { font-size: 12.5px; color: var(--text-muted); margin-top: 4px; }

.reg-card {
    display: flex;
    gap: 14px;
    align-items: flex-start;
}
.reg-card-body { flex: 1; min-width: 0; }
.reg-card-top { display: flex; align-items: center; gap: 10px; flex-wrap: wrap; }
.reg-card-id { font-weight: 700; font-size: 14.5px; }
.reg-card-msg { font-size: 13.5px; color: var(--text-muted); margin-top: 6px; line-height: 1.5; }
.reg-card-actions { display: flex; gap: 8px; margin-top: 12px; }
.reg-reject-box {
    display: none;
    margin-top: 12px;
    padding-top: 12px;
    border-top: 1px dashed var(--border);
}
.reg-reject-box.is-open { display: block; }
.reg-reject-box textarea { margin-bottom: 10px; }

.admin-table {
    width: 100%;
    border-collapse: collapse;
    background: var(--surface);
    border: 1px solid var(--border);
    border-radius: var(--radius-md);
    overflow: hidden;
}
.admin-table th, .admin-table td {
    text-align: left;
    padding: 11px 14px;
    font-size: 13.5px;
    border-bottom: 1px solid var(--border);
}
.admin-table th {
    font-size: 11.5px;
    text-transform: uppercase;
    letter-spacing: .03em;
    color: var(--text-faint);
    background: var(--bg);
}
.admin-table tr:last-child td { border-bottom: none; }
.table-wrap { overflow-x: auto; border-radius: var(--radius-md); }
.table-wrap .admin-table { border-radius: 0; border: none; }
.table-scroll-border { border: 1px solid var(--border); border-radius: var(--radius-md); }

.mod-grid {
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(220px, 1fr));
    gap: 12px;
}
.mod-card { display: flex; flex-direction: column; gap: 8px; }
.mod-card-text { font-size: 13.5px; color: var(--text-muted); line-height: 1.5; }
.mod-card-meta { font-size: 12px; color: var(--text-faint); }
.mod-card-actions { display: flex; gap: 8px; margin-top: 4px; }

.room-row { display: flex; align-items: center; gap: 12px; }
.room-row-info { flex: 1; min-width: 0; }
.room-row-name { font-weight: 700; font-size: 14px; }
.room-row-meta { font-size: 12.5px; color: var(--text-faint); margin-top: 2px; }

.empty-note {
    text-align: center;
    color: var(--text-faint);
    font-size: 13.5px;
    padding: 30px 10px;
}

/* Manage User modal (Admin > Users) */
.modal-overlay {
    display: none;
    position: fixed;
    inset: 0;
    background: rgba(17, 20, 28, .45);
    align-items: center;
    justify-content: center;
    padding: 20px;
    z-index: 100;
}
.modal-overlay.is-open { display: flex; }
.modal-card {
    background: var(--surface);
    border: 1px solid var(--border);
    border-radius: var(--radius-lg);
    width: 100%;
    max-width: 380px;
    max-height: 90vh;
    overflow-y: auto;
    overscroll-behavior: contain;
    padding: 20px;
}
.modal-head {
    display: flex;
    align-items: center;
    gap: 10px;
    margin-bottom: 16px;
    /* No visual effect on short modals that never scroll — only kicks in
       once content is tall enough for .modal-card itself to scroll, which
       is exactly when keeping the close button reachable matters most. */
    position: sticky;
    top: 0;
    background: var(--surface);
    z-index: 1;
}
.modal-head-info { flex: 1; min-width: 0; }
.modal-title { font-size: 14.5px; font-weight: 700; }
.modal-subtitle { font-size: 12.5px; color: var(--text-faint); margin-top: 1px; }
.modal-section {
    padding-bottom: 16px;
    margin-bottom: 16px;
    border-bottom: 1px solid var(--border);
}
.modal-section:last-child { border-bottom: none; margin-bottom: 0; padding-bottom: 0; }
.modal-section-label {
    font-size: 11.5px;
    font-weight: 700;
    text-transform: uppercase;
    letter-spacing: .03em;
    color: var(--text-faint);
    margin-bottom: 8px;
}
.modal-note { font-size: 12.5px; color: var(--text-faint); }

/* Room member pickers (New Room / Add Members) + Room Info member list */
.member-picker-list {
    max-height: 260px;
    overflow-y: auto;
    overscroll-behavior: contain;
    border: 1px solid var(--border);
    border-radius: var(--radius-md);
}
.member-picker-row,
.room-member-row {
    display: flex;
    align-items: center;
    gap: 10px;
    padding: 9px 12px;
    border-bottom: 1px solid #f1f2f5;
}
.member-picker-row:last-child,
.room-member-row:last-child { border-bottom: none; }
.member-picker-row label {
    display: flex;
    align-items: center;
    gap: 10px;
    flex: 1;
    min-width: 0;
    cursor: pointer;
    font-size: 13.5px;
    font-weight: 600;
}
.member-picker-row input[type="checkbox"] { flex-shrink: 0; width: 16px; height: 16px; }
.room-member-name { flex: 1; min-width: 0; font-size: 13.5px; font-weight: 600; }
.room-member-actions { display: flex; gap: 6px; flex-shrink: 0; }
.room-member-actions .btn { font-size: 11.5px; padding: 4px 9px; }

/* -------------------------------------------------------------------------
   13. Utilities
   ------------------------------------------------------------------------- */
.flex-between { display: flex; align-items: center; justify-content: space-between; gap: 10px; }
.mt-0 { margin-top: 0; }
.text-muted { color: var(--text-muted); }
.text-faint { color: var(--text-faint); }
.icon { width: 20px; height: 20px; }

/* -------------------------------------------------------------------------
   14. Responsive — tablet & mobile
   ------------------------------------------------------------------------- */
@media (max-width: 980px) {
    .admin-layout { flex-direction: column; }
    .admin-subnav {
        position: static;
        width: 100%;
        flex-direction: row;
        overflow-x: auto;
        gap: 6px;
        padding-bottom: 4px;
    }
    .admin-subnav a { white-space: nowrap; }
}

@media (max-width: 860px) {
    .chat-list { width: 260px; }
    .bubble { max-width: 78%; }
}

/* Tablet portrait: the sidebar is still visible here (that only hides at
   768px, below), but squeezing a fixed-width conversation list AND a chat
   panel into what's left of the viewport produces two cramped columns.
   Reuse the same list-then-thread pattern as mobile (driven by the same
   body[data-chat-view] attribute) so each gets the full content width. */
@media (max-width: 900px) {
    .chat-list { width: 100%; }
    body[data-chat-view="list"] .chat-panel { display: none; }
    body[data-chat-view="thread"] .chat-list { display: none; }
    body[data-chat-view="thread"] .chat-back { display: inline-flex; }
}

@media (max-width: 768px) {
    .sidebar { display: none; }
    .app-main { margin-left: 0; width: 100%; }
    .topbar { padding: 0 16px; }
    .topbar-brand-mark { display: flex; }
    .app-content { padding: 16px 16px calc(90px + env(safe-area-inset-bottom, 0px)); }
    .app-content--wide { max-width: none; }
    /* Chat is the only .app-content--nopad page — its .chat-layout below
       already reserves exact space for the bottom nav via its own height
       calc, so adding bottom padding here too would double-reserve that
       space and push the composer up behind a blank gap. */
    .app-content--nopad { padding: 0; }
    .bottom-nav { display: flex; }

    .mod-grid { grid-template-columns: 1fr; }
    .stat-grid { grid-template-columns: repeat(2, 1fr); }

    /* Chat: show either the list or the panel (rules live in the 900px
       query above, which already covers this narrower range too). Height
       must additionally account for the bottom nav + safe area. */
    .chat-layout { height: calc(100vh - 58px - 62px - env(safe-area-inset-bottom, 0px)); }
    .chat-layout { height: calc(100dvh - 58px - 62px - env(safe-area-inset-bottom, 0px)); }

    .profile-header { flex-direction: column; align-items: flex-start; text-align: left; }

    /* Touch targets: icon-only buttons (chat back, modal close, attachment
       remove, attach/send) are comfortably tappable at this size without
       changing how any of them look on desktop (mouse pointers don't need
       the extra padding, so this stays inside the mobile query). */
    .btn-icon { padding: 10px; }
    .room-member-actions .btn { padding: 7px 12px; font-size: 12.5px; }
}

@media (max-width: 480px) {
    .app-content { padding: 14px 14px calc(90px + env(safe-area-inset-bottom, 0px)); }
    .card { padding: 14px; }
    .stat-grid { grid-template-columns: 1fr 1fr; }
    .bubble { max-width: 86%; }
    .auth-card { padding: 26px 20px; }
}
