/* Server settings layout */
.settings-layout {
    display: flex;
    height: 100%;
}

.settings-sidebar {
    width: 240px;
    background-color: var(--bg-secondary);
    border-right: 1px solid var(--border);
    padding: 16px;
    display: flex;
    flex-direction: column;
    gap: 12px;
}

.settings-sidebar h3 {
    font-size: 16px;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

.settings-nav {
    display: flex;
    flex-direction: column;
    gap: 4px;
    flex: 1;
}

.settings-nav-item {
    padding: 8px 12px;
    border: none;
    background: transparent;
    color: var(--text-secondary);
    font-size: 14px;
    cursor: pointer;
    border-radius: 4px;
    text-align: left;
}

.settings-nav-item:hover {
    background: var(--bg-tertiary);
    color: var(--text-primary);
}

.settings-nav-item.active {
    background: var(--bg-tertiary);
    color: var(--text-primary);
    font-weight: 500;
}

.settings-back {
    margin-top: auto;
}

.settings-content {
    flex: 1;
    padding: 24px 32px;
    overflow-y: auto;
    background-color: var(--bg-primary);
}

/* Tab panes — all five live in the DOM at once. The active one gets
   .active and runs the fade-in animation; the rest are display:none
   so they don't catch focus or contribute to scroll. Lazy-render
   strategy in profile-settings.js renders each pane only on first
   visit, so switching back is instant with the same small fade. */
.settings-tab-pane {
    display: none;
}
.settings-tab-pane.active {
    display: block;
    animation: settingsTabFadeIn 0.18s ease-out;
}
@keyframes settingsTabFadeIn {
    from { opacity: 0; transform: translateY(4px); }
    to   { opacity: 1; transform: translateY(0); }
}

/* Roles */
.roles-header {
    display: flex;
    align-items: center;
    justify-content: space-between;
    margin-bottom: 16px;
}

.roles-header h2 {
    font-size: 20px;
}

.roles-list {
    display: flex;
    flex-direction: column;
    gap: 4px;
}

/* Each role row is a 2-row grid:
     [drag ⠿] [color dot] [ role info (name) ] [ Edit | Delete ]
     [                   members disclosure                    ]
   The members disclosure takes the full second row, so the buttons on
   the top row always sit flush against the right edge regardless of
   how long the role name is or how many members the disclosure summary
   reports. Fixes the "wiggly right edge" Vadim reported — row width
   stopped depending on the member-count string inside the disclosure. */
.role-item {
    display: grid;
    grid-template-columns: auto auto 1fr auto;
    align-items: center;
    gap: 8px 12px;
    padding: 10px 12px;
    border-radius: 6px;
    background: var(--bg-secondary);
}

.role-item:hover {
    background: var(--bg-tertiary);
}

.role-item .role-info { min-width: 0; }
.role-item .role-actions { flex-shrink: 0; white-space: nowrap; }

/* The <details> disclosure sits on its own grid row below everything. */
.role-item > .role-members-disclosure {
    grid-column: 1 / -1;
    margin-top: 6px;
}

/* Bans list — each row has avatar + name/username/reason + unban button.
   Matches the layout weight of role-item but with more body copy since
   the reason can be long. Avatar + name are clickable: they open the
   standard profile card via showProfileCard so mods can act from here. */
.bans-list {
    display: flex;
    flex-direction: column;
    gap: 8px;
}

.ban-item {
    display: flex;
    align-items: center;
    gap: 12px;
    padding: 10px 12px;
    border-radius: 6px;
    background: var(--bg-secondary);
}

.ban-item:hover {
    background: var(--bg-tertiary);
}

.ban-avatar {
    width: 40px;
    height: 40px;
    border-radius: 50%;
    background: var(--bg-tertiary);
    color: var(--text-primary);
    display: flex;
    align-items: center;
    justify-content: center;
    font-weight: 600;
    flex-shrink: 0;
    cursor: pointer;
    overflow: hidden;
}

.ban-avatar img {
    width: 100%;
    height: 100%;
    object-fit: cover;
}

.ban-info {
    flex: 1;
    min-width: 0;
}

.ban-name {
    font-weight: 600;
    color: var(--text-primary);
    cursor: pointer;
    display: inline-block;
}

.ban-name:hover {
    text-decoration: underline;
}

.ban-username {
    font-size: 12px;
    color: var(--text-muted);
}

.ban-reason {
    font-size: 13px;
    color: var(--text-secondary);
    margin-top: 4px;
    word-break: break-word;
}

.ban-unban-btn {
    flex-shrink: 0;
}

/* Invites list — each row is a 2-column grid:
     [ code + meta + role pills (1fr) ] [ actions (auto, right) ]
   The generic .role-item rule uses a 4-column grid meant for role rows
   (drag + dot + info + actions). Invites only have two slots worth of
   content, and the old 4-col layout dropped the actions into the wrong
   column so they floated mid-row instead of pinning right.

   Also: info column is a vertical stack (code on top, meta below,
   role pills last) so the row grows downward instead of forcing the
   action column sideways. */
.invite-item {
    grid-template-columns: 1fr auto;
    align-items: start;
}

.invite-item .role-info {
    flex-direction: column;
    align-items: flex-start;
    gap: 4px;
    min-width: 0;
}

.invite-actions {
    display: flex;
    gap: 6px;
    flex-shrink: 0;
    align-self: center;
}

.invite-roles {
    display: flex;
    flex-wrap: wrap;
    gap: 4px;
    align-items: center;
    margin-top: 2px;
    font-size: 12px;
    color: var(--text-muted);
}

.invite-roles-label {
    margin-right: 2px;
}

/* Drag handles for reorderable roles. Visible on hover on desktop (so the
   row stays clean at rest) and always visible on touch. @everyone gets a
   spacer of the same width so rows stay vertically aligned. */
.role-item .role-drag-handle {
    cursor: grab;
    user-select: none;
    color: var(--text-muted);
    font-size: 14px;
    line-height: 1;
    padding: 4px 2px;
    opacity: 0.4;
    transition: opacity 0.15s;
}

.role-item:hover .role-drag-handle {
    opacity: 1;
}

.role-item .drag-handle-spacer {
    display: inline-block;
    width: 18px;
}

.role-item.dragging {
    opacity: 0.5;
}

.role-drag-placeholder {
    background: var(--bg-tertiary) !important;
    border: 1px dashed var(--border);
    box-sizing: border-box;
}

.role-drag-ghost {
    background: var(--bg-tertiary);
    box-shadow: 0 8px 20px rgba(0, 0, 0, 0.35);
    opacity: 0.95;
    transform: rotate(0.5deg);
}

/* Explanatory hint above the roles list. Short enough to not nag;
   sits quietly in text-muted colour. */
.roles-hint {
    color: var(--text-muted);
    font-size: 13px;
    line-height: 1.4;
    margin: 4px 0 16px;
    padding: 10px 12px;
    background: var(--bg-secondary);
    border-left: 3px solid var(--accent);
    border-radius: 4px;
}

.role-color-dot {
    width: 16px;
    height: 16px;
    border-radius: 50%;
    flex-shrink: 0;
}

.role-info {
    flex: 1;
    display: flex;
    align-items: center;
    gap: 8px;
}

.role-name {
    font-weight: 500;
    font-size: 14px;
}

.role-position {
    font-size: 12px;
    color: var(--text-muted);
}

.role-actions {
    display: flex;
    gap: 4px;
}

/* Role editor */
.role-editor {
    max-width: 600px;
}

.role-editor h2 {
    margin-bottom: 20px;
}

.form-group {
    margin-bottom: 16px;
}

.form-group label {
    display: block;
    font-size: 12px;
    font-weight: 700;
    text-transform: uppercase;
    letter-spacing: 0.5px;
    color: var(--text-muted);
    margin-bottom: 6px;
}

.form-input {
    width: 100%;
    padding: 8px 12px;
    border: 1px solid var(--border);
    border-radius: 4px;
    background: var(--bg-input);
    color: var(--text-primary);
    font-size: 14px;
    outline: none;
}

.form-input:focus {
    border-color: var(--accent);
}

/* Native <input type="file"> styling via ::file-selector-button.
 * The OS default renders a generic grey button + "Файл не выбран"
 * label that clashes with the dark UI — we restyle the in-control
 * button as our primary action and tone the placeholder text down.
 * Works in Chrome 89+, Firefox 82+, Safari 14.1+; older browsers
 * fall back to the platform default and the form still works. */
input[type="file"].form-input,
.form-input[type="file"] {
    padding: 6px 10px;
    color: var(--text-muted);
    font-size: 13px;
    cursor: pointer;
}

input[type="file"]::file-selector-button {
    margin-right: 12px;
    padding: 6px 14px;
    background: var(--accent);
    color: #fff;
    border: none;
    border-radius: 6px;
    font-size: 13px;
    font-weight: 500;
    cursor: pointer;
    transition: background 0.12s, transform 0.06s;
}

input[type="file"]::file-selector-button:hover {
    background: var(--accent-hover);
}

input[type="file"]::file-selector-button:active {
    transform: scale(0.98);
}

.form-input-color {
    width: 48px;
    height: 36px;
    border: 1px solid var(--border);
    border-radius: 4px;
    background: none;
    cursor: pointer;
    padding: 2px;
}

.perm-grid {
    display: grid;
    grid-template-columns: 1fr 1fr;
    gap: 8px;
}

.perm-checkbox {
    display: flex;
    align-items: center;
    gap: 8px;
    font-size: 14px;
    color: var(--text-secondary);
    cursor: pointer;
}

.perm-checkbox input {
    accent-color: var(--accent);
}

.role-editor-actions {
    display: flex;
    gap: 8px;
    margin-top: 24px;
}

/* Server settings button in sidebar header */
.server-settings-btn {
    border: none;
    background: none;
    color: var(--text-muted);
    cursor: pointer;
    font-size: 36px;
    padding: 4px;
    border-radius: 4px;
    display: inline-flex;
    align-items: center;
    justify-content: center;
}
.server-settings-btn svg {
    width: 20px;
    height: 20px;
    display: block;
}

.server-settings-btn:hover {
    color: var(--text-primary);
    background: var(--bg-tertiary);
}

.channel-sidebar-header {
    display: flex;
    align-items: center;
    justify-content: space-between;
}

/* Member role badges */
.member-info {
    flex: 1;
    min-width: 0;
}

.member-roles {
    display: flex;
    flex-wrap: wrap;
    gap: 2px;
    margin-top: 2px;
}

.member-role-badge {
    font-size: 10px;
    padding: 1px 6px;
    border: 1px solid;
    border-radius: 8px;
    color: var(--text-secondary);
}

/* Button styles */
.btn {
    padding: 8px 16px;
    border: none;
    border-radius: 4px;
    font-size: 14px;
    cursor: pointer;
    font-weight: 500;
}

.btn-primary {
    background: var(--accent);
    color: #fff;
}

.btn-primary:hover {
    background: var(--accent-hover);
}

.btn-secondary {
    background: var(--bg-tertiary);
    color: var(--text-primary);
}

.btn-secondary:hover {
    background: var(--border);
}

.btn-danger {
    background: var(--danger);
    color: #fff;
}

.btn-danger:hover {
    background: var(--danger-hover);
}

.btn-sm {
    padding: 4px 10px;
    font-size: 12px;
}

.btn-lg {
    padding: 12px 32px;
    font-size: 16px;
}

/* Invite page */
.invite-page {
    display: flex;
    align-items: center;
    justify-content: center;
    height: 100%;
    background: var(--bg-primary);
}

.invite-card {
    text-align: center;
    padding: 40px;
    background: var(--bg-secondary);
    border-radius: 12px;
    max-width: 400px;
    width: 100%;
    box-shadow: 0 4px 16px var(--shadow);
}

.invite-server-icon {
    width: 80px;
    height: 80px;
    border-radius: 50%;
    background: var(--bg-tertiary);
    margin: 0 auto 16px;
    display: flex;
    align-items: center;
    justify-content: center;
    font-size: 32px;
    font-weight: 700;
    color: var(--text-primary);
    overflow: hidden;
}

.invite-server-icon img {
    width: 100%;
    height: 100%;
    object-fit: cover;
}

.invite-members {
    color: var(--text-muted);
    font-size: 14px;
    margin-bottom: 20px;
}

.invite-login-hint {
    margin-top: 12px;
    font-size: 13px;
    color: var(--text-muted);
}

.invite-code-display {
    font-family: monospace;
    font-size: 14px;
    font-weight: 600;
    color: var(--accent);
    cursor: pointer;
    padding: 2px 4px;
    margin-left: -4px;
    border-radius: 4px;
    transition: background-color 0.15s;
}

.invite-code-display:hover,
.invite-code-display:focus {
    background: var(--bg-tertiary);
    outline: none;
}

/* Profile settings */
.profile-images {
    position: relative;
    margin-bottom: 60px;
}

.profile-banner-preview {
    width: 100%;
    height: 120px;
    background: var(--bg-tertiary);
    border-radius: 8px;
    overflow: hidden;
    position: relative;
    display: flex;
    align-items: center;
    justify-content: center;
    color: var(--text-muted);
}

.profile-banner-preview img {
    width: 100%;
    height: 100%;
    object-fit: cover;
}

.profile-avatar-preview {
    width: 80px;
    height: 80px;
    border-radius: 50%;
    background: var(--bg-secondary);
    border: 4px solid var(--bg-primary);
    position: absolute;
    bottom: -40px;
    left: 24px;
    display: flex;
    align-items: center;
    justify-content: center;
    font-size: 28px;
    font-weight: 700;
    color: var(--text-primary);
    overflow: hidden;
}

.profile-avatar-preview img {
    width: 100%;
    height: 100%;
    object-fit: cover;
}

.profile-upload-overlay {
    position: absolute;
    inset: 0;
    background: rgba(0,0,0,0.5);
    display: flex;
    align-items: center;
    justify-content: center;
    color: #fff;
    font-size: 12px;
    font-weight: 600;
    opacity: 0;
    cursor: pointer;
    transition: opacity 0.2s;
    border-radius: inherit;
}

.profile-banner-preview:hover .profile-upload-overlay,
.profile-avatar-preview:hover .profile-upload-overlay {
    opacity: 1;
}

/* Profile card popup */
.profile-card-overlay {
    position: fixed;
    inset: 0;
    z-index: 5000;
}

.profile-card {
    position: fixed;
    width: 340px;
    background: var(--bg-secondary);
    border-radius: 12px;
    box-shadow: 0 8px 24px var(--shadow);
    overflow: hidden;
    z-index: 5001;
}

.profile-card-banner {
    height: 80px;
    background: var(--bg-tertiary);
    overflow: hidden;
}

.profile-card-banner img {
    width: 100%;
    height: 100%;
    object-fit: cover;
}

.profile-card-avatar {
    width: 64px;
    height: 64px;
    border-radius: 50%;
    background: var(--bg-secondary);
    border: 4px solid var(--bg-secondary);
    margin: -32px 0 0 16px;
    display: flex;
    align-items: center;
    justify-content: center;
    font-size: 24px;
    font-weight: 700;
    color: var(--text-primary);
    overflow: hidden;
}

.profile-card-avatar img {
    width: 100%;
    height: 100%;
    object-fit: cover;
}

.profile-card-body {
    padding: 8px 16px 16px;
}

.profile-card-name {
    font-size: 18px;
    font-weight: 700;
}

.profile-card-bio {
    font-size: 13px;
    color: var(--text-secondary);
    margin-top: 4px;
}

.profile-card-status {
    display: flex;
    align-items: center;
    gap: 6px;
    font-size: 13px;
    color: var(--text-muted);
    margin-top: 8px;
}

/* Server icon upload */
.server-icon-upload {
    display: flex;
    flex-direction: column;
    align-items: center;
    margin-bottom: 16px;
}

.server-icon-preview {
    width: 80px;
    height: 80px;
    border-radius: 50%;
    background: var(--bg-tertiary);
    display: flex;
    align-items: center;
    justify-content: center;
    overflow: hidden;
    font-size: 32px;
    font-weight: 700;
    color: var(--text-primary);
}

.server-icon-preview img {
    width: 100%;
    height: 100%;
    max-width: 80px;
    max-height: 80px;
    object-fit: cover;
    border-radius: 50%;
}

/* Channel management */
.channel-mgmt-category {
    margin-bottom: 16px;
}

.channel-mgmt-category-header {
    display: flex;
    align-items: center;
    gap: 8px;
    padding: 6px 8px;
    text-transform: uppercase;
    font-size: 12px;
    font-weight: 700;
    color: var(--text-secondary);
    letter-spacing: 0.5px;
}

.channel-mgmt-category-header .hover-btn {
    opacity: 0;
    transition: opacity 0.15s;
    font-size: 12px;
    padding: 2px 4px;
}

.channel-mgmt-category-header:hover .hover-btn {
    opacity: 1;
}

.channel-mgmt-item {
    display: flex;
    align-items: center;
    gap: 6px;
    padding: 8px 12px;
    border-radius: 6px;
    transition: background-color 0.15s;
}

.channel-mgmt-item:hover {
    background: var(--bg-tertiary);
}

.channel-mgmt-hash {
    color: var(--text-muted);
    font-size: 16px;
    font-weight: 600;
}

.channel-mgmt-name {
    flex: 1;
    font-size: 14px;
}

.channel-mgmt-actions {
    display: flex;
    gap: 4px;
    opacity: 0;
    transition: opacity 0.15s;
}

.channel-mgmt-item:hover .channel-mgmt-actions {
    opacity: 1;
}

/* Permission editor */
.perm-toggle {
    border: none;
    background: none;
    cursor: pointer;
    font-size: 14px;
    padding: 2px 6px;
    border-radius: 4px;
    min-width: 28px;
}

.perm-toggle:hover {
    background: var(--bg-tertiary);
}

/* Channel permission editor — per-role matrix.
   Two-letter column headers like "VC"/"SM" were unreadable; emoji icons
   read at a glance at any scale. Each column is fixed-width so the icons
   line up with their toggle cells in the rows below. */
.perm-editor-table {
    width: 100%;
    table-layout: auto;
    border-collapse: separate;
    border-spacing: 0;
    font-size: 12px;
}

.perm-editor-table th,
.perm-editor-table td {
    padding: 6px 4px;
    vertical-align: middle;
}

.perm-editor-role-col,
.perm-editor-role-cell {
    text-align: left;
    min-width: 120px;
}

.perm-editor-icon-col {
    width: 44px;
    text-align: center;
    position: relative;
}

/* Custom tooltip on the emoji column headers — the browser-native title
   attribute is easy to miss (appears ~1s later, faded). data-tooltip gives
   us an always-visible-on-hover pill so new users understand what each
   icon gates. Hidden on touch devices (no :hover, and mobile already gets
   a sticky role column + wider layout to compensate). */
.perm-editor-icon-col[data-tooltip]::after {
    content: attr(data-tooltip);
    position: absolute;
    bottom: calc(100% + 6px);
    left: 50%;
    transform: translateX(-50%) translateY(4px);
    background: var(--bg-secondary);
    color: var(--text-primary);
    border: 1px solid var(--border);
    border-radius: 6px;
    padding: 4px 10px;
    font-size: 12px;
    font-weight: normal;
    white-space: nowrap;
    opacity: 0;
    pointer-events: none;
    transition: opacity 0.15s ease, transform 0.15s ease;
    box-shadow: 0 4px 12px var(--shadow);
    z-index: 10;
}

.perm-editor-icon-col[data-tooltip]:hover::after {
    opacity: 1;
    transform: translateX(-50%) translateY(0);
}

@media (pointer: coarse) and (hover: none) {
    .perm-editor-icon-col[data-tooltip]::after { display: none; }
}

.perm-editor-cell {
    text-align: center;
}

.perm-editor-table .perm-icon {
    font-size: 18px;
    line-height: 1;
}

/* Bulk-row controls — three compact chips that stamp allow/inherit/deny
   across every perm cell in the same row. Big enough on mobile to hit
   reliably without needing the 44pt mobile treatment — they're always
   inline next to the role name. */
.perm-editor-bulk-col {
    width: 120px;
    text-align: center;
}

.perm-bulk-group {
    display: inline-flex;
    gap: 4px;
    align-items: center;
    justify-content: center;
}

.perm-bulk-btn {
    border: 1px solid var(--border);
    background: var(--bg-secondary);
    cursor: pointer;
    font-size: 13px;
    line-height: 1;
    padding: 4px 8px;
    min-width: 32px;
    min-height: 28px;
    border-radius: 6px;
    transition: background-color 0.15s, border-color 0.15s;
}

.perm-bulk-btn:hover {
    background: var(--bg-tertiary);
}

.perm-bulk-btn.perm-bulk-allow:hover {
    background: rgba(46, 160, 67, 0.15);
    border-color: rgba(46, 160, 67, 0.5);
}

.perm-bulk-btn.perm-bulk-deny:hover {
    background: rgba(248, 81, 73, 0.15);
    border-color: rgba(248, 81, 73, 0.5);
}

/* Mobile: horizontal scroll for the matrix rather than cramming columns
   into tiny widths. Sticky role column keeps context while the user
   scrolls sideways through the icons. */
@media (max-width: 767px), ((pointer: coarse) and (hover: none) and (max-width: 1280px)) {
    .perm-editor-grid {
        overflow-x: auto;
        -webkit-overflow-scrolling: touch;
    }

    .perm-editor-table {
        min-width: 100%;
        width: max-content;
    }

    .perm-editor-role-col,
    .perm-editor-role-cell {
        position: sticky;
        left: 0;
        background: var(--bg-primary);
        z-index: 2;
        min-width: 100px;
    }

    .perm-editor-icon-col {
        width: 40px;
    }

    .perm-bulk-btn {
        min-width: 36px;
        min-height: 32px;
        font-size: 14px;
    }
}

/* Sticker pack management */
.sticker-pack-manager {
    margin-bottom: 16px;
    border: 1px solid var(--border);
    border-radius: 8px;
    overflow: hidden;
}

.sticker-pack-header {
    display: flex;
    align-items: center;
    justify-content: space-between;
    padding: 10px 14px;
    background: var(--bg-tertiary);
}

.sticker-pack-grid {
    display: flex;
    flex-wrap: wrap;
    gap: 6px;
    padding: 10px 14px;
    min-height: 40px;
}

.sticker-manage-item {
    width: 64px;
    height: 64px;
    border-radius: 6px;
    overflow: visible;
    border: 1px solid var(--border);
    position: relative;
}

.sticker-manage-item img {
    width: 100%;
    height: 100%;
    object-fit: contain;
    border-radius: 6px;
}

.sticker-delete-btn {
    position: absolute;
    top: -6px;
    right: -6px;
    width: 18px;
    height: 18px;
    border-radius: 50%;
    border: none;
    background: var(--danger);
    color: #fff;
    font-size: 12px;
    cursor: pointer;
    display: flex;
    align-items: center;
    justify-content: center;
    opacity: 0;
    transition: opacity 0.15s;
}

.sticker-manage-item:hover .sticker-delete-btn {
    opacity: 1;
}

.sticker-emoji-label {
    position: absolute;
    bottom: -4px;
    left: 50%;
    transform: translateX(-50%);
    background: var(--bg-secondary);
    border: 1px solid var(--border);
    border-radius: 8px;
    font-size: 12px;
    padding: 0 4px;
    cursor: pointer;
    min-width: 18px;
    text-align: center;
}

.sticker-emoji-label:hover {
    border-color: var(--accent);
}

.emote-name-label {
    position: absolute;
    top: -6px;
    left: 50%;
    transform: translateX(-50%);
    background: var(--bg-secondary);
    border: 1px solid var(--border);
    border-radius: 4px;
    font-size: 9px;
    padding: 0 3px;
    cursor: pointer;
    white-space: nowrap;
    max-width: 70px;
    overflow: hidden;
    text-overflow: ellipsis;
    color: var(--text-muted);
    opacity: 0;
    transition: opacity 0.15s;
}

.sticker-manage-item:hover .emote-name-label {
    opacity: 1;
}

.emote-name-label:hover {
    border-color: var(--accent);
    color: var(--text-primary);
}

.sticker-add-label {
    cursor: pointer;
}

/* General tab */
.settings-section-title {
    margin-top: 24px;
    margin-bottom: 12px;
    font-size: 14px;
    font-weight: 600;
    text-transform: uppercase;
    letter-spacing: 0.5px;
    color: var(--text-secondary);
}

.settings-section-title:first-of-type {
    margin-top: 0;
}

.theme-toggle-group {
    display: flex;
    gap: 8px;
}

.theme-toggle-btn {
    padding: 8px 20px;
    border: 1px solid var(--border);
    border-radius: 6px;
    background: var(--bg-tertiary);
    color: var(--text-secondary);
    cursor: pointer;
    font-size: 14px;
    transition: background 0.15s, border-color 0.15s, color 0.15s;
}

.theme-toggle-btn.active {
    background: var(--accent);
    border-color: var(--accent);
    color: #fff;
}

.theme-toggle-btn:hover:not(.active) {
    border-color: var(--accent);
    color: var(--text-primary);
}

/* Compact theme-toggle when sitting in a .settings-toggle-row-select
   right column — keeps the segmented pill from dwarfing other controls
   on the same row (language select, send-mode select). */
.settings-toggle-row-select .theme-toggle-group { flex-shrink: 0; }
.settings-toggle-row-select .theme-toggle-btn {
    padding: 6px 12px;
    font-size: 13px;
}

.settings-general-spacer {
    flex: 1;
    min-height: 40px;
}

.settings-logout-btn {
    margin-top: auto;
    width: 100%;
    padding: 10px;
    font-size: 14px;
}

/* Settings overlay (opens over chat, like Discord) */
.settings-overlay {
    position: fixed;
    inset: 0;
    z-index: 200;
    background: rgba(0, 0, 0, 0.6);
    display: flex;
    align-items: center;
    justify-content: center;
    animation: settingsFadeIn 0.2s ease;
}

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

.settings-panel {
    display: flex;
    width: 90%;
    max-width: 900px;
    height: 85vh;
    background: var(--bg-primary);
    border-radius: 12px;
    box-shadow: 0 8px 32px rgba(0, 0, 0, 0.5);
    position: relative;
    overflow: hidden;
}

.settings-panel .settings-sidebar {
    width: 220px;
    border-right: 1px solid var(--border);
    border-radius: 12px 0 0 12px;
}

.settings-panel .settings-content {
    flex: 1;
    overflow-y: auto;
    padding: 24px 32px;
    /* Reserve space for the scrollbar so content doesn't shift
     * sideways when it appears/disappears. Falls back to overflow-y:
     * scroll on Safari < 16 which doesn't know scrollbar-gutter. */
    scrollbar-gutter: stable;
}

.settings-close-btn {
    position: absolute;
    top: 12px;
    right: 16px;
    background: none;
    border: none;
    color: var(--text-muted);
    font-size: 28px;
    cursor: pointer;
    line-height: 1;
    z-index: 5;
    transition: color 0.15s;
}
.settings-close-btn:hover {
    color: var(--text-primary);
}

/* Mobile settings — sidebar collapses to tabs */
@media (max-width: 767px), ((pointer: coarse) and (hover: none) and (max-width: 1280px)) {
    .settings-panel {
        width: 100%;
        height: 100%;
        max-width: none;
        border-radius: 0;
        flex-direction: column;
        /* Clip any rogue inner content that ignores the column width
         * (long Russian labels, oversized sticker tiles on viewports
         * the inner grid mis-sizes for, etc). The opt-in scroll for
         * specific surfaces (.perm-editor-grid, .settings-nav) lives
         * INSIDE this container and uses its own overflow-x: auto, so
         * those still work. */
        overflow-x: hidden;
    }

    .settings-panel .settings-content {
        /* Hard-cap content width to the panel width — defense in
         * depth for the same overflow scenario above. min-width: 0
         * lets flex/grid children that should shrink actually shrink
         * (without it some browsers default to min-content). */
        max-width: 100%;
        min-width: 0;
        overflow-x: hidden;
    }

    .settings-panel .settings-sidebar {
        width: 100%;
        border-right: none;
        border-bottom: 1px solid var(--border);
        border-radius: 0;
        padding: 12px;
        flex-direction: row;
        align-items: center;
        gap: 0;
        overflow: hidden;
    }

    .settings-panel .settings-sidebar h3 {
        display: none;
    }

    .settings-panel .settings-nav {
        flex-direction: row;
        gap: 2px;
        overflow-x: auto;
        overflow-y: hidden;
        flex: 1;
        margin-right: 44px;
        scrollbar-width: none;
        padding-bottom: 4px;
    }

    .settings-panel .settings-nav::-webkit-scrollbar {
        height: 1px;
    }

    .settings-panel .settings-nav::-webkit-scrollbar-track {
        background: transparent;
    }

    .settings-panel .settings-nav::-webkit-scrollbar-thumb {
        background: transparent;
        border-radius: 1px;
    }

    .settings-panel .settings-nav:hover::-webkit-scrollbar-thumb {
        background: rgba(255, 255, 255, 0.2);
    }

    .settings-panel .settings-nav-item {
        white-space: nowrap;
        font-size: 13px;
        padding: 6px 10px;
    }

    .settings-panel .settings-content {
        padding: 16px;
    }

    .settings-close-btn {
        top: 6px;
        right: 10px;
        width: 36px;
        height: 36px;
        font-size: 20px;
        background: var(--bg-tertiary, #40444b);
        border-radius: 50%;
        display: flex;
        align-items: center;
        justify-content: center;
    }

    /* Admin channels tab — on desktop the rename/delete/perm buttons are
       hover-revealed (opacity 0 → 1), which means on touch they never show
       at all. Make them always visible on narrow/touch viewports and wrap
       the row when the action group + category-select doesn't fit. */
    .channel-mgmt-actions {
        opacity: 1 !important;
        flex-wrap: wrap;
        justify-content: flex-end;
    }

    .channel-mgmt-item {
        flex-wrap: wrap;
        row-gap: 6px;
    }

    .channel-mgmt-item .hover-btn,
    .channel-mgmt-category-header .hover-btn {
        opacity: 1 !important;
        min-width: 32px;
        min-height: 32px;
    }

    .channel-cat-select {
        flex: 1 1 120px;
        min-width: 100px;
    }

    /* Roles tab — desktop grid layout already wraps the members
       disclosure to its own row and keeps actions flush right, so
       mobile only needs the long-name break and a slightly tighter
       column gap. */
    .role-item {
        gap: 6px 8px;
    }

    .role-name { word-break: break-word; }

    /* Overview + roles tab — inputs get the full column width. Small
       tweaks only; the form structure itself is already single-column. */
    .role-editor input[type="text"],
    .role-editor textarea,
    .role-editor .form-input {
        width: 100%;
        box-sizing: border-box;
    }

    /* Roles header (Roles tab) — the "Create role" button shouldn't
       overflow the row when the title text hugs it. */
    .roles-header {
        flex-wrap: wrap;
        gap: 8px;
    }
}

/* ── Settings drag ── */
.channel-mgmt-item.dragging,
.channel-mgmt-category.dragging {
    opacity: 0.3;
}

/* .drag-placeholder base styles come from chat.css — no override needed here */

.channel-mgmt-item .drag-handle,
.channel-mgmt-category-header .drag-handle {
    cursor: grab;
    color: var(--text-muted);
    padding: 0 6px;
    font-size: 13px;
    flex-shrink: 0;
    user-select: none;
}

/* ── Channel mode toggle (Overview tab) ── */
.channel-mode-toggle {
    display: flex;
    gap: 8px;
    margin-top: 6px;
}

.channel-mode-btn {
    padding: 6px 14px;
    border: 1px solid var(--border);
    border-radius: 6px;
    background: var(--bg-tertiary);
    color: var(--text-secondary);
    cursor: pointer;
    font-size: 13px;
    transition: background 0.15s, border-color 0.15s, color 0.15s;
}

.channel-mode-btn.active {
    background: var(--accent);
    border-color: var(--accent);
    color: #fff;
}

.channel-mode-btn:hover:not(.active) {
    border-color: var(--accent);
    color: var(--text-primary);
}

/* ── Drag: category highlight when hovering over it ── */
.channel-mgmt-category.drag-over {
    outline: 2px dashed var(--accent);
    outline-offset: 2px;
    border-radius: 6px;
    background: rgba(var(--accent-rgb, 88, 101, 242), 0.07);
}

/* ── Uncategorized drop zone header ── */
.channel-uncat-zone {
    font-size: 11px;
    font-weight: 600;
    text-transform: uppercase;
    letter-spacing: 0.06em;
    color: var(--text-muted);
    padding: 4px 8px 6px;
    border-bottom: 1px dashed var(--border);
    margin-bottom: 4px;
    user-select: none;
}

/* ── Roles tab: per-role members disclosure (Stage 4 / Task 11) ── */
.role-members-disclosure { margin-top: 6px; }
.role-members-summary {
    font-size: 12px;
    color: var(--text-muted);
    cursor: pointer;
    padding: 4px 0;
}
.role-members-summary:hover { color: var(--text-primary); }
.role-members-list {
    list-style: none;
    padding: 4px 8px;
    margin: 0;
    max-height: 200px;
    overflow-y: auto;
}
.role-members-item {
    display: flex;
    justify-content: space-between;
    align-items: center;
    padding: 4px 0;
    font-size: 13px;
}
.role-members-empty {
    font-size: 12px;
    color: var(--text-muted);
    padding: 4px 0;
}
.role-members-remove {
    background: transparent;
    border: none;
    color: var(--text-muted);
    cursor: pointer;
    font-size: 16px;
    line-height: 1;
}
.role-members-remove:hover { color: var(--danger, #e04b4b); }
.role-members-add { padding: 6px 0; }
.role-members-add-select { width: 100%; padding: 4px; font-size: 13px; }

/* ===========================================================================
   Settings — Stickers tab "Settings" block. Compact toggle row with a
   pill-style switch on the right and primary/hint text on the left.
   Reusable: any future preference toggle in the settings overlay can
   reuse .settings-toggle-row + .settings-toggle.
   =========================================================================== */
.emotes-settings-block {
    padding: 12px 14px;
    background: var(--bg-tertiary, rgba(255, 255, 255, 0.03));
    border-radius: 8px;
    border: 1px solid var(--border-color, rgba(255, 255, 255, 0.06));
}
.emotes-settings-block .settings-section-title {
    margin: 0 0 12px;
    font-size: 13px;
    font-weight: 600;
    text-transform: uppercase;
    letter-spacing: 0.4px;
    color: var(--text-muted);
}

.settings-toggle-row {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 16px;
    cursor: pointer;
    user-select: none;
}
.settings-toggle-text {
    display: flex;
    flex-direction: column;
    gap: 2px;
    flex: 1;
    min-width: 0;
}
.settings-toggle-text strong {
    font-size: 14px;
    font-weight: 500;
    color: var(--text-primary);
}
.settings-toggle-hint {
    font-size: 12px;
    color: var(--text-muted);
    line-height: 1.4;
}

/* iOS-style pill switch built from a hidden checkbox + a styled slider.
   :checked drives both the track colour and the knob translation. */
.settings-toggle {
    position: relative;
    display: inline-block;
    width: 40px;
    height: 22px;
    flex-shrink: 0;
}
.settings-toggle input[type="checkbox"] {
    opacity: 0;
    width: 0;
    height: 0;
    position: absolute;
}
.settings-toggle-slider {
    position: absolute;
    inset: 0;
    background: var(--bg-input, rgba(255, 255, 255, 0.1));
    border-radius: 999px;
    transition: background 0.18s ease;
    cursor: pointer;
}
.settings-toggle-slider::before {
    content: "";
    position: absolute;
    top: 3px;
    left: 3px;
    width: 16px;
    height: 16px;
    background: #fff;
    border-radius: 50%;
    box-shadow: 0 1px 3px rgba(0, 0, 0, 0.3);
    transition: transform 0.18s ease;
}
.settings-toggle input[type="checkbox"]:checked + .settings-toggle-slider {
    background: var(--accent, #5865f2);
}
.settings-toggle input[type="checkbox"]:checked + .settings-toggle-slider::before {
    transform: translateX(18px);
}
.settings-toggle input[type="checkbox"]:focus-visible + .settings-toggle-slider {
    outline: 2px solid var(--accent, #5865f2);
    outline-offset: 2px;
}

/* Variant of .settings-toggle-row that holds a <select> instead of a
   pill-switch on the right. Used for tri-state preferences (e.g. text
   emoticons: off / suggest / replace). Inherits the row layout from
   .settings-toggle-row and adds a thin gap between consecutive rows. */
.settings-toggle-row + .settings-toggle-row {
    margin-top: 14px;
    padding-top: 14px;
    border-top: 1px solid var(--border-color, rgba(255, 255, 255, 0.05));
}
.settings-toggle-row-select { align-items: center; }
.settings-select-compact {
    width: auto;
    min-width: 180px;
    max-width: 220px;
    flex-shrink: 0;
    padding: 6px 10px;
    font-size: 13px;
}

/* Disabled-row state — used for the preview-toggle while master push
   is off, and the master toggle while permission is denied. Visually
   muted, ignores pointer events on the toggle area only (label still
   readable). */
.settings-toggle-row.is-disabled {
    opacity: 0.5;
    pointer-events: none;
}

/* ===========================================================================
   Settings — Notifications tab. Same visual language as the Stickers
   tab (.emotes-settings-block + .settings-toggle-row), plus a few
   notification-specific surfaces: blocked-permission card, device
   list cards, empty state. No more .ios-toggle-* / btn-primary big-
   button mismatches — every toggle on this tab is a pill-switch.
   =========================================================================== */

/* Permission-blocked / unsupported card. Lives at the top of the
   first .emotes-settings-block when push.permission === 'denied'. */
.settings-permission-card {
    display: flex;
    align-items: flex-start;
    gap: 12px;
    padding: 12px 14px;
    margin-bottom: 14px;
    background: var(--bg-input, rgba(255, 255, 255, 0.04));
    border: 1px solid var(--border-color, rgba(255, 255, 255, 0.08));
    border-radius: 8px;
}
.settings-permission-card-icon {
    flex-shrink: 0;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 32px;
    height: 32px;
    border-radius: 50%;
    background: var(--bg-tertiary, rgba(255, 255, 255, 0.06));
    color: var(--danger, #e04b4b);
}
.settings-permission-card-icon svg { width: 18px; height: 18px; display: block; }
.settings-permission-card-text {
    display: flex;
    flex-direction: column;
    gap: 2px;
    min-width: 0;
}
.settings-permission-card-text strong {
    font-size: 14px;
    font-weight: 600;
    color: var(--text-primary);
}
.settings-permission-card-text span {
    font-size: 12px;
    color: var(--text-muted);
    line-height: 1.4;
}

/* Devices block — header with title + count, then a column of cards. */
.push-devices-block { padding-bottom: 8px; }
.push-devices-header {
    display: flex;
    align-items: baseline;
    gap: 6px;
    margin-bottom: 10px;
}
.push-devices-header .settings-section-title { margin: 0; }
.push-devices-count {
    color: var(--text-muted);
    font-size: 12px;
    font-weight: 500;
}

#push-devices-list {
    display: flex;
    flex-direction: column;
    gap: 6px;
}

.push-device-card {
    display: flex;
    align-items: center;
    gap: 12px;
    padding: 10px 12px;
    background: var(--bg-tertiary, rgba(255, 255, 255, 0.03));
    border: 1px solid transparent;
    border-radius: 8px;
    transition: border-color 0.12s, background 0.12s;
}
.push-device-card:hover {
    border-color: var(--border-color, rgba(255, 255, 255, 0.08));
    background: var(--bg-input, var(--bg-tertiary));
}

/* Letter-circle for browser glyph — same visual mechanic as the
   pack-cover fallback in the Stickers tab. Hue derived from the
   browser name so Chrome / Firefox / Safari / Edge each get a stable
   distinct accent without us shipping brand logos. */
.push-device-icon {
    flex-shrink: 0;
    width: 40px;
    height: 40px;
    border-radius: 10px;
    display: flex;
    align-items: center;
    justify-content: center;
    font-size: 16px;
    font-weight: 700;
    color: hsl(var(--push-device-hue, 220), 70%, 92%);
    background: hsl(var(--push-device-hue, 220), 60%, 26%);
    text-shadow: 0 1px 2px rgba(0, 0, 0, 0.3);
}

.push-device-meta {
    flex: 1;
    min-width: 0;
    display: flex;
    flex-direction: column;
    gap: 2px;
}
.push-device-name-row {
    display: flex;
    align-items: center;
    gap: 8px;
    flex-wrap: wrap;
}
.push-device-name {
    font-size: 14px;
    font-weight: 600;
    color: var(--text-primary);
}
.push-device-current-pill {
    display: inline-flex;
    align-items: center;
    padding: 1px 8px;
    border-radius: 999px;
    background: var(--accent, #5865f2);
    color: #fff;
    font-size: 11px;
    font-weight: 500;
    line-height: 1.6;
}
.push-device-subline {
    font-size: 12px;
    color: var(--text-muted);
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

/* Empty-state — no active devices. Centered icon + text. */
.push-devices-empty {
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    gap: 8px;
    padding: 28px 20px;
    text-align: center;
}
.push-devices-empty-icon {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 48px;
    height: 48px;
    border-radius: 50%;
    background: var(--bg-tertiary, rgba(255, 255, 255, 0.05));
    color: var(--text-muted);
}
.push-devices-empty-icon svg { width: 24px; height: 24px; display: block; }
.push-devices-empty-title {
    font-size: 14px;
    font-weight: 600;
    color: var(--text-secondary);
}
.push-devices-empty-hint {
    font-size: 12px;
    color: var(--text-muted);
}

/* Outline-style danger button — used for revoke on device cards so a
   row of three full-fill red buttons doesn't dominate the section.
   Fills on hover for affordance. */
.btn-ghost-danger {
    background: transparent;
    color: var(--danger, #e04b4b);
    border: 1px solid var(--danger, #e04b4b);
    padding: 5px 12px;
    border-radius: 999px;
    font-size: 12px;
    font-weight: 600;
    cursor: pointer;
    flex-shrink: 0;
    transition: background 0.12s, color 0.12s, transform 0.08s;
}
.btn-ghost-danger:hover {
    background: var(--danger, #e04b4b);
    color: #fff;
}
.btn-ghost-danger:active {
    transform: scale(0.97);
}

/* Privacy tab — radio groups */
.privacy-group { display: flex; flex-direction: column; gap: 4px; }
.privacy-radio { display: flex; align-items: center; gap: 10px; padding: 8px 12px; cursor: pointer; border-radius: 6px; transition: background 0.12s; }
.privacy-radio:hover { background: var(--bg-tertiary); }
.privacy-radio input[type=radio] { margin: 0; cursor: pointer; }
.privacy-radio span { user-select: none; }
