.vh-mem-wrap {
    --bg:        #0d0d0e;
    --card:      #151516;
    --hover:     #1b1b1d;
    --line:      rgba(99,99,99,0.25);
    --line-soft: rgba(99,99,99,0.12);
    --ink:       #e0e0e0;
    --ink-dim:   rgba(224,224,224,0.8);
    --ink-faint: rgba(224,224,224,0.65);
    --accent:    #ff9900;
    --green:     #1cbb8c;
    --red:       #ff3b30;
    color: var(--ink);
    padding: 1.25rem;
    display: flex; flex-direction: column; gap: 1rem;
}

/* ── Top metrics strip ──────────────────────────────────────────────── */
.mem-stats {
    display: grid; grid-template-columns: repeat(3, 1fr); gap: 0.75rem;
}
@media (max-width: 700px) { .mem-stats { grid-template-columns: 1fr; } }
.mem-stat {
    background: var(--card); border-radius: 0;
    padding: 0.7rem 0.95rem 0.8rem;
    box-shadow: 0 4px 14px rgba(0,0,0,0.35);
}
.mem-stat-h {
    font-size: 0.62rem; font-weight: 700; color: var(--ink-dim);
    text-transform: uppercase; letter-spacing: 0.18em;
    padding-bottom: 0.4rem; margin-bottom: 0.5rem;
    border-bottom: 1px dashed var(--line-soft);
    display: flex; align-items: center; gap: 0.4rem;
}
.mem-stat-h::before { content: "▸"; color: var(--accent); }
.mem-stat-val {
    font-size: 1.35rem; font-weight: 600; line-height: 1.1;
    font-variant-numeric: tabular-nums;
}
.mem-stat-val small { font-size: 0.7rem; color: var(--ink-faint); margin-left: 4px; }
.mem-stat-val .pulse { color: var(--green); }

