/* ============================================================
   NEX ADMIN — RAÍL DE NAVEGACIÓN Y PANTALLA DE RESUMEN
   ------------------------------------------------------------
   Va aparte de style.css a propósito. style.css son 38 KB que ya
   funcionan; meter una reforma estructural dentro es la forma más
   rápida de romper algo que nadie mira hasta que falla en juego.
   Aquí solo hay lo nuevo y las tres reglas que se sobrescriben,
   señaladas una por una.

   MOTOR: CEF 103 (comprobado en libcef.dll). Prohibido color-mix(),
   :has(), oklch(), @container y dvh/svh. Aquí no se usa ninguno.
   ============================================================ */

/* ---------- Las tres reglas que se sobrescriben ---------- */

/* .body era `flex:1; overflow:hidden; position:relative` y contenía
   las secciones directamente. Ahora lleva el raíl al lado. */
.body {
    display: flex;
    align-items: stretch;
}

/* El contenedor nuevo que ocupa el hueco que ocupaba .body. */
.views {
    flex: 1;
    min-width: 0;          /* sin esto una tabla ancha empuja el raíl fuera */
    position: relative;
    overflow: hidden;
}

/* La cabecera ya no lleva las pestañas, así que la cinta de estado
   se pega a la derecha donde estaban ellas. */
.cinta {
    display: flex;
    align-items: center;
    gap: clamp(10px, 1vw, 22px);
    margin-left: auto;
}

/* ============================================================
   CINTA DE ESTADO (cabecera)
   ============================================================ */
.cinta-dato {
    display: flex;
    align-items: baseline;
    gap: 6px;
    padding: 5px 13px;
    border-radius: 999px;
    background: rgba(255, 255, 255, .045);
    box-shadow: inset 0 0 0 1px rgba(255, 255, 255, .05);
}

