/* ════════════════════════════════════════════════════════════════════════
   PLAYERS TAB — a roster, not a stack of cards.

   Each row was `flex-direction: column`, so every player occupied three
   stacked lines: name, then metadata, then a wrapping row of four buttons.
   Nothing lined up between rows, every row was a different height, and a
   roster of six looked like six unrelated cards. Hence "weirdly shaped".

   It is now a grid with shared column tracks, so names, roles, pings and
   actions align down the list and every row is the same height. You can
   scan a column instead of reading each entry.

   Loaded after overture.css so it refines the roster rather than forking it.
   ════════════════════════════════════════════════════════════════════════ */

/* ─── the panel ──────────────────────────────────────────────────────── */

.ovt-ply {
    border: 1px solid var(--ovt-hairline);
    border-radius: 4px;
    background: rgba(255, 255, 255, 0.012);
    overflow: hidden;
}

.ovt-ply-head {
    padding: 0.6rem 0.8rem;
    border-bottom: 1px solid var(--ovt-hairline);
    background: linear-gradient(180deg, rgba(255, 255, 255, 0.02), transparent);
}

/* ─── column tracks, shared by the header and every row ──────────────── */

.ovt-ply-row {
    display: grid;
    grid-template-columns:
        minmax(0, 1fr)      /* name + badges          */
        minmax(0, 8rem)     /* role                   */
        4.5rem              /* level                  */
        4.5rem              /* ping                   */
        auto;               /* actions, right-aligned */
    align-items: center;
    gap: 0 0.75rem;
    padding: 0.42rem 0.8rem;
    border-bottom: 1px solid var(--ovt-hairline);
    transition: background 0.12s ease;
}

.ovt-ply-row:last-child { border-bottom: none; }
.ovt-ply-row:hover { background: rgba(255, 255, 255, 0.025); }

/* every cell is a grid child; min-width:0 lets long names ellipsis instead of
   stretching the track and pushing the actions off the row */
.ovt-ply-cell {
    display: flex;
    align-items: baseline;
    gap: 0.4rem;
    min-width: 0;
}

.ovt-ply-cell-lvl,
.ovt-ply-cell-ping { justify-content: flex-end; }

.ovt-ply-name {
    font-family: 'Roboto Flex', sans-serif;
    font-size: 0.82rem;
    font-weight: 700;
    color: var(--ovt-fg);
    line-height: 1.2;
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
}

.ovt-ply-role {
    font-family: 'JetBrains Mono', ui-monospace, monospace;
    font-size: 0.6rem;
    letter-spacing: 0.1em;
    text-transform: uppercase;
    color: var(--ovt-fg-dim);
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
}

