/* ==========================================================================
   OWN Locator — shared styles with light and dark themes
   ========================================================================= */

:root {
    --sidebar-width: 260px;
    --events-width: 296px;

    --radius-xs: 8px;
    --radius-sm: 12px;
    --radius-md: 18px;
    --radius-lg: 24px;
    --radius-pill: 999px;

    --shadow-sm: 0 12px 30px rgba(5, 8, 16, 0.12);
    --shadow-md: 0 20px 50px rgba(5, 8, 16, 0.18);
    --shadow-lg: 0 30px 80px rgba(5, 8, 16, 0.28);

    --font: "Segoe UI", "Inter", "Helvetica Neue", Arial, sans-serif;
    --font-mono: "JetBrains Mono", "SFMono-Regular", "Consolas", monospace;

    --transition-fast: 160ms ease;
    --transition-base: 220ms ease;
}

:root,
html[data-theme="dark"] {
    --bg-primary: #0a1222;
    --bg-secondary: #111929;
    --bg-tertiary: #151f31;
    --bg-card: rgba(21, 31, 49, 0.92);
    --bg-card-elevated: rgba(34, 45, 66, 0.98);
    --bg-hover: rgba(0, 135, 113, 0.14);
    --bg-input: rgba(14, 22, 34, 0.92);
    --bg-overlay: rgba(4, 11, 20, 0.74);
    --bg-gradient:
        radial-gradient(
            circle at top left,
            rgba(0, 135, 113, 0.18),
            transparent 34%
        ),
        radial-gradient(
            circle at top right,
            rgba(37, 169, 255, 0.1),
            transparent 30%
        ),
        linear-gradient(180deg, #081120 0%, #0a1222 100%);
    --bg-login:
        radial-gradient(
            circle at 14% 18%,
            rgba(0, 135, 113, 0.22),
            transparent 26%
        ),
        radial-gradient(
            circle at 86% 12%,
            rgba(57, 155, 255, 0.16),
            transparent 20%
        ),
        linear-gradient(180deg, #081120 0%, #0d1729 100%);
    --bg-sidebar: linear-gradient(
        180deg,
        rgba(16, 25, 41, 0.98) 0%,
        rgba(12, 18, 31, 0.98) 100%
    );

    --text-primary: rgba(255, 255, 255, 0.88);
    --text-secondary: rgba(226, 235, 252, 0.72);
    --text-muted: rgba(180, 198, 231, 0.52);
    --text-soft: rgba(148, 168, 204, 0.4);

    --accent: #008771;
    --accent-hover: #089883;
    --accent-dim: rgba(0, 135, 113, 0.18);

    --success: #3ad3ba;
    --warning: #ffa031;
    --danger: #e84749;
    --info: #52a6ff;

    --border: rgba(87, 106, 139, 0.3);
    --border-light: rgba(111, 136, 176, 0.42);

    --card-outline: rgba(255, 255, 255, 0.03);
    --table-stripe: rgba(255, 255, 255, 0.012);
    --table-hover: rgba(0, 135, 113, 0.08);
    --marker-label-bg: rgba(10, 18, 34, 0.9);
}

html[data-theme="light"] {
    --bg-primary: #eef4f3;
    --bg-secondary: #f4f8f7;
    --bg-tertiary: #ffffff;
    --bg-card: rgba(255, 255, 255, 0.94);
    --bg-card-elevated: rgba(255, 255, 255, 0.99);
    --bg-hover: rgba(0, 135, 113, 0.08);
    --bg-input: rgba(247, 250, 249, 0.98);
    --bg-overlay: rgba(11, 19, 28, 0.42);
    --bg-gradient:
        radial-gradient(
            circle at top left,
            rgba(0, 135, 113, 0.14),
            transparent 36%
        ),
        radial-gradient(
            circle at top right,
            rgba(89, 169, 255, 0.11),
            transparent 28%
        ),
        linear-gradient(180deg, #f4f8f7 0%, #ecf2f1 100%);
    --bg-login:
        radial-gradient(
            circle at 18% 18%,
            rgba(0, 135, 113, 0.16),
            transparent 24%
        ),
        radial-gradient(
            circle at 82% 12%,
            rgba(89, 169, 255, 0.14),
            transparent 18%
        ),
        linear-gradient(180deg, #f5f9f8 0%, #edf3f2 100%);
    --bg-sidebar: linear-gradient(
        180deg,
        rgba(255, 255, 255, 0.96) 0%,
        rgba(247, 251, 250, 0.98) 100%
    );

    --text-primary: #18303b;
    --text-secondary: #4d6570;
    --text-muted: #69808a;
    --text-soft: #94a9b1;

    --accent: #008771;
    --accent-hover: #0b9b84;
    --accent-dim: rgba(0, 135, 113, 0.14);

    --success: #0a9c72;
    --warning: #b86f00;
    --danger: #ce3d4d;
    --info: #1d76d2;

    --border: rgba(24, 48, 59, 0.09);
    --border-light: rgba(24, 48, 59, 0.16);

    --shadow-sm: 0 10px 24px rgba(16, 37, 47, 0.08);
    --shadow-md: 0 18px 48px rgba(16, 37, 47, 0.12);
    --shadow-lg: 0 30px 80px rgba(16, 37, 47, 0.14);

    --card-outline: rgba(24, 48, 59, 0.02);
    --table-stripe: rgba(24, 48, 59, 0.018);
    --table-hover: rgba(0, 135, 113, 0.06);
    --marker-label-bg: rgba(255, 255, 255, 0.92);
}

* {
    box-sizing: border-box;
}

html,
body {
    min-height: 100%;
}

html {
    scroll-behavior: smooth;
}

body {
    margin: 0;
    position: relative;
    font-family: var(--font);
    font-size: 16px;
    line-height: 1.5;
    color: var(--text-primary);
    background: var(--bg-gradient);
    transition:
        background var(--transition-base),
        color var(--transition-base);
    -webkit-font-smoothing: antialiased;
    text-rendering: optimizeLegibility;
}

body::before {
    content: "";
    position: fixed;
    inset: 0;
    pointer-events: none;
    background:
        radial-gradient(
            circle at 18% 0%,
            rgba(255, 255, 255, 0.05),
            transparent 28%
        ),
        radial-gradient(
            circle at 100% 10%,
            rgba(255, 255, 255, 0.03),
            transparent 20%
        );
    opacity: 0.8;
}

a {
    color: inherit;
}

button,
input,
select,
textarea {
    font: inherit;
}

h1,
h2,
h3,
p {
    margin-top: 0;
}

h1 {
    font-size: clamp(1.8rem, 2vw, 2.4rem);
    line-height: 1.1;
    margin-bottom: 0;
}

h2 {
    font-size: 1.1rem;
    line-height: 1.2;
    margin-bottom: 0;
}

h3 {
    font-size: 1rem;
    line-height: 1.2;
    margin-bottom: 0;
}

.text-muted {
    color: var(--text-muted);
}

.text-secondary {
    color: var(--text-secondary);
}

code {
    font-family: var(--font-mono);
}

/* ==========================================================================
   Forms
   ========================================================================= */

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

.form-group label,
.form-label {
    display: block;
    margin-bottom: 8px;
    font-size: 0.82rem;
    font-weight: 700;
    letter-spacing: 0.04em;
    text-transform: uppercase;
    color: var(--text-secondary);
}

.form-label-row {
    display: flex;
    align-items: baseline;
    justify-content: space-between;
    flex-wrap: wrap;
    gap: 8px 14px;
}

.form-label-row .form-label {
    margin-bottom: 0;
}

input[type="text"],
input[type="password"],
input[type="email"],
input[type="number"],
input[type="search"],
select,
textarea,
.form-input,
.form-select,
.lang-select {
    width: 100%;
    appearance: none;
    border: 1px solid var(--border);
    background: var(--bg-input);
    color: var(--text-primary);
    border-radius: var(--radius-sm);
    padding: 11px 14px;
    transition:
        border-color var(--transition-fast),
        background var(--transition-fast),
        box-shadow var(--transition-fast),
        transform var(--transition-fast);
}

textarea {
    min-height: 120px;
    resize: vertical;
}

input:hover,
select:hover,
textarea:hover,
.form-input:hover,
.form-select:hover,
.lang-select:hover {
    border-color: var(--border-light);
}

input:focus,
select:focus,
textarea:focus,
.form-input:focus,
.form-select:focus,
.lang-select:focus {
    outline: none;
    border-color: var(--accent);
    box-shadow: 0 0 0 4px var(--accent-dim);
}

.lang-select {
    min-width: 110px;
    cursor: pointer;
    padding-right: 34px;
    background-image:
        linear-gradient(45deg, transparent 50%, var(--text-muted) 50%),
        linear-gradient(135deg, var(--text-muted) 50%, transparent 50%);
    background-position:
        calc(100% - 18px) calc(50% - 2px),
        calc(100% - 12px) calc(50% - 2px);
    background-size:
        6px 6px,
        6px 6px;
    background-repeat: no-repeat;
}

.form-hint {
    margin: 6px 0 0;
    color: var(--text-muted);
    font-size: 0.86rem;
}

.form-hint-warning {
    color: var(--warning);
    font-weight: 800;
}

.form-link {
    color: var(--accent);
    font-weight: 600;
    text-decoration: none;
}

.form-link:hover {
    color: var(--accent-hover);
    text-decoration: underline;
}

.form-label-link {
    margin-left: auto;
    font-size: 0.86rem;
    font-weight: 600;
    letter-spacing: normal;
    text-align: right;
    text-transform: none;
}

.checkbox-field {
    display: inline-flex !important;
    align-items: center;
    gap: 10px;
    margin-bottom: 0 !important;
    cursor: pointer;
    text-transform: none !important;
    letter-spacing: normal !important;
}

.checkbox-field input[type="checkbox"] {
    width: 16px;
    height: 16px;
    margin: 0;
    flex-shrink: 0;
    accent-color: var(--accent);
}

.checkbox-field span {
    display: block;
    color: var(--text-primary);
    font-size: 0.95rem;
    font-weight: 600;
}

.form-error {
    margin-top: 8px;
    padding: 10px 12px;
    border: 1px solid rgba(255, 107, 122, 0.28);
    border-radius: var(--radius-sm);
    background: rgba(255, 107, 122, 0.08);
    color: var(--danger);
    font-size: 0.92rem;
}

.form-actions {
    display: flex;
    flex-wrap: wrap;
    gap: 10px;
}

/* Pushes children to the right edge of the row — used for destructive
   actions ("Удалить все события" on the dashboard, "Выйти со всех
   устройств" on user-detail) so they sit visually away from the
   primary content. Mirrors what user-detail-sessions does locally. */
.form-actions-end {
    justify-content: flex-end;
    margin-top: 16px;
}

.filter-group {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: 8px;
}

/* ==========================================================================
   Buttons and badges
   ========================================================================= */

.btn {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    gap: 8px;
    min-height: 42px;
    padding: 10px 18px;
    border: 1px solid transparent;
    border-radius: var(--radius-pill);
    cursor: pointer;
    font-weight: 700;
    text-decoration: none;
    white-space: nowrap;
    transition:
        transform var(--transition-fast),
        background var(--transition-fast),
        border-color var(--transition-fast),
        color var(--transition-fast),
        box-shadow var(--transition-fast);
}

.btn:hover {
    transform: translateY(-1px);
}

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

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

.btn-primary {
    background: linear-gradient(
        135deg,
        var(--accent) 0%,
        var(--accent-hover) 100%
    );
    color: #fff;
    box-shadow: 0 12px 24px rgba(0, 0, 0, 0.18);
}

.btn-primary:hover {
    box-shadow: 0 16px 32px rgba(0, 0, 0, 0.22);
}

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

.btn-secondary:hover,
.btn-outline:hover {
    border-color: var(--accent);
    color: var(--accent);
    background: var(--accent-dim);
}

.btn-outline {
    background: transparent;
    border-color: var(--border-light);
    color: var(--text-primary);
}

.btn-danger {
    background: rgba(255, 107, 122, 0.12);
    border-color: rgba(255, 107, 122, 0.26);
    color: var(--danger);
}

.btn-danger:hover {
    background: rgba(255, 107, 122, 0.18);
}

.btn-success {
    background: rgba(51, 196, 143, 0.12);
    border-color: rgba(51, 196, 143, 0.28);
    color: var(--success);
}

.btn-success:hover {
    background: rgba(51, 196, 143, 0.18);
}

.btn-warning {
    background: rgba(245, 183, 74, 0.12);
    border-color: rgba(245, 183, 74, 0.3);
    color: var(--warning);
}

.btn-warning:hover {
    background: rgba(245, 183, 74, 0.2);
}

.btn-sm {
    min-height: 34px;
    padding: 7px 14px;
    font-size: 0.86rem;
}

.btn-large {
    min-height: 48px;
    padding: 12px 26px;
    font-size: 1rem;
}

.btn-block {
    width: 100%;
}

.badge {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    min-height: 28px;
    padding: 4px 10px;
    border-radius: var(--radius-pill);
    border: 1px solid transparent;
    font-size: 0.78rem;
    font-weight: 700;
}

.badge-success {
    background: rgba(51, 196, 143, 0.12);
    border-color: rgba(51, 196, 143, 0.28);
    color: var(--success);
}

.badge-warning {
    background: rgba(245, 183, 74, 0.12);
    border-color: rgba(245, 183, 74, 0.28);
    color: var(--warning);
}

.badge-danger {
    background: rgba(255, 107, 122, 0.12);
    border-color: rgba(255, 107, 122, 0.26);
    color: var(--danger);
}

.badge-info {
    background: rgba(73, 167, 255, 0.12);
    border-color: rgba(73, 167, 255, 0.26);
    color: var(--info);
}

.badge-default {
    background: rgba(128, 145, 170, 0.12);
    border-color: rgba(128, 145, 170, 0.24);
    color: var(--text-secondary);
}

/* User-group badges — shared across /admin/users, /admin/circles member
   lists, and the /app member profile modal. Colour coding mirrors the
   Android client: red (admin), amber (advanced), grey (participant),
   muted grey (guest). */
.user-group-admin {
    background: rgba(255, 107, 122, 0.12);
    border-color: rgba(255, 107, 122, 0.26);
    color: var(--danger);
}
.user-group-advanced {
    background: rgba(245, 183, 74, 0.12);
    border-color: rgba(245, 183, 74, 0.28);
    color: var(--warning);
}
.user-group-participant {
    background: rgba(128, 145, 170, 0.12);
    border-color: rgba(128, 145, 170, 0.24);
    color: var(--text-secondary);
}
.user-group-guest {
    background: rgba(128, 145, 170, 0.08);
    border-color: rgba(128, 145, 170, 0.18);
    color: var(--text-muted);
}

/* ==========================================================================
   Alerts
   ========================================================================= */

.alert {
    padding: 14px 16px;
    border-radius: var(--radius-md);
    border: 1px solid transparent;
}

.alert-success {
    background: rgba(51, 196, 143, 0.1);
    border-color: rgba(51, 196, 143, 0.24);
    color: var(--success);
}

.alert-warning {
    background: rgba(245, 183, 74, 0.12);
    border-color: rgba(245, 183, 74, 0.24);
    color: var(--warning);
}

/* ==========================================================================
   Theme picker
   ========================================================================= */

.theme-picker {
    display: grid;
    gap: 10px;
}

.theme-picker-label {
    font-size: 0.72rem;
    font-weight: 800;
    letter-spacing: 0.1em;
    text-transform: uppercase;
    color: var(--text-muted);
}

.theme-picker-options {
    display: grid;
    grid-template-columns: repeat(2, minmax(0, 1fr));
    gap: 6px;
}

.theme-option {
    border: 1px solid var(--border);
    background: var(--bg-input);
    color: var(--text-secondary);
    border-radius: var(--radius-sm);
    padding: 10px 8px;
    font-size: 0.78rem;
    font-weight: 700;
    cursor: pointer;
    transition:
        border-color var(--transition-fast),
        background var(--transition-fast),
        color var(--transition-fast),
        transform var(--transition-fast),
        box-shadow var(--transition-fast);
}

.theme-option:hover {
    border-color: var(--border-light);
    color: var(--text-primary);
    transform: translateY(-1px);
}

.theme-option.active {
    background: var(--accent-dim);
    border-color: rgba(255, 255, 255, 0.08);
    color: var(--accent);
    box-shadow: inset 0 0 0 1px rgba(255, 255, 255, 0.04);
}

html[data-theme="light"] .theme-option.active {
    border-color: rgba(0, 135, 113, 0.22);
}

/* ==========================================================================
   Login
   ========================================================================= */

.login-container {
    min-height: 100vh;
    display: grid;
    place-items: center;
    padding: 32px 20px;
    background: var(--bg-login);
}

.login-card {
    width: min(100%, 460px);
    padding: 38px 34px 28px;
    border-radius: 32px;
    border: 1px solid var(--border);
    background:
        linear-gradient(180deg, rgba(255, 255, 255, 0.03), transparent 26%),
        var(--bg-card-elevated);
    box-shadow: var(--shadow-lg);
    position: relative;
    overflow: hidden;
}

.login-card::before {
    content: "";
    position: absolute;
    inset: auto auto -110px -80px;
    width: 220px;
    height: 220px;
    border-radius: 50%;
    background: radial-gradient(circle, var(--accent-dim) 0%, transparent 70%);
    pointer-events: none;
}

.login-header {
    text-align: center;
    margin-bottom: 28px;
}

.login-logo {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 82px;
    height: 82px;
    border-radius: 28px;
    margin-bottom: 16px;
    background: rgba(255, 255, 255, 0.04);
    border: 1px solid var(--border);
    box-shadow: inset 0 1px 0 var(--card-outline);
}

.login-header h1 {
    margin-bottom: 8px;
}

.login-footer {
    margin-top: 24px;
    display: grid;
    gap: 14px;
}

.login-footer .lang-select {
    width: 100%;
}

/* ==========================================================================
   Admin layout
   ========================================================================= */

.app-layout {
    min-height: 100vh;
}

.sidebar {
    position: fixed;
    inset: 0 auto 0 0;
    width: var(--sidebar-width);
    display: flex;
    flex-direction: column;
    background: var(--bg-sidebar);
    border-right: 1px solid var(--border);
    box-shadow: var(--shadow-md);
    backdrop-filter: blur(20px);
    z-index: 100;
}

.sidebar-header {
    display: flex;
    align-items: center;
    gap: 12px;
    /* 18 + 28 (logo row) + 18 = 64 + 1 border = 65px to the line.
     Same math as .app-sidebar-header on /app so the two sidebars
     line up pixel-for-pixel across admin and user pages. */
    padding: 18px 14px;
    border-bottom: 1px solid var(--border);
}

.sidebar-logo {
    display: inline-flex;
    align-items: center;
    justify-content: center;
}

.sidebar-title {
    font-size: 1.06rem;
    font-weight: 800;
    letter-spacing: 0.02em;
    color: var(--text-primary);
}

.sidebar-nav {
    flex: 1;
    padding: 14px 10px;
    overflow-y: auto;
}

.nav-item {
    width: 100%;
    display: flex;
    align-items: center;
    gap: 12px;
    margin-bottom: 6px;
    padding: 12px 14px;
    border: 1px solid transparent;
    border-radius: var(--radius-sm);
    background: transparent;
    color: var(--text-secondary);
    text-decoration: none;
    cursor: pointer;
    transition:
        background var(--transition-fast),
        border-color var(--transition-fast),
        color var(--transition-fast),
        transform var(--transition-fast);
}

.nav-item:hover {
    background: var(--bg-hover);
    border-color: rgba(255, 255, 255, 0.04);
    color: var(--text-primary);
    transform: translateX(2px);
}

.nav-item.active {
    background: linear-gradient(90deg, var(--accent-dim) 0%, transparent 100%);
    border-color: rgba(255, 255, 255, 0.06);
    color: var(--accent);
}

.nav-item svg {
    flex-shrink: 0;
}

.sidebar-footer {
    display: grid;
    gap: 12px;
    padding: 16px 12px 18px;
    border-top: 1px solid var(--border);
    background: rgba(255, 255, 255, 0.01);
}

.sidebar-lang {
    display: flex;
}

.logout-btn {
    color: var(--danger) !important;
}

.logout-btn:hover {
    background: rgba(255, 107, 122, 0.08);
    border-color: rgba(255, 107, 122, 0.16);
}

.main-content {
    min-height: 100vh;
    margin-left: var(--sidebar-width);
    padding: 32px;
}

/* Admin top-bar — layout only. The title text inside is wrapped in
   <span class="page-header-font">…</span> on every admin screen so
   the typography knob lives in exactly one rule (.page-header-font
   below). Pages with action buttons next to the title put them in a
   sibling .page-header-actions block; the flex layout here handles
   the title-left / actions-right arrangement on wide screens and the
   @media (max-width: 768px) override below stacks them vertically
   on narrow ones. */
.page-header {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 16px;
    margin-bottom: 24px;
}
/* Single knob for the title font size on every /admin/* page. Used
   by dashboard / users / circles / api-keys / audit / devices /
   settings / user-detail (the back-link). Change here → every
   heading scales together. */
.page-header-font {
    font-size: 1.8rem;
    font-weight: 600;
    line-height: 1.2;
    letter-spacing: -0.02em;
}
/* ==========================================================================
   Cards and statistics
   ========================================================================= */

.card,
.stat-card,
.login-card,
.modal-dialog {
    box-shadow: var(--shadow-sm);
}

.card {
    position: relative;
    overflow: hidden;
    border-radius: 26px;
    border: 1px solid var(--border);
    background:
        linear-gradient(180deg, rgba(255, 255, 255, 0.035), transparent 24%),
        var(--bg-card);
    box-shadow: var(--shadow-md);
}

.card::before {
    content: "";
    position: absolute;
    inset: 0;
    border-radius: inherit;
    border: 1px solid var(--card-outline);
    pointer-events: none;
}

.card-header {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 12px;
    padding: 20px 22px 16px;
    border-bottom: 1px solid var(--border);
}

.card-body {
    padding: 20px 22px 22px;
}

.card-body-stretch {
    display: flex;
    flex-direction: column;
    flex: 1 1 auto;
    min-height: 0;
}

.card-body-content {
    flex: 1 1 auto;
}

.settings-secondary-grid {
    display: grid;
    grid-template-columns: repeat(2, minmax(0, 1fr));
    gap: 18px;
    margin-top: 18px;
}

/* Admin · User-detail "← Пользователи" back-link. The font-size and
   weight come from .page-header on the parent <div>, so this rule
   only takes care of the link-specific bits (primary text colour,
   no underline, accent on hover). The user-detail page uses the
   same .page-header wrapper as every other admin screen — no extra
   page-modifier class, so all heading bands stay visually identical. */
.user-detail-back {
    color: var(--text-primary);
    text-decoration: none;
}
.user-detail-back:hover {
    color: var(--accent);
}

/* ── Admin · User detail split (Аккаунт 30% | Активные сессии 70%) ─────── */
.user-detail-card {
    /* The split lays out two sections side-by-side; .card-header is replaced
     by per-section headers so we drop the outer header padding. */
}
.user-detail-split {
    display: grid;
    grid-template-columns: minmax(0, 30fr) minmax(0, 70fr);
    gap: 0;
}
.user-detail-split > section {
    min-width: 0;
    padding: 20px 22px 22px;
}
.user-detail-split > .user-detail-account {
    border-right: 1px solid var(--border);
}
.user-detail-section-header {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 12px;
    /* Explicit fixed height — NOT min-height — so the bare-text left
     header ("Аккаунт") sits at exactly the same vertical extent as
     the badge-carrying right header ("Активные сессии"). With only
     min-height the bare-text variant collapses to its content height
     in some browsers and the bottom border ends up higher than the
     badge-stretched one across the column gutter; height + flex
     align-items: center pins both at the same Y. The 1px divider
     itself lives at: section padding-top (20px) + this 28px header
     row + 14px padding-bottom = 62px below the card edge. */
    height: 28px;
    padding-bottom: 14px;
    margin-bottom: 18px;
    border-bottom: 1px solid var(--border);
    /* Allow the explicit height to take effect on the box-model so
     padding-bottom doesn't add on top of it. */
    box-sizing: content-box;
}
.user-detail-section-header h2 {
    margin: 0;
    font-size: 1rem;
    font-weight: 600;
    line-height: 1.2;
}
.user-detail-section-body {
    min-width: 0;
}
/* Sessions section: column layout so the "Выйти со всех устройств"
   button auto-margins down and aligns to the right edge. The flex
   stretching is what pushes the button to the bottom of the right
   column even when the account section on the left is taller. */
.user-detail-sessions {
    display: flex;
    flex-direction: column;
}
.user-detail-sessions .user-detail-section-body {
    display: flex;
    flex-direction: column;
    flex: 1 1 auto;
}
.user-detail-sessions .form-actions {
    margin-top: auto;
    justify-content: flex-end;
}
@media (max-width: 900px) {
    /* Stack vertically on narrow screens — no horizontal squeeze. */
    .user-detail-split {
        grid-template-columns: 1fr;
    }
    .user-detail-split > .user-detail-account {
        border-right: none;
        border-bottom: 1px solid var(--border);
    }
}

/* On the user-detail account column, lay the avatar in a 140px
   first track so the name + role chip align with the value column
   (140px label + 14px gap = 154px from the section's left edge)
   of the rows below. Reads as "label : value" continuity from
   the avatar block all the way through the field rows. */
.user-detail-account .member-profile {
    display: grid;
    grid-template-columns: 140px 1fr;
    gap: 14px;
    align-items: center;
}
.user-detail-account .member-profile-avatar {
    /* Stay anchored to the left edge of the 140px track instead of
     stretching to fill it — the avatar visual stays its own size. */
    justify-self: start;
}

.settings-secondary-grid > .card {
    display: flex;
    flex-direction: column;
}

.card-body-stretch > .form-actions {
    margin-top: auto;
}

.stats-grid {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(220px, 1fr));
    gap: 16px;
    margin-bottom: 24px;
}

.stat-card {
    position: relative;
    display: flex;
    align-items: center;
    gap: 16px;
    padding: 20px;
    border-radius: 24px;
    border: 1px solid var(--border);
    background:
        linear-gradient(180deg, rgba(255, 255, 255, 0.035), transparent 26%),
        var(--bg-card);
    transition:
        transform var(--transition-base),
        border-color var(--transition-base),
        box-shadow var(--transition-base);
}

.stat-card:hover {
    transform: translateY(-3px);
    border-color: var(--border-light);
    box-shadow: var(--shadow-md);
}

.stat-icon {
    width: 50px;
    height: 50px;
    border-radius: 18px;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    flex-shrink: 0;
    border: 1px solid transparent;
}

.stat-icon.users-icon {
    background: rgba(127, 112, 240, 0.14);
    border-color: rgba(127, 112, 240, 0.2);
    color: var(--accent);
}

.stat-icon.circles-icon {
    background: rgba(73, 167, 255, 0.12);
    border-color: rgba(73, 167, 255, 0.18);
    color: var(--info);
}

.stat-icon.devices-icon {
    background: rgba(51, 196, 143, 0.12);
    border-color: rgba(51, 196, 143, 0.18);
    color: var(--success);
}

.stat-icon.active-icon {
    background: rgba(245, 183, 74, 0.12);
    border-color: rgba(245, 183, 74, 0.18);
    color: var(--warning);
}

.stat-info {
    display: grid;
    gap: 4px;
}

.stat-value {
    font-size: clamp(1.7rem, 2vw, 2.1rem);
    line-height: 1;
    font-weight: 800;
    letter-spacing: -0.04em;
}

.stat-label {
    color: var(--text-secondary);
    font-size: 0.84rem;
    font-weight: 600;
}

/* ==========================================================================
   Tables
   ========================================================================= */

.table-wrapper {
    overflow-x: auto;
}

table,
.data-table {
    width: 100%;
    border-collapse: collapse;
}

th,
td,
.data-table th,
.data-table td {
    text-align: center;
    padding: 12px 12px;
    border-bottom: 1px solid var(--border);
    vertical-align: middle;
}

th,
.data-table th {
    font-size: 0.75rem;
    font-weight: 800;
    letter-spacing: 0.08em;
    text-transform: uppercase;
    color: var(--text-muted);
}

.data-table tbody tr:nth-child(even) {
    background: var(--table-stripe);
}

/* Stacked "name + email" cell shared by /admin/users, /admin/circles
   (owner column), and /admin/devices (user column). Name reads as the
   primary label centred over the email; the email sits underneath at
   a smaller font + secondary text colour so the two scan as a unit
   without ballooning row height. The container is text-align: center
   so the name line centres relative to whichever sub-line is wider. */
.user-cell {
    display: flex;
    flex-direction: column;
    align-items: center;
    line-height: 1.25;
    gap: 2px;
}
.user-cell-name {
    font-weight: 600;
}
.user-cell-email {
    font-size: 0.85em;
    color: var(--text-secondary);
    word-break: break-all;
}

tr:hover td,
.data-table tbody tr:hover td {
    background: var(--table-hover);
}

.data-table tbody tr.clickable-row {
    cursor: pointer;
}

.data-table code,
.modal-body code {
    display: inline-flex;
    align-items: center;
    min-height: 30px;
    padding: 4px 8px;
    border-radius: 10px;
    background: var(--accent-dim);
    color: var(--accent);
    font-size: 0.8rem;
    word-break: break-all;
}

.table-pagination {
    display: flex;
    align-items: center;
    gap: 12px;
    padding-top: 14px;
    color: var(--text-secondary);
    font-size: 0.9rem;
}

/* ==========================================================================
   Event lists
   ========================================================================= */

.events-list,
.events-feed {
    display: grid;
    gap: 10px;
}

.events-list .event-item,
.events-feed .event-item {
    display: flex;
    align-items: flex-start;
    gap: 12px;
    padding: 12px 14px;
    border-radius: 16px;
    border: 1px solid var(--border);
    background: rgba(255, 255, 255, 0.02);
}

.events-list .event-item.warning,
.events-feed .event-item.warning {
    background: rgba(245, 183, 74, 0.08);
}

.events-list .event-item.critical,
.events-feed .event-item.critical {
    background: rgba(255, 107, 122, 0.08);
}

.event-icon {
    flex-shrink: 0;
    font-size: 1.05rem;
    margin-top: 2px;
}

.event-body {
    display: grid;
    gap: 2px;
    min-width: 0;
}

.event-text,
.event-type {
    color: var(--text-primary);
    font-size: 0.9rem;
}

.event-time {
    color: var(--text-muted);
    font-size: 0.8rem;
}

/* ==========================================================================
   Public landing
   ========================================================================= */

.public-layout {
    min-height: 100vh;
    display: grid;
    place-items: center;
    padding: 32px 18px;
}

.landing-container {
    width: min(100%, 540px);
    padding: 42px 34px 30px;
    border-radius: 34px;
    text-align: center;
    border: 1px solid var(--border);
    background:
        linear-gradient(180deg, rgba(255, 255, 255, 0.035), transparent 24%),
        var(--bg-card-elevated);
    box-shadow: var(--shadow-lg);
}

.landing-logo {
    margin-bottom: 18px;
}

.landing-title {
    margin-bottom: 10px;
    font-size: clamp(2rem, 3vw, 2.6rem);
    letter-spacing: -0.05em;
}

.landing-subtitle {
    margin-bottom: 24px;
    color: var(--text-secondary);
    font-size: 1.02rem;
}

.landing-actions {
    display: grid;
    justify-items: center;
    gap: 12px;
    margin-bottom: 22px;
}

.landing-hint {
    margin-top: 14px;
    color: var(--text-muted);
    font-size: 0.9rem;
}

.lang-switcher-center {
    margin-top: 22px;
    display: flex;
    justify-content: center;
    flex-direction: column;
    align-items: center;
    gap: 14px;
}

.lang-switcher-center .theme-picker,
.lang-switcher-center .lang-select {
    width: min(100%, 320px);
}

/* ==========================================================================
   App shell
   ========================================================================= */

.app-shell {
    display: grid;
    grid-template-columns: var(--sidebar-width) 1fr var(--events-width);
    /* Hard-clamp the shell to the viewport height so overflowing children
     (long member list, long messages panel) scroll INSIDE their column
     instead of stretching the page vertically. Matches what the
     messenger-mode override already does. */
    height: 100vh;
    overflow: hidden;
    position: relative;
}

.app-sidebar,
.events-panel {
    display: flex;
    flex-direction: column;
    background: var(--bg-sidebar);
    backdrop-filter: blur(20px);
    overflow-y: auto;
    z-index: 10;
}

.app-sidebar {
    border-right: 1px solid var(--border);
}

.events-panel {
    border-left: 1px solid var(--border);
}

.app-sidebar-header {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 12px;
    padding: 18px 14px;
    border-bottom: 1px solid var(--border);
}

.app-logo {
    display: flex;
    align-items: center;
    gap: 10px;
    color: var(--text-primary);
    font-size: 0.95rem;
    font-weight: 800;
}

.app-sidebar-footer {
    margin-top: auto;
    display: grid;
    gap: 10px;
    padding: 14px;
    border-top: 1px solid var(--border);
}

/* Lives inside .app-sidebar-footer. The wrapper itself is stuck to the
   bottom of the sidebar via margin-top:auto, so these buttons end up
   directly above the theme/language/logout rows regardless of the
   member-list length. */
.sidebar-quick-actions {
    display: grid;
    gap: 8px;
}

/* Radio list used by the "Access mode" settings card. Vertical stack, each
   row has the radio input on the left and label text on the right. */
.radio-group {
    display: grid;
    gap: 10px;
}
.radio-field {
    display: flex;
    align-items: flex-start;
    gap: 10px;
    cursor: pointer;
    line-height: 1.4;
}
.radio-field input[type="radio"] {
    margin-top: 4px;
    flex-shrink: 0;
}

/* Inline token display + copy/regenerate buttons. */
.token-row {
    display: flex;
    align-items: center;
    gap: 8px;
    flex-wrap: wrap;
}
.token-value {
    flex: 1 1 200px;
    padding: 6px 10px;
    background: var(--bg-card);
    border: 1px solid var(--border);
    border-radius: 6px;
    font-family: monospace;
    font-size: 0.9rem;
    word-break: break-all;
}

.sidebar-divider {
    margin: 4px 0;
    border: 0;
    border-top: 1px solid var(--border);
}

.footer-row {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 10px;
}

.section-label {
    padding: 14px 14px 8px;
    color: var(--text-muted);
    font-size: 0.72rem;
    font-weight: 800;
    letter-spacing: 0.1em;
    text-transform: uppercase;
}

.circle-list,
.member-list {
    padding: 4px 10px 10px;
}

.circle-item,
.member-item {
    display: flex;
    align-items: center;
    gap: 10px;
    padding: 10px 12px;
    border-radius: 16px;
    color: var(--text-secondary);
    cursor: pointer;
    transition:
        background var(--transition-fast),
        color var(--transition-fast),
        transform var(--transition-fast);
}

.circle-item:hover,
.member-item:hover {
    background: var(--bg-hover);
    color: var(--text-primary);
}

.circle-item.active {
    background: var(--accent-dim);
    color: var(--accent);
}

.member-item.active {
    /* Telegram-style active pill: full accent-dim tint + a crisp
     1px accent border so the selected row stands out at a glance
     even against the sidebar's own hover background. */
    background: var(--accent-dim);
    color: var(--text-primary);
    box-shadow: inset 0 0 0 1px var(--accent);
}

/* Info (ⓘ) button on the right edge of each member row. Tapping it
   opens the "Профиль участника" modal; tapping the row itself just
   pans the map. The button stops click propagation so the row's
   pan handler doesn't also fire. */
.member-info-btn {
    margin-left: auto;
    flex-shrink: 0;
    width: 28px;
    height: 28px;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    border: none;
    background: transparent;
    color: var(--text-secondary);
    font-size: 1.1rem;
    border-radius: 50%;
    cursor: pointer;
    transition:
        background var(--transition-fast),
        color var(--transition-fast);
}
.member-info-btn:hover {
    background: var(--bg-hover);
    color: var(--accent);
}

.circle-avatar,
.member-avatar {
    width: 32px;
    height: 32px;
    border-radius: 50%;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    flex-shrink: 0;
    font-size: 0.82rem;
    font-weight: 800;
}

.circle-avatar {
    background: var(--accent-dim);
    color: var(--accent);
}

.member-avatar {
    background: rgba(255, 255, 255, 0.06);
    color: var(--text-secondary);
    overflow: hidden;
}

.member-avatar.has-image {
    background: rgba(255, 255, 255, 0.08);
}

.member-avatar img {
    width: 100%;
    height: 100%;
    object-fit: cover;
    display: block;
}

.member-avatar-fallback {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 100%;
    height: 100%;
}

.member-avatar.has-image .member-avatar-fallback {
    display: none;
}

.member-avatar.image-error .member-avatar-fallback {
    display: inline-flex;
}

.member-info {
    display: grid;
    line-height: 1.2;
}

.member-name {
    color: var(--text-primary);
    font-size: 0.9rem;
}

.member-role {
    color: var(--text-muted);
    font-size: 0.74rem;
    text-transform: capitalize;
}

/* User-group palette — mirrors Android GroupLabel (HomeScreen.kt:433):
   admin=StatusRed, advanced=StatusAmber, participant/guest=muted. Keeps
   the sidebar role label visually matching the mobile card chip. */
.member-role--admin {
    color: #f85149;
    font-weight: 600;
}
.member-role--advanced {
    color: #d29922;
    font-weight: 600;
}
.member-role--participant {
    color: var(--text-muted);
}
.member-role--guest {
    color: var(--text-muted);
    opacity: 0.7;
}

.map-container {
    position: relative;
    min-height: 100vh;
}

#map {
    width: 100%;
    height: 100%;
}

.map-toolbar {
    position: absolute;
    top: 18px;
    left: 18px;
    display: grid;
    gap: 8px;
    z-index: 400;
}

.map-btn,
.icon-btn {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 42px;
    height: 42px;
    border: 1px solid var(--border);
    border-radius: 16px;
    background: var(--bg-card-elevated);
    color: var(--text-primary);
    cursor: pointer;
    box-shadow: var(--shadow-sm);
    transition:
        background var(--transition-fast),
        border-color var(--transition-fast),
        color var(--transition-fast),
        transform var(--transition-fast);
}

.map-btn:hover,
.icon-btn:hover {
    background: var(--bg-hover);
    border-color: var(--border-light);
    color: var(--accent);
    transform: translateY(-1px);
}

.sidebar-close {
    display: none;
}

.events-feed {
    padding: 10px 12px 16px;
}

.events-feed .event-item {
    background: var(--bg-card);
}

/* ── Event card (Android-style) ─────────────────────────────────────────── */
.event-card {
    display: flex;
    align-items: center;
    gap: 12px;
    padding: 12px;
    border-radius: 14px;
    background: var(--bg-card);
    margin-bottom: 10px;
}
.event-card-icon {
    width: 40px;
    height: 40px;
    flex: 0 0 40px;
    border-radius: 10px;
    display: flex;
    align-items: center;
    justify-content: center;
    font-size: 18px;
    font-weight: 700;
}
.event-icon-sos {
    background: rgba(255, 107, 122, 0.15);
    color: #ff6b7a;
}
.event-icon-checkin {
    background: rgba(0, 214, 143, 0.15);
    color: #00d68f;
}
.event-icon-geofence {
    background: rgba(0, 214, 143, 0.15);
    color: #00d68f;
}
.event-icon-geofence-exit {
    background: rgba(245, 183, 74, 0.15);
    color: #f5b74a;
}
.event-icon-ring {
    background: rgba(108, 92, 231, 0.15);
    color: #6c5ce7;
}
.event-icon-default {
    background: rgba(255, 255, 255, 0.08);
    color: var(--text-muted);
}

.event-card-body {
    flex: 1;
    min-width: 0;
}
.event-card-row {
    display: flex;
    align-items: baseline;
    justify-content: space-between;
    gap: 8px;
}
.event-card-name {
    font-size: 14px;
    font-weight: 600;
    color: var(--text-primary);
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
}
.event-card-circle {
    font-size: 12px;
    color: var(--text-muted);
    white-space: nowrap;
    flex-shrink: 0;
}
.event-card-subtitle {
    font-size: 13px;
    color: var(--text-muted);
    margin-top: 2px;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

.sos-btn {
    background: rgba(255, 107, 122, 0.12);
    border-color: rgba(255, 107, 122, 0.26);
    color: var(--danger);
}

/* ==========================================================================
   Map markers
   ========================================================================= */

.member-marker {
    display: flex;
    flex-direction: column;
    align-items: center;
    pointer-events: none;
}

.marker-dot {
    width: 14px;
    height: 14px;
    border-radius: 50%;
    border: 2px solid rgba(255, 255, 255, 0.92);
    box-shadow: 0 10px 20px rgba(0, 0, 0, 0.22);
}

.member-marker.me .marker-dot {
    width: 18px;
    height: 18px;
}

/* Avatar-rendered marker (preferred when member has a Google picture). */
.marker-avatar {
    width: 40px;
    height: 40px;
    border-radius: 50%;
    border: 3px solid #00d68f;
    background: var(--bg-card);
    color: var(--text-primary);
    display: flex;
    align-items: center;
    justify-content: center;
    font-size: 16px;
    font-weight: 700;
    overflow: hidden;
    box-shadow: 0 2px 6px rgba(0, 0, 0, 0.35);
}
.member-marker.me .marker-avatar {
    width: 44px;
    height: 44px;
}
.marker-avatar img {
    width: 100%;
    height: 100%;
    object-fit: cover;
    display: block;
}
.marker-avatar-fallback {
    /* Applied by the JS onerror handler when the avatar image fails to load —
     the div then renders its initial as text. */
    background: #4a3e96;
    color: #ffffff;
}

.marker-label {
    margin-top: 4px;
    padding: 3px 10px 4px;
    border-radius: 10px;
    background: var(--marker-label-bg);
    color: var(--text-primary);
    font-size: 0.68rem;
    font-weight: 700;
    text-align: center;
    white-space: nowrap;
    box-shadow: var(--shadow-sm);
    line-height: 1.2;
}

html[data-theme="light"] .marker-label {
    border: 1px solid var(--border);
}

/* Second line inside the marker label: battery + last-seen. Smaller and
   less saturated than the name so the eye lands on the name first. */
.marker-meta {
    display: flex;
    justify-content: center;
    gap: 6px;
    margin-top: 1px;
    font-size: 0.62rem;
    font-weight: 500;
    opacity: 0.85;
    color: var(--text-secondary);
}

.marker-meta-battery {
    font-variant-numeric: tabular-nums;
}

/* Speed tooltip — replaces the previous Leaflet popup so we get an
   anchored, close-button-less badge that follows the marker on every
   setLatLng() and disappears reliably with unbindTooltip() the moment
   speed drops below the walking-pace threshold. The colours mirror the
   default Leaflet popup so the visual change is unnoticeable while the
   member is moving; only the buggy detach + lingering close-button go
   away. */
.leaflet-tooltip.speed-tooltip {
    background: rgba(255, 255, 255, 0.96);
    color: #111;
    font-size: 0.78rem;
    padding: 4px 8px;
    border: 0;
    border-radius: 8px;
    box-shadow: 0 2px 6px rgba(0, 0, 0, 0.25);
    font-variant-numeric: tabular-nums;
}
.leaflet-tooltip.speed-tooltip::before {
    display: none;
}

/* ==========================================================================
   Modal
   ========================================================================= */

.modal {
    position: fixed;
    inset: 0;
    z-index: 1000;
    display: none;
    align-items: center;
    justify-content: center;
}

.modal[style*="flex"] {
    display: flex !important;
}

.modal-backdrop {
    position: absolute;
    inset: 0;
    background: var(--bg-overlay);
    backdrop-filter: blur(4px);
}

.modal-dialog {
    position: relative;
    z-index: 1;
    width: min(100% - 24px, 520px);
    border-radius: 28px;
    border: 1px solid var(--border);
    background:
        linear-gradient(180deg, rgba(255, 255, 255, 0.035), transparent 24%),
        var(--bg-card-elevated);
    overflow: hidden;
}

/* .modal-wide is for modals that need to fit a multi-column table or a
   long URL per row — e.g. the Drive bootstrap-file viewer that lists
   one panel per row with its api_base_url. The default 520px is too
   narrow once URLs wrap; 684px (was 760px before user feedback,
   trimmed 10%) is the sweet spot where the URL fits on one line
   without dwarfing the page on a 1080p screen. */
.modal-wide .modal-dialog {
    width: min(100% - 24px, 660px);
}

/* Drive bootstrap-file modal — per-instance rows + raw-JSON fallback */
.bootstrap-instance-list {
    display: flex;
    flex-direction: column;
    gap: 0.5rem;
    margin-bottom: 0.75rem;
}
.bootstrap-instance-row {
    display: grid;
    grid-template-columns: 1fr auto;
    gap: 0.75rem;
    align-items: center;
    padding: 0.6rem 0.75rem;
    border-radius: 12px;
    background: var(--surface-2, rgba(255, 255, 255, 0.04));
    border: 1px solid var(--border);
}
.bootstrap-instance-meta {
    display: flex;
    flex-direction: column;
    gap: 0.15rem;
    min-width: 0;
}
.bootstrap-instance-name {
    font-weight: 600;
    word-break: break-all;
}
.bootstrap-instance-url {
    font-size: 0.85rem;
    color: var(--text-secondary);
    word-break: break-all;
}
.bootstrap-instance-updated {
    font-size: 0.78rem;
    color: var(--text-muted);
}
.bootstrap-raw-toggle {
    margin-top: 0.5rem;
}
.bootstrap-raw-toggle > summary {
    cursor: pointer;
    color: var(--text-secondary);
    font-size: 0.85rem;
    user-select: none;
}
.bootstrap-raw-json {
    white-space: pre-wrap;
    word-break: break-word;
    background: var(--surface-2, #111);
    padding: 0.75rem;
    border-radius: 6px;
    font-size: 0.85rem;
    max-height: 50vh;
    overflow: auto;
    margin: 0.5rem 0 0 0;
}

.modal-header {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 12px;
    padding: 18px 22px 16px;
    border-bottom: 1px solid var(--border);
}

.modal-close {
    border: none;
    background: transparent;
    color: var(--text-muted);
    font-size: 1.5rem;
    line-height: 1;
    cursor: pointer;
}

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

.modal-body {
    padding: 20px 22px;
}

.modal-footer {
    display: flex;
    justify-content: flex-end;
    flex-wrap: wrap;
    gap: 10px;
    padding: 0 22px 22px;
}

.member-modal-dialog {
    width: min(100% - 24px, 560px);
}

.member-profile {
    display: flex;
    align-items: center;
    gap: 18px;
    margin-bottom: 22px;
}

.member-profile-avatar {
    width: 88px;
    height: 88px;
    border-radius: 50%;
    overflow: hidden;
    flex-shrink: 0;
    background: rgba(255, 255, 255, 0.08);
    color: var(--text-primary);
    display: inline-flex;
    align-items: center;
    justify-content: center;
    font-size: 1.8rem;
    font-weight: 800;
}

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

.member-profile-main {
    min-width: 0;
}

.member-profile-name {
    color: var(--text-primary);
    font-size: 1.32rem;
    font-weight: 800;
    line-height: 1.15;
}

.member-profile-role {
    color: var(--accent);
    font-size: 0.9rem;
    margin-top: 6px;
}

.member-profile-grid {
    display: grid;
    gap: 12px;
}

.member-profile-row {
    display: grid;
    grid-template-columns: 140px 1fr;
    gap: 14px;
    align-items: start;
    padding: 10px 0;
    border-top: 1px solid var(--border);
}

.member-profile-row:first-child {
    border-top: none;
    padding-top: 0;
}

.member-profile-label {
    color: var(--text-muted);
    font-size: 0.84rem;
    font-weight: 700;
}

.member-profile-value {
    color: var(--text-primary);
    font-size: 0.92rem;
    word-break: break-word;
}

.member-profile-diagnostics {
    margin-top: 18px;
    padding: 14px 16px;
    border-radius: 18px;
    border: 1px solid var(--border);
    background: rgba(255, 255, 255, 0.03);
}

.member-profile-diagnostics-title {
    color: var(--text-primary);
    font-size: 0.84rem;
    font-weight: 800;
    margin-bottom: 6px;
}

.member-profile-diagnostics-text {
    color: var(--text-secondary);
    font-size: 0.88rem;
    line-height: 1.45;
}

.member-profile-diagnostics-actions {
    margin-top: 12px;
}

.circle-members-admin-list {
    display: grid;
    gap: 14px;
    margin-top: 18px;
}

.circle-member-admin-item {
    padding: 16px;
    border: 1px solid var(--border);
    border-radius: 20px;
    background: var(--bg-card);
}

/* ==========================================================================
   Responsive
   ========================================================================= */

@media (max-width: 1180px) {
    .app-shell {
        grid-template-columns: var(--sidebar-width) 1fr;
    }

    .events-panel {
        display: none;
    }
}

@media (max-width: 860px) {
    .main-content {
        padding: 22px 18px;
    }

    .settings-secondary-grid {
        grid-template-columns: 1fr;
    }
}

@media (max-width: 768px) {
    .sidebar {
        transform: translateX(-100%);
        transition: transform var(--transition-base);
    }

    .sidebar.open {
        transform: translateX(0);
    }

    .main-content {
        margin-left: 0;
    }

    .page-header {
        align-items: flex-start;
        flex-direction: column;
    }

    .stats-grid {
        grid-template-columns: repeat(2, minmax(0, 1fr));
    }

    .app-shell {
        grid-template-columns: 1fr;
    }

    .app-sidebar {
        position: fixed;
        inset: 0 auto 0 0;
        width: min(86vw, 320px);
        transform: translateX(-100%);
        transition: transform var(--transition-base);
        box-shadow: var(--shadow-lg);
    }

    .app-sidebar.open {
        transform: translateX(0);
    }

    .sidebar-close {
        display: inline-flex;
    }

    .map-container {
        min-height: 100vh;
    }

    .footer-row {
        flex-direction: column;
        align-items: stretch;
    }

    .footer-row .lang-select,
    .footer-row .btn {
        width: 100%;
    }

    .member-profile {
        align-items: flex-start;
    }
}

@media (max-width: 520px) {
    .stats-grid {
        grid-template-columns: 1fr;
    }

    .theme-picker-options {
        grid-template-columns: 1fr;
    }

    .login-card,
    .landing-container {
        padding-left: 22px;
        padding-right: 22px;
        border-radius: 28px;
    }

    .card-body,
    .card-header,
    .modal-header,
    .modal-body,
    .modal-footer {
        padding-left: 16px;
        padding-right: 16px;
    }

    .member-profile-row {
        grid-template-columns: 1fr;
        gap: 6px;
    }
}

/* ==========================================================================
   Admin Map page (/admin/map)
   ==========================================================================
   Reuses .member-marker / .marker-avatar / .marker-label from the /app
   styling above — only the surrounding shell + right-hand members list is
   page-specific.
*/

.admin-map-content {
    padding: 0;
}

.admin-map-layout {
    display: flex;
    height: 100vh;
    min-height: 100vh;
}

.admin-map-canvas {
    position: relative;
    flex: 1 1 auto;
    min-width: 0;
}

.admin-map-canvas #map {
    width: 100%;
    height: 100%;
}

.admin-map-members-panel {
    /* Match /app's events-panel width so the two pages feel symmetric. */
    width: var(--events-width);
    flex: 0 0 var(--events-width);
    border-left: 1px solid var(--border);
    background: var(--bg-sidebar);
    display: flex;
    flex-direction: column;
    overflow: hidden;
}

.admin-map-members-panel .section-label {
    padding: 16px 16px 8px;
    display: flex;
    align-items: center;
    gap: 8px;
    text-transform: uppercase;
    font-size: 12px;
    letter-spacing: 0.08em;
    color: var(--text-muted);
}

.admin-map-filter {
    padding: 0 16px 12px;
}

.admin-map-filter .form-input {
    width: 100%;
}

.admin-map-members-list {
    flex: 1 1 auto;
    overflow-y: auto;
    /* 16px sides match the .admin-map-filter dropdown above so each
     member row is the same width as the "Все круги" select. 8px
     top gives the .active row's outline room to breathe — at 0
     padding-top the green border was getting clipped by the panel. */
    padding: 8px 16px 16px;
}

.admin-map-member {
    display: flex;
    align-items: center;
    gap: 12px;
    padding: 10px 12px;
    border-radius: 12px;
    cursor: pointer;
    transition: background var(--transition-fast);
}

.admin-map-member:hover {
    background: var(--bg-hover);
}

.admin-map-member.active {
    background: var(--bg-hover);
    outline: 1px solid var(--accent);
}

.admin-map-member.no-loc {
    opacity: 0.55;
}

.admin-map-member-avatar {
    width: 36px;
    height: 36px;
    flex: 0 0 36px;
    border-radius: 50%;
    background: var(--bg-input);
    display: flex;
    align-items: center;
    justify-content: center;
    font-weight: 600;
    color: var(--text-primary);
    overflow: hidden;
}

.admin-map-member-avatar img {
    width: 100%;
    height: 100%;
    object-fit: cover;
}

.admin-map-member-name {
    flex: 1;
    min-width: 0;
    font-size: 14px;
    color: var(--text-primary);
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
}

.admin-map-member-meta {
    font-size: 12px;
    color: var(--text-muted);
}

/* Info (ⓘ) button on the right edge of each admin member row.
   Mirrors .member-info-btn on the public app — pans-on-row-click,
   popup-on-info-click. */
.admin-map-member-info {
    margin-left: auto;
    flex-shrink: 0;
    width: 26px;
    height: 26px;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    border: none;
    background: transparent;
    color: var(--text-muted);
    font-size: 1.05rem;
    border-radius: 50%;
    cursor: pointer;
    transition:
        background 120ms,
        color 120ms;
}
.admin-map-member-info:hover {
    background: var(--bg-hover);
    color: var(--accent);
}

@media (max-width: 900px) {
    .admin-map-layout {
        flex-direction: column;
        height: auto;
    }

    .admin-map-canvas {
        height: 60vh;
    }

    .admin-map-members-panel {
        width: 100%;
        flex: 1 1 auto;
        border-left: none;
        border-top: 1px solid var(--border);
    }
}