/* ── Toolbar ────────────────────────────────────────────────────────── */
.mem-toolbar {
    background: var(--card); border-radius: 0;
    padding: 0.6rem 0.75rem;
    box-shadow: 0 4px 14px rgba(0,0,0,0.35);
    display: flex; align-items: center; gap: 0.6rem; flex-wrap: wrap;
}
.mem-search {
    position: relative; flex: 1; min-width: 200px;
}
.mem-search i {
    position: absolute; left: 0.6rem; top: 50%; transform: translateY(-50%);
    color: var(--ink-faint); font-size: 0.78rem;
}
.mem-search input {
    width: 100%;
    background: var(--bg, #0d0d0e);
    border: 1px solid rgba(99,99,99,0.25);
    color: var(--ink);
    border-radius: 0;
    padding: 0.4rem 0.6rem 0.4rem 1.9rem;
    font-size: 0.78rem;
    transition: border-color 0.15s;
}
.mem-search input::placeholder { color: var(--ink-faint); }
.mem-search input:focus {
    outline: none;
    border-color: rgba(255,153,0,0.4);
}
.mem-pill {
    padding: 0.35rem 0.65rem; font-size: 0.7rem; font-weight: 500;
    background: rgba(255,255,255,0.03);
    border: 1px solid rgba(99,99,99,0.2); border-radius: 0;
    color: var(--ink-dim); cursor: pointer;
    transition: all 0.15s;
    text-transform: uppercase; letter-spacing: 0.06em;
    white-space: nowrap;
}
.mem-pill:hover { color: var(--ink); border-color: rgba(99,99,99,0.4); }
.mem-pill.active {
    color: var(--accent);
    background: rgba(255,153,0,0.08);
    border-color: rgba(255,153,0,0.3);
}
.mem-pill .count {
    margin-left: 4px; opacity: 0.5; font-variant-numeric: tabular-nums;
}

/* ── Role group ─────────────────────────────────────────────────────── */
.mem-group { display: flex; flex-direction: column; gap: 0.4rem; }
.mem-group-h {
    display: flex; align-items: center; gap: 0.5rem;
    font-size: 0.66rem; font-weight: 700; color: var(--ink-dim);
    text-transform: uppercase; letter-spacing: 0.18em;
    padding: 0.5rem 0.25rem 0.3rem;
}
.mem-group-h::before { content: "▸"; color: var(--accent); }
.mem-group-h .badge {
    margin-left: auto;
    font-size: 0.65rem; font-weight: 600;
    padding: 1px 7px; border-radius: 999px;
    background: rgba(255,255,255,0.04);
    color: var(--ink-faint);
}

/* ── Member row ─────────────────────────────────────────────────────── */
.mem-list { display: flex; flex-direction: column; gap: 0.3rem; }
.mem-row {
    display: grid;
    grid-template-columns: 44px minmax(0,1.4fr) minmax(0,1fr) minmax(0,1fr);
    align-items: center; gap: 0.85rem;
    padding: 0.55rem 0.85rem;
    background: var(--hover, #2d2d2d); border-radius: 0;
    border: 1px solid rgba(99,99,99,0.1);
    transition: border-color 0.15s, background 0.12s;
}
.vh-mem-wrap.is-insider .mem-row {
    grid-template-columns: 44px minmax(0,1.4fr) minmax(0,1fr) minmax(0,1fr) 90px;
}
.mem-row:hover {
    border-color: rgba(255,153,0,0.25);
    background: var(--hover);
}
.mem-row.is-online {
    border-left: 2px solid var(--green);
}
.mem-row .col-avatar { display: flex; align-items: center; }
.mem-row .col-name {
    overflow: hidden;
}
.mem-row .col-name .name-line {
    color: var(--ink); font-weight: 500;
    overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
/* APPEARS OFFLINE - staff only.
   Only rendered when the controller set `appears_offline`, which it does for a VTLog staff
   viewer and nobody else. Inline with the username rather than down among the meta chips: it
   qualifies who the row IS, not what they have. */
.mem-row .col-name .name-line .mem-ao {
    display: inline-block;
    margin-left: 0.4rem;
    padding: 1px 6px;
    border: 1px solid var(--accent);
    border-radius: 0;
    background: rgba(255,153,0,0.12);
    color: var(--accent);
    font-size: 0.58rem;
    font-weight: 800;
    letter-spacing: 0.04em;
    text-transform: uppercase;
    vertical-align: middle;
    white-space: nowrap;
    cursor: help;
}

.mem-row .col-name .meta-line {
    font-size: 0.7rem; color: var(--ink-faint);
    margin-top: 3px;
    /* Wraps rather than clips: an insider sees up to four chips here (role,
       progression rank, pin, quota) and col-name is overflow:hidden. */
    display: flex; align-items: center; flex-wrap: wrap; gap: 0.3rem;
}
.mem-row .col-name .meta-line .dot {
    width: 5px; height: 5px; border-radius: 50%;
    background: var(--ink-faint); display: inline-block;
}
.mem-row.is-online .meta-line .dot {
    background: var(--green); box-shadow: 0 0 6px rgba(28,187,140,0.6);
    animation: mem-pulse 2.4s ease-in-out infinite;
}
@keyframes mem-pulse {
    0%, 100% { opacity: 1; }
    50%      { opacity: 0.45; }
}
/* One chip shape for everything on the meta line - role, progression rank, pin
   and quota. They sit side by side, so a bare text label among them read as a
   chip that had failed to render. */
.mem-row .role-chip,
.mem-row .rank-chip,
.mem-row .pin-chip,
.mem-row .quota-chip {
    display: inline-flex; align-items: center; gap: 0.3rem;
    max-width: 100%;
    font-size: 0.62rem; font-weight: 600;
    padding: 1px 7px; border-radius: 999px;
    border: 1px solid transparent;
    letter-spacing: 0.02em;
    white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
.mem-row .quota-chip { font-variant-numeric: tabular-nums; }
.mem-row .quota-chip i { font-size: 0.6rem; }
/* The role is the primary thing on this line. A staff role - one that actually
   carries permissions - gets the accent; a plain driver role stays quiet, since
   a 117-member list would otherwise be solid orange. */
.mem-row .role-chip {
    color: var(--ink-dim);
    border-color: var(--line);
    background: rgba(255,255,255,0.04);
}
.mem-row .role-chip.is-staff {
    color: var(--accent);
    border-color: rgba(255,153,0,0.35);
    background: rgba(255,153,0,0.1);
}
.mem-row .quota-chip.ok      { color: var(--green); border-color: rgba(28,187,140,0.35); background: rgba(28,187,140,0.08); }
.mem-row .quota-chip.partial { color: #d49a26; border-color: rgba(212,154,38,0.35); background: rgba(212,154,38,0.08); }
.mem-row .quota-chip.under   { color: var(--red); border-color: rgba(255,59,48,0.3);  background: rgba(255,59,48,0.06); }

/* Progression rank held alongside a staff role (Progression's second axis), and
   the staff pin that freezes it. Both only render when they say something the
   role chip next to them does not.
   Deliberately quieter than the role: a driver rank is an achievement, the role
   is the job. Colouring the rank louder than the role read as though the rank
   outranked it. */
.mem-row .rank-chip .role-logo { flex-shrink: 0; }
.mem-row .rank-chip i { font-size: 0.6rem; opacity: 0.75; }
.mem-row .rank-chip {
    color: var(--ink-dim);
    border-color: var(--line);
    background: rgba(255,255,255,0.04);
}
.mem-row .pin-chip {
    color: var(--ink-dim);
    border-color: var(--line);
    background: rgba(255,255,255,0.04);
    text-transform: uppercase;
}
.mem-row .pin-chip i { font-size: 0.55rem; }
.mem-row .col-joined,
.mem-row .col-seen {
    font-size: 0.75rem; color: var(--ink-dim);
    font-variant-numeric: tabular-nums;
    overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.mem-row .col-seen .label,
.mem-row .col-joined .label {
    display: block;
    font-size: 0.6rem; font-weight: 700;
    color: var(--ink-faint);
    text-transform: uppercase; letter-spacing: 0.1em;
    margin-bottom: 1px;
}
.mem-row .col-version {
    font-size: 0.7rem; color: var(--ink-faint);
    font-variant-numeric: tabular-nums;
    text-align: right;
}
.mem-row .col-version code {
    background: rgba(255,255,255,0.04);
    border: 1px solid rgba(99,99,99,0.18);
    color: var(--ink-dim);
    padding: 1px 6px; border-radius: 0;
    font-size: 0.68rem;
}

.mem-empty {
    background: var(--card); border-radius: 0;
    padding: 2.5rem 1rem; text-align: center;
    color: var(--ink-faint); font-size: 0.85rem;
}

@media (max-width: 700px) {
    .mem-row {
        grid-template-columns: 44px minmax(0,1fr);
    }
    .vh-mem-wrap.is-insider .mem-row {
        grid-template-columns: 44px minmax(0,1fr) auto;
    }
    .mem-row .col-joined,
    .mem-row .col-seen,
    .mem-row .col-version { display: none; }
    /* The Last Online column is hidden here, so the row says it inline instead.
       Shaped like the chips it now sits beside. */
    .mem-row.is-online .col-name .meta-line::after {
        content: "online";
        color: var(--green); font-weight: 600;
        font-size: 0.62rem; letter-spacing: 0.02em;
        padding: 1px 7px; border-radius: 999px;
        border: 1px solid rgba(28,187,140,0.35);
        background: rgba(28,187,140,0.08);
    }
}