.ovt-ply-role.is-staff { color: var(--ovt-violet, #B19CD9); }

.ovt-ply-lvl,
.ovt-ply-ping {
    font-family: 'JetBrains Mono', ui-monospace, monospace;
    font-size: 0.66rem;
    color: var(--ovt-fg-dim);
    font-variant-numeric: tabular-nums;
    white-space: nowrap;
}

.ovt-ply-afk {
    font-family: 'JetBrains Mono', ui-monospace, monospace;
    font-size: 0.56rem;
    font-weight: 700;
    letter-spacing: 0.12em;
    text-transform: uppercase;
    color: var(--ovt-amber);
    padding: 0.08rem 0.3rem;
    border: 1px solid rgba(251, 191, 36, 0.35);
    border-radius: 2px;
    white-space: nowrap;
}

.ovt-ply-patreon { color: var(--ovt-amber); font-size: 0.7rem; }

/* ─── actions ────────────────────────────────────────────────────────── */

/* Hidden until the row is hovered or focused. Four buttons per row, times a
   full server, is visual noise on a page you mostly open to READ the roster.
   Keyboard focus still reveals them, so this costs nothing in accessibility. */
.ovt-ply-actions {
    display: flex;
    align-items: center;
    gap: 0.3rem;
    justify-content: flex-end;
    opacity: 0;
    transition: opacity 0.12s ease;
}

.ovt-ply-row:hover .ovt-ply-actions,
.ovt-ply-row:focus-within .ovt-ply-actions { opacity: 1; }

/* an inline input (message / kick reason / send target) takes over the row,
   so it needs the full width rather than being squeezed into one cell */
.ovt-ply-inline {
    grid-column: 1 / -1;
    display: flex;
    align-items: center;
    gap: 0.35rem;
    width: 100%;
}

.ovt-ply-row:has(.ovt-ply-inline) .ovt-ply-actions { opacity: 1; }

.ovt-ply-input {
    flex: 1;
    min-width: 0;
    padding: 0.3rem 0.5rem;
    border: 1px solid var(--ovt-hairline);
    border-radius: 3px;
    background: var(--ovt-bg-deeper, #06080a);
    color: var(--ovt-fg);
    font-size: 0.74rem;
}

.ovt-ply-input:focus { outline: none; border-color: var(--ovt-green); }

/* ─── narrow screens: fall back to a stack, but a tidy one ───────────── */

@media (max-width: 820px) {
    .ovt-ply-row {
        grid-template-columns: minmax(0, 1fr) auto auto;
        gap: 0.2rem 0.6rem;
    }
    /* role drops under the name; level and ping stay on the top line */
    .ovt-ply-cell-role { grid-column: 1 / -1; }
    /* touch has no hover, so the actions must always be visible */
    .ovt-ply-actions { grid-column: 1 / -1; justify-content: flex-start; opacity: 1; }
}

@media (hover: none) {
    .ovt-ply-actions { opacity: 1; }
}

/* ─── column header ──────────────────────────────────────────────────── */

.ovt-ply-colhead {
    padding-top: 0.35rem;
    padding-bottom: 0.35rem;
    background: rgba(255, 255, 255, 0.015);
    font-family: 'JetBrains Mono', ui-monospace, monospace;
    font-size: 0.54rem;
    font-weight: 700;
    letter-spacing: 0.16em;
    text-transform: uppercase;
    color: var(--ovt-fg-dim);
}

.ovt-ply-colhead:hover { background: rgba(255, 255, 255, 0.015); }

/* the header must not reserve the full action width, or the labels drift */
.ovt-ply-colhead .ovt-ply-actions { opacity: 0; min-width: 0; }

@media (max-width: 820px) {
    .ovt-ply-colhead { display: none; }
}

/* ════════════════════════════════════════════════════════════════════════
   ACCESS — maintenance lock, one control with a scope switch.

   Previously two stacked blocks that were the same control twice, differing
   only in blast radius, both wearing the roster's panel class. Now: pick a
   scope, read one state line, edit one pair of fields.
   ════════════════════════════════════════════════════════════════════════ */

.ovt-acc { display: flex; flex-direction: column; gap: 0.7rem; }

/* scope switch. The pip marks a scope that is currently locked, so you can
   see the network is down without switching to it. */
.ovt-acc-scopes {
    display: inline-flex;
    align-self: flex-start;
    border: 1px solid var(--ovt-hairline);
    border-radius: 3px;
    overflow: hidden;
}

.ovt-acc-scopes button {
    appearance: none;
    cursor: pointer;
    display: inline-flex;
    align-items: center;
    gap: 0.4rem;
    padding: 0.35rem 0.75rem;
    border: none;
    background: transparent;
    font-family: 'JetBrains Mono', ui-monospace, monospace;
    font-size: 0.6rem;
    font-weight: 700;
    letter-spacing: 0.12em;
    text-transform: uppercase;
    color: var(--ovt-fg-dim);
    transition: background 0.14s ease, color 0.14s ease;
}

.ovt-acc-scopes button + button { border-left: 1px solid var(--ovt-hairline); }
.ovt-acc-scopes button:hover { color: var(--ovt-fg); background: rgba(255, 255, 255, 0.03); }
.ovt-acc-scopes button.is-on { color: var(--ovt-fg); background: rgba(255, 255, 255, 0.06); }

.ovt-acc-pip {
    width: 5px; height: 5px;
    border-radius: 50%;
    background: var(--ovt-amber);
    box-shadow: 0 0 6px rgba(251, 191, 36, 0.6);
}

/* state, said once */
.ovt-acc-state {
    display: flex;
    align-items: baseline;
    gap: 0.6rem;
    flex-wrap: wrap;
    padding: 0.55rem 0.7rem;
    border: 1px solid var(--ovt-hairline);
    border-left: 2px solid var(--ovt-green);
    border-radius: 0 3px 3px 0;
    background: rgba(16, 185, 129, 0.045);
}

.ovt-acc-state.is-locked {
    border-left-color: var(--ovt-amber);
    background: rgba(251, 191, 36, 0.05);
}

.ovt-acc-lamp {
    width: 7px; height: 7px;
    border-radius: 50%;
    align-self: center;
    background: var(--ovt-green);
    box-shadow: 0 0 8px rgba(16, 185, 129, 0.55);
}

.ovt-acc-state.is-locked .ovt-acc-lamp {
    background: var(--ovt-amber);
    box-shadow: 0 0 8px rgba(251, 191, 36, 0.6);
}

.ovt-acc-word {
    font-family: 'JetBrains Mono', ui-monospace, monospace;
    font-size: 0.72rem;
    font-weight: 700;
    letter-spacing: 0.14em;
    text-transform: uppercase;
    color: var(--ovt-green-soft);
}

.ovt-acc-state.is-locked .ovt-acc-word { color: var(--ovt-amber); }

.ovt-acc-sub { font-size: 0.76rem; color: var(--ovt-fg-muted); }

.ovt-acc-shown {
    display: flex;
    align-items: baseline;
    gap: 0.5rem;
    font-size: 0.76rem;
    color: var(--ovt-fg-muted);
    font-style: italic;
}

.ovt-acc-shown .k {
    font-family: 'JetBrains Mono', ui-monospace, monospace;
    font-size: 0.54rem;
    font-weight: 700;
    letter-spacing: 0.16em;
    text-transform: uppercase;
    font-style: normal;
    color: var(--ovt-fg-dim);
    flex: 0 0 auto;
}

/* fields: message takes the room, allow-level stays compact */
.ovt-acc-fields {
    display: grid;
    grid-template-columns: minmax(0, 1fr) minmax(9rem, auto);
    gap: 0.45rem;
}

@media (max-width: 700px) {
    .ovt-acc-fields { grid-template-columns: minmax(0, 1fr); }
}

.ovt-acc-msg,
.ovt-acc-allow {
    min-width: 0;
    padding: 0.4rem 0.55rem;
    border: 1px solid var(--ovt-hairline);
    border-radius: 3px;
    background: var(--ovt-bg-deeper, #06080a);
    color: var(--ovt-fg);
    font-size: 0.76rem;
}

.ovt-acc-msg:focus,
.ovt-acc-allow:focus { outline: none; border-color: var(--ovt-green); }

.ovt-acc-actions { display: flex; align-items: center; gap: 0.5rem; flex-wrap: wrap; }

/* ─── list container ─────────────────────────────────────────────────── */

.ovt-ply-list { max-height: 60vh; overflow-y: auto; }

.ovt-ply-empty {
    padding: 1.6rem 0.8rem;
    text-align: center;
    font-size: 0.78rem;
    color: var(--ovt-fg-dim);
}