.cinta-dato b {
    font-size: clamp(14px, .32vw + 11px, 19px);
    font-weight: 800;
    color: var(--bone, #e8e6de);
    font-variant-numeric: tabular-nums;
}

/* El aforo va pegado al número, más pequeño y apagado: es contexto,
   no un dato que compita con el que importa. */
.cinta-dato b + span {
    font-size: clamp(10px, .18vw + 8px, 13px);
    color: #6e6d65;
    font-variant-numeric: tabular-nums;
}

.cinta-dato i {
    font-style: normal;
    font-size: clamp(9px, .15vw + 7px, 12px);
    letter-spacing: .07em;
    text-transform: uppercase;
    color: #8a897f;
}

/* Solo se pinta de rojo lo que de verdad requiere que alguien actúe.
   Si todo grita, nada grita. */
.cinta-dato.alerta {
    background: rgba(214, 77, 77, .14);
    box-shadow: inset 0 0 0 1px rgba(214, 77, 77, .35);
}

.cinta-dato.alerta b { color: #ff8f8f; }
.cinta-dato.alerta i { color: #e0a0a0; }

/* Ojo: en style.css NO hay una regla general para [data-hide="true"], cada
   elemento lleva la suya. Poner el atributo sin su regla no oculta nada —
   es justo el fallo que dejó el Registro del chat visible para siempre. */
.cinta-dato[data-hide="true"] { display: none; }

/* Mismo caso: este botón nace oculto y solo aparece mientras espectas. */
#stopspec-btn[data-hide="true"] { display: none; }

/* ============================================================
   RAÍL DE NAVEGACIÓN
   ============================================================ */
.rail {
    display: flex;
    flex-direction: column;
    gap: 2px;
    padding: clamp(10px, .9vw, 16px) clamp(8px, .7vw, 12px);
    /* Ancho fijo por contenido: el texto no se recorta nunca. Recortar
       con puntos suspensivos es un defecto grave en este proyecto. */
    width: max-content;
    min-width: clamp(132px, 10vw, 178px);
    border-right: 1px solid var(--line, rgba(255, 255, 255, .08));
    background: linear-gradient(180deg, rgba(0, 0, 0, .16), rgba(0, 0, 0, .04));
    overflow-y: auto;
    overflow-x: hidden;
    flex-shrink: 0;
}

.rl {
    display: flex;
    align-items: center;
    gap: 10px;
    width: 100%;
    padding: 9px 12px;
    border: none;
    border-radius: 999px;      /* misma píldora que el chat: la casa se nota */
    background: transparent;
    color: #8a897f;
    font-family: inherit;
    font-size: clamp(11px, .22vw + 9px, 14px);
    font-weight: 600;
    letter-spacing: .02em;
    text-align: left;
    cursor: pointer;
    position: relative;
    transition: color .16s var(--ease, ease), background-color .16s var(--ease, ease);
}

.rl > span {
    /* Nunca se parte ni se recorta: el raíl crece si hace falta. */
    white-space: nowrap;
    flex: 1;
}

.rl svg {
    width: 17px;
    height: 17px;
    flex-shrink: 0;
    fill: none;
    stroke: currentColor;
    stroke-width: 1.7;
    stroke-linecap: round;
    stroke-linejoin: round;
}

.rl:hover {
    color: var(--bone, #e8e6de);
    background: rgba(255, 255, 255, .05);
}

.rl.active {
    color: #fff;
    background: linear-gradient(160deg, var(--accent, #3d7ad6), var(--accent-deep, #2a56a0));
    box-shadow: 0 4px 16px var(--glow, rgba(61, 122, 214, .3));
}

.rl.active svg { stroke-width: 2; }

/* Contador dentro del botón, no un punto suelto: "3" dice cuántos,
   un punto solo dice "algo pasa" y obliga a entrar para saberlo. */
.rl-num {
    flex-shrink: 0;
    min-width: 19px;
    padding: 1px 6px;
    border-radius: 999px;
    background: var(--danger, #d64d4d);
    color: #fff;
    font-size: 10px;
    font-weight: 800;
    text-align: center;
    font-variant-numeric: tabular-nums;
}

.rl-num.aviso { background: var(--warn, #d8a13a); color: #1a1a1a; }
.rl-num[data-hide="true"] { display: none; }

.rail-sep {
    height: 1px;
    margin: 7px 12px;
    background: var(--line, rgba(255, 255, 255, .08));
}

/* Cuando el permiso no da para una sección, se esconde entera.
   Un botón que siempre dice "sin permiso" es ruido, no información. */
.rl[data-hide="true"] { display: none; }

/* ============================================================
   PANTALLA DE RESUMEN
   ============================================================ */
.res-wrap {
    display: flex;
    flex-direction: column;
    gap: clamp(12px, 1.1vw, 20px);
    width: 100%;
    height: 100%;
    padding: clamp(16px, 1.5vw, 30px);
    overflow-y: auto;
}

/* ---------- Aviso de lo urgente ---------- */
.res-alerta {
    display: flex;
    align-items: center;
    gap: 12px;
    padding: 13px 18px;
    border-radius: 14px;
    background: rgba(214, 77, 77, .13);
    box-shadow: inset 0 0 0 1px rgba(214, 77, 77, .32);
    color: #ffbcbc;
    font-size: clamp(12px, .24vw + 10px, 15px);
    line-height: 1.45;
}

.res-alerta[data-hide="true"] { display: none; }

.res-alerta.tranquilo {
    background: rgba(255, 255, 255, .04);
    box-shadow: inset 0 0 0 1px rgba(255, 255, 255, .06);
    color: #8a897f;
}

.res-alerta b { color: #fff; font-weight: 700; }
.res-alerta.tranquilo b { color: var(--bone, #e8e6de); }

/* ---------- Las cuatro cifras ---------- */
.res-cifras {
    display: grid;
    /* minmax(0,·) obligatorio: `1fr` es minmax(auto,1fr) y el mínimo
       automático es el min-content del hijo, que aquí desborda. */
    grid-template-columns: repeat(4, minmax(0, 1fr));
    gap: clamp(10px, .9vw, 16px);
}

.res-card {
    display: flex;
    flex-direction: column;
    gap: 7px;
    padding: clamp(13px, 1.1vw, 20px);
    border-radius: 16px;
    background: linear-gradient(165deg, rgba(255, 255, 255, .055), rgba(255, 255, 255, .018));
    box-shadow: inset 0 0 0 1px rgba(255, 255, 255, .06);
    min-width: 0;
}

.res-lbl {
    font-size: clamp(9px, .16vw + 7px, 12px);
    font-weight: 700;
    letter-spacing: .1em;
    text-transform: uppercase;
    color: #7d7c73;
}

.res-big {
    display: flex;
    align-items: baseline;
    gap: 5px;
}

.res-big b {
    font-size: clamp(26px, 1.5vw + 16px, 46px);
    font-weight: 800;
    line-height: 1;
    color: var(--bone, #e8e6de);
    font-variant-numeric: tabular-nums;
}

.res-big em {
    font-style: normal;
    font-size: clamp(12px, .22vw + 9px, 16px);
    color: #6e6d65;
    font-variant-numeric: tabular-nums;
}

.res-pie {
    font-size: clamp(10px, .18vw + 8px, 13px);
    color: #7d7c73;
    line-height: 1.4;
}

/* Barra de aforo. Se rellena con el ancho, no con transform, porque
   aquí no hay animación por fotograma que optimizar. */
.res-barra {
    height: 4px;
    border-radius: 999px;
    background: rgba(255, 255, 255, .07);
    overflow: hidden;
}

.res-barra i {
    display: block;
    height: 100%;
    width: 0;
    border-radius: 999px;
    background: linear-gradient(90deg, var(--accent-deep, #2a56a0), var(--accent-bright, #6aa8ff));
    transition: width .5s var(--ease, ease);
}

.res-barra i.lleno {
    background: linear-gradient(90deg, #b8862c, var(--danger, #d64d4d));
}

/* La tarjeta de reportes se enciende sola cuando hay alguno sin atender. */
.res-card.urge {
    background: linear-gradient(165deg, rgba(214, 77, 77, .16), rgba(214, 77, 77, .05));
    box-shadow: inset 0 0 0 1px rgba(214, 77, 77, .34);
}

.res-card.urge .res-big b { color: #ff9c9c; }
.res-card.urge .res-lbl  { color: #d99e9e; }
.res-card.urge .res-pie  { color: #d9a5a5; }

/* ---------- Chips del staff ---------- */
.res-chips {
    display: flex;
    flex-wrap: wrap;
    gap: 5px;
}

.res-chip {
    padding: 3px 10px;
    border-radius: 999px;
    background: rgba(255, 255, 255, .06);
    box-shadow: inset 0 0 0 1px rgba(255, 255, 255, .05);
    font-size: clamp(10px, .16vw + 8px, 12px);
    color: #a8a69c;
    white-space: nowrap;   /* un nombre no se parte por la mitad */
}

.res-chip b {
    color: #6e6d65;
    font-weight: 600;
    font-variant-numeric: tabular-nums;
}

.res-vacio {
    font-size: clamp(10px, .18vw + 8px, 13px);
    color: #6e6d65;
    font-style: italic;
}

/* ---------- Las dos columnas de abajo ---------- */
.res-fila {
    display: grid;
    grid-template-columns: minmax(0, 1fr) minmax(0, 1fr);
    grid-template-rows: auto auto;
    gap: clamp(10px, .9vw, 16px);
    /* `flex: 1` era `flex: 1 1 0%`, o sea base CERO. Con tres bloques dentro
       el espacio libre se volvia negativo, la rejilla se quedaba mas baja que
       su contenido y los bloques se salian de su tarjeta y se pisaban entre
       ellos. Ahora la rejilla mide lo que mide su contenido y quien hace
       scroll es .res-wrap, que ya lo tiene puesto. */
    flex: 0 0 auto;
}

.res-bloque {
    display: flex;
    flex-direction: column;
    /* Una tarjeta con esquinas redondeadas cuyo contenido asoma por debajo
       no parece llena: parece rota. */
    overflow: hidden;
    gap: 11px;
    padding: clamp(13px, 1.1vw, 20px);
    border-radius: 16px;
    background: rgba(255, 255, 255, .028);
    box-shadow: inset 0 0 0 1px rgba(255, 255, 255, .05);
    min-height: 0;
}

/* ---------- Últimas 24 h ---------- */
.res-24 {
    display: flex;
    flex-direction: column;
    gap: 9px;
}

.res-24-fila {
    display: flex;
    align-items: center;
    gap: 11px;
}

.res-24-nom {
    width: 74px;
    flex-shrink: 0;
    font-size: clamp(10px, .18vw + 8px, 13px);
    color: #8a897f;
}

.res-24-barra {
    flex: 1;
    height: 8px;
    min-width: 0;
    border-radius: 999px;
    background: rgba(255, 255, 255, .05);
    overflow: hidden;
}

.res-24-barra i {
    display: block;
    height: 100%;
    width: 0;
    border-radius: 999px;
    transition: width .5s var(--ease, ease);
}

.res-24-fila[data-t="ban"]  .res-24-barra i { background: var(--danger, #d64d4d); }
.res-24-fila[data-t="warn"] .res-24-barra i { background: var(--warn, #d8a13a); }
.res-24-fila[data-t="kick"] .res-24-barra i { background: #7d8fa8; }

.res-24-n {
    width: 30px;
    flex-shrink: 0;
    text-align: right;
    font-size: clamp(11px, .2vw + 9px, 14px);
    font-weight: 700;
    color: var(--bone, #e8e6de);
    font-variant-numeric: tabular-nums;
}

/* ---------- Equipo ---------- */
.res-equipo {
    display: flex;
    flex-direction: column;
    gap: 6px;
    overflow-y: auto;
    min-height: 0;
}

.res-eq {
    display: flex;
    align-items: center;
    gap: 10px;
    padding: 7px 12px;
    border-radius: 999px;
    background: rgba(255, 255, 255, .04);
}

.res-eq-nom {
    flex: 1;
    min-width: 0;
    font-size: clamp(11px, .2vw + 9px, 13px);
    color: #b5b3a9;
    /* Se parte en varias líneas antes que recortarse. */
    overflow-wrap: anywhere;
}

.res-eq-n {
    flex-shrink: 0;
    padding: 1px 9px;
    border-radius: 999px;
    background: rgba(255, 255, 255, .07);
    font-size: 11px;
    font-weight: 700;
    color: var(--bone, #e8e6de);
    font-variant-numeric: tabular-nums;
}

/* ---------- Placa de pie ---------- */
.res-pieplaca {
    display: flex;
    justify-content: space-between;
    align-items: center;
    gap: 12px;
    font-size: clamp(9px, .16vw + 7px, 12px);
    color: #6e6d65;
    letter-spacing: .04em;
}

.res-actualiza { font-variant-numeric: tabular-nums; }

/* ============================================================
   PANTALLAS ESTRECHAS
   El panel se estira con clamp(), pero cuatro tarjetas en fila
   dejan de leerse por debajo de cierto ancho.
   ============================================================ */
@media (max-width: 1180px) {
    .res-cifras { grid-template-columns: repeat(2, minmax(0, 1fr)); }
    .res-fila   { grid-template-columns: minmax(0, 1fr); }
}

@media (max-width: 900px) {
    .rail { min-width: 0; }
    .rl > span { display: none; }        /* solo iconos, pero nada recortado */
    .rl { justify-content: center; padding: 10px; }
    .cinta-dato i { display: none; }
}

/* ============================================================
   DAR COSAS — botones y su ventana
   ------------------------------------------------------------
   Sustituyen a las cuatro filas de campo+botón que vivían dentro
   de la ficha. Aquella maqueta desbordaba el hueco (689 px de
   contenido en 611) y el usuario veía el bloque cortado por
   abajo, que es de las cosas que menos toleramos.
   ============================================================ */
.dc-dar {
    display: grid;
    grid-template-columns: repeat(4, minmax(0, 1fr));   /* minmax(0,·): sin él,
        el mínimo es el ancho del texto y la rejilla se sale del panel */
    gap: 8px;
    margin-top: 14px;
    padding-top: 14px;
    border-top: 1px solid rgba(255, 255, 255, .07);
}

.dar-btn {
    background: rgba(255, 255, 255, .03);
    border: 1px solid rgba(255, 255, 255, .09);
    clip-path: var(--cut-sm);
    color: var(--bone);
    font-family: inherit;
    font-size: clamp(11px, .2vw + 9px, 14px);
    font-weight: 600;
    letter-spacing: .04em;
    padding: 11px 8px;
    cursor: pointer;
    transition: background .18s var(--ease), border-color .18s var(--ease),
                transform .18s var(--ease);
}
.dar-btn::before { content: '+'; margin-right: 6px; opacity: .5; font-weight: 400; }
.dar-btn:hover {
    background: linear-gradient(160deg, rgba(74,144,217,.16), rgba(74,144,217,.04));
    border-color: rgba(74,144,217,.5);
    transform: translateY(-2px);
}
.dar-btn:active { transform: scale(.97); }

/* --- La ventana --- */
.tool-campos { display: flex; gap: 10px; margin-top: 12px; }
.tool-campo { flex: 1; display: flex; flex-direction: column; gap: 5px; min-width: 0; }
.tool-campo.corto { flex: 0 0 96px; }
.tool-campo[data-hide="true"] { display: none; }
.tool-campo > span {
    font-size: 11px;
    letter-spacing: .1em;
    text-transform: uppercase;
    color: rgba(255, 255, 255, .42);
}
.tool-campo .mini-input { width: 100%; }

.tool-nota {
    margin-top: 12px;
    font-size: 12px;
    line-height: 1.5;
    color: rgba(255, 255, 255, .48);
}
.tool-nota:empty { display: none; }

/* Los atajos negativos se marcan: quitar dinero no es lo mismo que darlo,
   y en una lista de números todos iguales el signo se pasa por alto. */
.srv-chip.neg { border-color: rgba(229, 72, 77, .35); color: rgba(229, 72, 77, .9); }
.srv-chip.neg:hover {
    background: linear-gradient(160deg, rgba(229,72,77,.16), rgba(229,72,77,.04));
    border-color: var(--danger);
    color: #ff8b8f;
}

/* Refuerzo de las acciones graves. El icono ya salía rojo, pero en una
   rejilla de doce botones idénticos esa señal sola es demasiado débil:
   "Matar" tiene que distinguirse de "Curar" sin buscarlo. */
.act-btn.danger { border-color: rgba(229, 72, 77, .28); }
.act-btn.danger span { color: rgba(255, 173, 176, .92); }

/* ============================================================
   ACCIONES POR FAMILIA
   ------------------------------------------------------------
   Doce botones iguales en fila se leen por POSICIÓN, no por
   etiqueta — y equivocarse de posición aquí es matar a alguien
   queriendo curarlo. Van agrupados por lo que hacen, de lo
   inocuo a lo grave, y lo irreversible se aparta.
   ============================================================ */
.act-fam {
    font-size: 11px;
    letter-spacing: .12em;
    text-transform: uppercase;
    color: rgba(255, 255, 255, .38);
    margin: 14px 0 7px;
}
.act-fam:first-child { margin-top: 0; }

.act-fila {
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(118px, 1fr));
    gap: 8px;
}

/* La zona de riesgo se separa de verdad: línea, sangrado y aviso.
   No basta con teñir el botón — lo que evita el accidente es que
   la mano tenga que ir a otro sitio. */
.act-fam.riesgo {
    color: rgba(229, 72, 77, .8);
    margin-top: 18px;
    padding-top: 14px;
    border-top: 1px solid rgba(229, 72, 77, .22);
}
.act-fam.riesgo::before { content: '▲ '; }
.act-fila.riesgo {
    grid-template-columns: repeat(auto-fill, minmax(118px, 1fr));
    padding: 10px;
    background: rgba(229, 72, 77, .05);
    border: 1px solid rgba(229, 72, 77, .16);
    clip-path: var(--cut-sm);
}

/* Botón de acción en horizontal: icono al lado del texto, no encima.
   Apilados medían 75 px de alto y la ficha entera se iba a 1001 px en
   un hueco de 611. Así bajan a ~40 px y cabe casi todo sin desplazar,
   que es como se lee una lista de acciones: de un vistazo. */
.act-btn {
    flex-direction: row;
    align-items: center;
    justify-content: flex-start;
    gap: 9px;
    padding: 10px 11px;
    text-align: left;
}
.act-btn svg { width: 17px; height: 17px; flex: 0 0 17px; }
.act-btn span {
    /* Sin recortes: si el nombre no cabe, se estrecha la rejilla, no el
       texto. Cortar con puntos suspensivos aquí sería un defecto. */
    white-space: nowrap;
}
.act-fila { grid-template-columns: repeat(auto-fill, minmax(146px, 1fr)); }
.act-fila.riesgo { grid-template-columns: repeat(auto-fill, minmax(146px, 1fr)); }

/* .actions-grid ya NO es la rejilla de botones: ahora contiene familias
   (cabecera + fila). Si sigue siendo `grid` de 3 columnas, cada cabecera
   y cada fila caen en una celda y los grupos salen uno al lado de otro
   en vez de uno debajo de otro. La rejilla vive ahora en .act-fila. */
.actions-grid { display: block; margin-bottom: 0; }

/* ============================================================
   FICHA DEL JUGADOR — barras, expediente e identificadores
   ============================================================ */
.barras { display: grid; grid-template-columns: 1fr 1fr; gap: 12px; margin: 14px 0; }
.barra-alto {
    display: flex; justify-content: space-between; align-items: baseline;
    margin-bottom: 5px;
}
.barra-alto span {
    font-size: 11px; letter-spacing: .1em; text-transform: uppercase;
    color: rgba(255, 255, 255, .42);
}
.barra-alto b { font-size: 14px; color: var(--bone); }
.barra-riel {
    height: 5px; background: rgba(255, 255, 255, .07);
    border-radius: 3px; overflow: hidden;
}
.barra-riel i {
    display: block; height: 100%; width: 0;
    background: linear-gradient(90deg, #e0574c, #34d399);
    /* El degradado va sobre el RIEL, no sobre el relleno: así el color
       depende de cuánta vida queda, no del ancho de la barra. Si se pinta
       sobre el relleno, al 10 % de vida sale verde igualmente. */
    background-size: calc(100% * var(--esc, 1)) 100%;
    transition: width .35s var(--ease);
}
.barra { --esc: 1; }
.barra .barra-riel i { background-size: 20rem 100%; }
.barra.chaleco .barra-riel i { background: linear-gradient(90deg, #4a90d9, #7fd4f0); }

.dc-cols {
    display: grid; grid-template-columns: repeat(auto-fit, minmax(190px, 1fr));
    gap: 16px; margin: 16px 0 4px;
    padding: 14px 0; border-top: 1px solid rgba(255, 255, 255, .07);
    border-bottom: 1px solid rgba(255, 255, 255, .07);
}
.dc-col-tit {
    font-size: 11px; letter-spacing: .12em; text-transform: uppercase;
    color: rgba(255, 255, 255, .38); margin-bottom: 9px;
}
.dc-datos { margin: 0; display: grid; grid-template-columns: auto 1fr; gap: 4px 12px; }
.dc-datos dt { font-size: 12.5px; color: rgba(255, 255, 255, .5); }
.dc-datos dd {
    margin: 0; font-size: 12.5px; color: var(--bone);
    text-align: right; font-variant-numeric: tabular-nums;
}
.dc-datos dd.malo { color: #ff9a9d; }

/* --- Identificadores --- */
.dc-ids { display: flex; flex-direction: column; gap: 5px; }
.id-fila {
    display: grid; grid-template-columns: 74px minmax(0, 1fr) 26px;
    align-items: center; gap: 7px;
    background: rgba(0, 0, 0, .3);
    border: 1px solid rgba(255, 255, 255, .06);
    border-radius: 3px; padding: 5px 7px;
}
.id-tipo { font-size: 10.5px; color: rgba(255, 255, 255, .42); }
.id-valor {
    font-family: ui-monospace, Consolas, monospace; font-size: 11px;
    color: rgba(255, 255, 255, .8);
    /* Se recorta con puntos suspensivos A PROPÓSITO y sólo aquí: una
       licencia son 40 caracteres hexadecimales que nadie lee ni memoriza,
       lo que se hace con ella es copiarla — y para eso está el botón.
       El valor entero se ve al pasar por encima. */
    overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.id-fila:hover .id-valor { overflow: visible; text-overflow: clip; }
.id-copiar {
    background: none; border: none; cursor: pointer; padding: 3px;
    color: rgba(255, 255, 255, .35);
    transition: color .18s var(--ease);
}
.id-copiar svg { width: 14px; height: 14px; fill: none; stroke: currentColor; stroke-width: 1.8; }
.id-copiar:hover { color: var(--accent-bright); }
.id-copiar.hecho { color: var(--ok); }

/* ============================================================
   COLOR POR FAMILIA
   ------------------------------------------------------------
   Con doce botones grises y uno rojo, el ojo agrupa por POSICIÓN.
   Con color, agrupa por SIGNIFICADO — y «Traer» deja de poder
   confundirse con «Matar» aunque estén cerca.

   El color va en el icono y en una línea a la izquierda, no en el
   fondo: doce rectángulos de colores serían un semáforo. Lo justo
   para que se distingan de un vistazo sin gritar.
   ============================================================ */
.act-btn { position: relative; }
.act-btn::before {
    content: '';
    position: absolute; left: 0; top: 22%; bottom: 22%;
    width: 2px; border-radius: 2px;
    background: var(--fam, transparent);
    opacity: .75;
    transition: opacity .18s var(--ease), top .18s var(--ease), bottom .18s var(--ease);
}
.act-btn:hover::before { opacity: 1; top: 12%; bottom: 12%; }
.act-btn svg { stroke: var(--fam, var(--accent-bright)); }

.act-btn.fam-ver     { --fam: #4a90d9; }   /* mirar, no tocar */
.act-btn.fam-mover   { --fam: #7fd4f0; }   /* movimiento */
.act-btn.fam-salud   { --fam: #34d399; }   /* devolver a la vida */
.act-btn.fam-moderar { --fam: #f0a63c; }   /* sancionar: ámbar, avisa */
.act-btn.fam-riesgo  { --fam: #e5484d; }   /* irreversible */

/* La cabecera de cada familia se tiñe igual, para que la pareja
   título-botones se lea como un bloque. */
.act-fam { position: relative; padding-left: 10px; }
.act-fam::after {
    content: '';
    position: absolute; left: 0; top: 50%; transform: translateY(-50%);
    width: 4px; height: 4px; border-radius: 50%;
    background: currentColor; opacity: .5;
}

/* ============================================================
   REGISTRO
   ============================================================ */
.reg-wrap { display: flex; flex-direction: column; height: 100%; min-height: 0; }
.reg-barra {
    display: flex; align-items: center; gap: 12px; flex-wrap: wrap;
    margin-bottom: 12px;
}
.reg-filtros { display: flex; gap: 6px; flex-wrap: wrap; }
.reg-cat-btn {
    background: rgba(255, 255, 255, .04);
    border: 1px solid rgba(255, 255, 255, .08);
    clip-path: var(--cut-sm);
    color: rgba(255, 255, 255, .55);
    font: inherit; font-size: 12.5px; padding: 6px 11px; cursor: pointer;
    transition: background-color .18s var(--ease), color .18s var(--ease),
                border-color .18s var(--ease);
}
.reg-cat-btn:hover { color: var(--bone); background: rgba(255, 255, 255, .07); }
.reg-cat-btn.sel {
    background: rgba(74, 144, 217, .16);
    border-color: rgba(74, 144, 217, .5);
    color: var(--accent-bright);
}
.reg-solo {
    display: flex; align-items: center; gap: 7px;
    font-size: 12.5px; color: rgba(255, 255, 255, .55); cursor: pointer;
}
.reg-barra .search { flex: 1; min-width: 200px; }

.reg-tabla {
    flex: 1; min-height: 0; overflow-y: auto;
    border: 1px solid rgba(255, 255, 255, .07);
    clip-path: var(--cut-sm);
}
.reg-fila {
    display: grid;
    /* minmax(0,·) en las dos últimas: sin él, un detalle largo ensancha la
       rejilla y saca barra horizontal en vez de repartirse. */
    grid-template-columns: 104px 96px 128px 132px 132px minmax(0, 1fr);
    gap: 10px; align-items: center;
    padding: 8px 12px;
    border-bottom: 1px solid rgba(255, 255, 255, .04);
    font-size: 12.5px;
}
.reg-fila:last-child { border-bottom: 0; }
.reg-fila:hover { background: rgba(255, 255, 255, .03); }
.reg-fila.grave { box-shadow: inset 2px 0 0 var(--danger); }

.reg-cuando { color: rgba(255, 255, 255, .42); white-space: nowrap; }
.reg-cat {
    font-size: 10.5px; letter-spacing: .06em; text-transform: uppercase;
    padding: 2px 7px; border-radius: 999px;
    background: rgba(255, 255, 255, .06); color: rgba(255, 255, 255, .55);
    justify-self: start;
}
.reg-cat.cat-moderacion { background: rgba(229,72,77,.14);  color: #ff9a9d; }
.reg-cat.cat-economia   { background: rgba(52,211,153,.14); color: #6ee7b7; }
.reg-cat.cat-vigilancia { background: rgba(127,212,240,.14);color: #a5e4f7; }
.reg-cat.cat-servidor   { background: rgba(240,166,60,.14); color: #f5c37a; }

.reg-accion { color: var(--bone); font-weight: 600; }
.reg-quien  { color: rgba(255, 255, 255, .62); }
.reg-sobre  { color: rgba(255, 255, 255, .62); }
.reg-sobre i { color: rgba(255, 255, 255, .25); font-style: normal; }
.reg-detalle {
    color: rgba(255, 255, 255, .42);
    /* Aquí SÍ se recorta, y es la única excepción: el detalle es contexto,
       no el dato. El valor entero se ve al pasar por encima de la fila. */
    overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.reg-fila:hover .reg-detalle { overflow: visible; white-space: normal; }

.reg-vacio { padding: 40px; text-align: center; color: rgba(255, 255, 255, .35); }
.reg-pie {
    display: flex; align-items: center; justify-content: space-between;
    margin-top: 12px; font-size: 12.5px; color: rgba(255, 255, 255, .45);
}
.reg-pag { display: flex; gap: 8px; }
.reg-pag .mini-btn:disabled { opacity: .35; cursor: not-allowed; }

/* Historial en la ficha del jugador */
.dc-ultimas { margin-top: 14px; }
.ult-fila {
    display: grid; grid-template-columns: 78px 104px 120px minmax(0, 1fr);
    gap: 10px; align-items: center;
    padding: 6px 0; font-size: 12px;
    border-bottom: 1px solid rgba(255, 255, 255, .04);
}
.ult-fila.grave .ult-accion { color: #ff9a9d; }
.ult-cuando { color: rgba(255, 255, 255, .38); }
.ult-accion { color: var(--bone); font-weight: 600; }
.ult-quien  { color: rgba(255, 255, 255, .55); }
.ult-detalle {
    color: rgba(255, 255, 255, .40);
    overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}

/* ============================================================
   Servicio del staff
   ------------------------------------------------------------
   Reaprovecha .res-bloque, .res-24-* y .res-eq del resumen: son
   las mismas dos formas —barra normalizada y fila de ranking— y
   meter un lenguaje nuevo para el mismo dato solo hace que la
   pantalla parezca de otro sitio.
   ============================================================ */
.res-servicio{grid-column:1 / -1}

/* El titulo con su apunte a la derecha. Con float el apunte se salia de la
   caja del titulo y arrastraba la primera linea del contenido. */
.res-servicio .srv-title{
  display:flex;align-items:baseline;justify-content:space-between;gap:12px;
}
.res-sub{
  font-style:normal;font-weight:400;text-transform:none;
  color:rgba(var(--skal-accent-rgb),.55);font-size:11px;letter-spacing:.02em;
  white-space:nowrap;flex:0 0 auto;
}

.res-mio{margin:2px 0 10px}
.res-mio-p{
  display:inline-block;border-radius:999px;padding:4px 12px;
  font-size:12px;letter-spacing:.01em;
  background:rgba(255,255,255,.045);border:1px solid var(--line);color:var(--bone);
}
/* Estar de servicio es un estado, no una alarma: se marca con el acento
   de siempre y nada más. Sin glow ni parpadeo. */
.res-mio-p.on{
  background:rgba(var(--skal-accent-rgb),.14);
  border-color:rgba(var(--skal-accent-rgb),.42);
}

.res-dias{margin-bottom:12px}

/* Fila de dia. NO reutiliza .res-24-*: aquella cifra mide 30 px fijos con
   flex-shrink:0 porque se hizo para "12", y aqui recibe "3 h 20 min", que
   se partia en tres lineas y triplicaba el alto de cada fila. Ese era el
   descuadre que se veia en juego. */
.sv-fila-dia{display:flex;align-items:center;gap:10px;margin-bottom:5px}
.sv-dia-nom{
  flex:0 0 auto;width:46px;
  color:var(--bone);opacity:.62;font-size:11.5px;
  font-variant-numeric:tabular-nums;
}
.sv-dia-barra{
  flex:1;min-width:0;height:8px;border-radius:999px;
  background:rgba(255,255,255,.06);overflow:hidden;
}
/* El color va AQUI. Las barras de "Ultimas 24 horas" solo se pintan a traves
   de [data-t="ban|warn|kick"], asi que reutilizarlas sin ese atributo dejaba
   los siete carriles transparentes. */
.sv-dia-barra i{
  display:block;height:100%;border-radius:999px;
  background:rgb(var(--skal-accent-rgb));
  width:0;transition:width .5s var(--ease);
}
.sv-dia-n{
  flex:0 0 auto;
  color:var(--bone);opacity:.75;font-size:11.5px;
  white-space:nowrap;         /* nunca envuelve: era la causa del descuadre */
  font-variant-numeric:tabular-nums;
}

/* Fila de persona: nombre a la izquierda, y las dos cifras separadas. */
.res-servicio .res-eq{display:flex;align-items:baseline;gap:10px}
.res-servicio .res-eq-nom{flex:1;min-width:0;overflow-wrap:anywhere}
.sv-horas{
  flex:0 0 auto;color:var(--bone);font-size:12.5px;
  font-variant-numeric:tabular-nums;white-space:nowrap;
}
.sv-acciones{
  flex:0 0 auto;color:var(--bone);opacity:.5;font-size:11px;white-space:nowrap;
}

/* Tu propia fila, resaltada lo justo para encontrarla de un vistazo en
   una lista de quince. */
.res-eq.yo .res-eq-nom{background:rgba(var(--skal-accent-rgb),.14)}
.res-eq.yo .res-eq-n{color:var(--bone)}
