/* =====================================================================
   ProHygiene Portal — sistema visual de la app
   Se apoya en marca/brand.css (color, tipografía, botón píldora).
   Criterio: aire, superficies suaves, azul de marca como acento y no
   como bloque macizo. Nada de colores de marca hardcodeados.
   ===================================================================== */

:root {
  /* Neutros derivados (no son colores de marca, son la escala de grises) */
  --ph-bg:          #f3f6fb;
  --ph-superficie:  #ffffff;
  --ph-borde:       #e3eaf5;
  --ph-borde-2:     #d2ddee;
  --ph-texto-2:     #55647e;
  --ph-texto-3:     #8794ab;

  /* Colores de marca oscurecidos SOLO para texto: el cyan y el naranja de
     marca no llegan a contraste legible sobre fondos claros. El matiz se
     mantiene, baja la luminosidad. No usarlos como fondo ni en el logo. */
  --ph-banos-texto: #0f6f96;   /* deriva de --ph-banos  #00AEEF */
  --ph-pisos-texto: #a1500f;   /* deriva de --ph-pisos  #F47521 */

  /* Radios y elevación */
  --ph-r-lg: 20px;
  --ph-r-md: 14px;
  --ph-r-sm: 10px;
  --ph-elev-1: 0 1px 2px rgba(13,32,84,.05), 0 8px 24px rgba(13,32,84,.06);
  --ph-elev-2: 0 16px 40px rgba(13,32,84,.16);
  --ph-anillo: 0 0 0 4px rgba(0,27,114,.13);
}

* { box-sizing: border-box; }
html, body { height: 100%; }

body.ph {
  /* Lavado superior sereno en vez de manchones radiales: la página nace
     apenas más fría arriba y se asienta en el gris azulado de base. */
  background:
    radial-gradient(880px 300px at 88% -120px, rgba(0,174,239,.07), transparent 70%),
    linear-gradient(180deg, #e9effa 0%, var(--ph-bg) 380px);
  color: var(--ph-texto);
  -webkit-font-smoothing: antialiased;
}

/* -------- utilidades -------- */
.ph-hide   { display: none !important; }
.ph-muted  { color: var(--ph-texto-2); }
.ph-center { text-align: center; }
a { color: var(--ph-azul); }

@media (prefers-reduced-motion: no-preference) {
  @keyframes ph-in { from { opacity: 0; transform: translateY(8px); } to { opacity: 1; transform: none; } }
  .ph-anim { animation: ph-in .32s cubic-bezier(.22,.8,.3,1) both; }
}

/* =====================================================================
   LOGIN
   ===================================================================== */
.login-wrap {
  min-height: 100vh;
  display: grid;
  place-items: center;
  padding: 24px;
  /* El login es la portada del portal: navy de marca de punta a punta,
     con las ondas del activo marcario insinuadas abajo. Es la única
     pantalla donde la marca puede ocupar todo el lienzo. */
  background:
    url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 1440 320' preserveAspectRatio='none'%3E%3Cpath fill='%2300AEEF' fill-opacity='.12' d='M0,256 C260,200 520,290 780,258 C1040,226 1240,180 1440,226 L1440,320 L0,320 Z'/%3E%3Cpath fill='%23ffffff' fill-opacity='.05' d='M0,208 C240,150 480,268 720,236 C960,204 1200,120 1440,180 L1440,320 L0,320 Z'/%3E%3C/svg%3E") bottom / 100% 240px no-repeat,
    linear-gradient(165deg, #001450 0%, var(--ph-azul) 52%, #102f94 100%);
}
.login-card {
  width: 100%;
  max-width: 420px;
  background: var(--ph-superficie);
  border-radius: var(--ph-r-lg);
  box-shadow: 0 24px 70px rgba(0, 8, 40, .45);
  overflow: hidden;
  animation: ph-in .4s cubic-bezier(.22,.8,.3,1) both;
}
.login-head {
  position: relative;
  /* Mismo navy que el fondo del isologo: se funde sin parche. Contra la
     página navy, la card se despega por la sombra y los bordes redondos. */
  background: var(--ph-azul);
  padding: 34px 28px 46px;
  text-align: center;
  overflow: hidden;
}
/* Onda de marca: curva blanca que funde el header con el cuerpo de la card. */
.login-head::after {
  content: "";
  position: absolute; left: -1px; right: -1px; bottom: -1px; height: 30px;
  background: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 1440 100' preserveAspectRatio='none'%3E%3Cpath fill='%23ffffff' d='M0,58 C240,104 480,8 720,36 C960,64 1200,96 1440,50 L1440,100 L0,100 Z'/%3E%3C/svg%3E") no-repeat;
  background-size: 100% 100%;
}
.login-head img { height: 46px; position: relative; z-index: 1; }
.login-head p {
  color: rgba(255,255,255,.82);
  margin: 12px 0 0; font-size: .8rem; letter-spacing: .4px;
  position: relative; z-index: 1;
}
.login-body { padding: 30px 30px 34px; }
.login-body h1 { font-size: 1.45rem; margin: 0 0 6px; }

/* -------- Acceso alternativo (cuenta de Google) --------
   Va debajo del formulario, separado por una línea con "o". El botón lo
   dibuja Google (no se puede restilar), así que se lo pide en versión
   píldora para que converse con el botón primario de marca. */
.login-alt { margin-top: 4px; }
.login-sep {
  display: flex; align-items: center; gap: 12px;
  margin: 0 0 18px;
  color: var(--ph-texto-2); font-size: .78rem;
}
.login-sep::before, .login-sep::after {
  content: ""; flex: 1; height: 1px; background: var(--ph-borde-2);
}
.google-btn { display: flex; justify-content: center; min-height: 40px; }

/* Botón de SSO con Google Workspace. Es secundario respecto de "Ingresar":
   va en línea, no macizo, para que siga habiendo un solo botón primario. */
.ph-btn.linea-google {
  display: flex; align-items: center; justify-content: center; gap: 10px;
  background: #fff; color: var(--ph-texto);
  box-shadow: inset 0 0 0 1.5px var(--ph-borde-2);
  font-size: .9rem;
  transition: box-shadow .18s, background .18s;
}
.ph-btn.linea-google:hover {
  background: #f7f9fc;
  box-shadow: inset 0 0 0 1.5px var(--ph-azul);
}
.ph-btn.linea-google .g-mark {
  font-weight: 800; font-size: 1.05rem; line-height: 1;
  background: conic-gradient(from -45deg, #EA4335, #FBBC05, #34A853, #4285F4, #EA4335);
  -webkit-background-clip: text; background-clip: text; color: transparent;
}
.login-alt-nota {
  margin: 14px 0 0; text-align: center;
  font-size: .76rem; line-height: 1.5; color: var(--ph-texto-2);
}

/* =====================================================================
   FORMULARIOS
   ===================================================================== */
.field { margin-bottom: 18px; }
.field label {
  display: block; font-weight: 600; font-size: .8rem;
  margin-bottom: 7px; color: var(--ph-texto-2);
}
.field input, .field select {
  width: 100%;
  font-family: var(--ph-font);
  font-size: .95rem;
  color: var(--ph-texto);
  padding: .8em 1em;
  border: 1.5px solid var(--ph-borde-2);
  border-radius: 12px;
  background: #fbfcfe;
  outline: none;
  transition: border-color .18s, box-shadow .18s, background .18s;
}
.field input:hover, .field select:hover { border-color: #c3d1e6; }
.field input:focus, .field select:focus {
  border-color: var(--ph-azul);
  box-shadow: var(--ph-anillo);
  background: #fff;
}
.field input[readonly] { background: #f4f7fb; color: var(--ph-texto-2); }

.ph-btn {
  box-shadow: 0 4px 14px rgba(0,27,114,.22);
  transition: background .18s, transform .12s, box-shadow .18s;
}
.ph-btn:hover  { transform: translateY(-1px); box-shadow: 0 8px 22px rgba(0,27,114,.28); }
.ph-btn:active { transform: translateY(0); }
.ph-btn:disabled { opacity: .5; cursor: not-allowed; box-shadow: none; transform: none; }
.ph-btn.full { width: 100%; text-align: center; padding: .9em; }
.ph-btn.sm   { padding: .58em 1.2em; font-size: .85rem; }
.ph-btn.gray   { background: #7b8aa3; box-shadow: 0 4px 14px rgba(123,138,163,.25); }
.ph-btn.gray:hover   { background: #67758d; }
.ph-btn.danger { background: #c2413f; box-shadow: 0 4px 14px rgba(194,65,63,.25); }
.ph-btn.danger:hover { background: #a33432; }

/* -------- avisos -------- */
.alert {
  background: #fdeceb;
  color: #9a2b28;
  border: 1px solid #f6cecb;
  border-left: 4px solid #d9534f;
  border-radius: var(--ph-r-sm);
  padding: .8em 1em;
  font-size: .86rem;
  margin-bottom: 16px;
  animation: ph-in .25s ease both;
}
.alert.ok {
  background: #e9f7ef; color: #1c6b3f;
  border-color: #c3e8d2; border-left-color: #2fa36b;
}

/* =====================================================================
   TOPBAR + CRUMB
   ===================================================================== */
.topbar {
  position: sticky; top: 0; z-index: 20;
  /* Navy pleno de marca, sin degradado: la barra es el ancla visual y no
     compite con el contenido. El filo cyan de abajo es la firma de marca. */
  background: var(--ph-azul);
  color: #fff;
  display: flex; align-items: center; gap: 18px;
  padding: 0 22px 0 0; min-height: 56px;
  box-shadow: 0 2px 16px rgba(0,20,80,.22);
}
.topbar::after {
  content: ""; position: absolute; left: 0; right: 0; bottom: 0; height: 2px;
  background: linear-gradient(90deg, var(--ph-banos) 0%, var(--ph-azul-claro) 45%, transparent 85%);
  pointer-events: none;
}
.topbar .spacer { flex: 1; }

/* Bloque de marca: el navy del isologo (var(--ph-azul)) ocupa todo el alto y
   el logo se funde en él; el remate diagonal repite la itálica del isologo. */
.marca-bloque {
  align-self: stretch; display: flex; align-items: center;
  /* MISMO navy que el PNG del isologo: cualquier otro tono deja un
     parche rectangular alrededor del logo. */
  background: var(--ph-azul);
  padding: 0 20px 0 22px;
  position: relative; margin-right: 16px;
  flex-shrink: 0;
}
.marca-bloque img { height: 26px; display: block; }
.marca-bloque::after {
  content: ""; position: absolute; top: 0; bottom: 0; right: -13px; width: 13px;
  background: var(--ph-azul);
  clip-path: polygon(0 0, 100% 0, 0 100%);
}
.marca-sub {
  font-size: .58rem; font-weight: 800; letter-spacing: 2.6px; color: rgba(255,255,255,.72);
  border-left: 1px solid rgba(255,255,255,.28);
  padding-left: 11px; margin-left: 12px; padding-top: 2px;
}
.topbar .who {
  font-size: .78rem; color: rgba(255,255,255,.78);
  text-align: right; line-height: 1.35;
}
.topbar .who b { color: #fff; display: block; font-size: .84rem; }
.topbar a.link {
  color: #fff; text-decoration: none; font-size: .82rem; font-weight: 600;
  padding: 6px 12px; border-radius: 999px;
  background: rgba(255,255,255,.12);
  transition: background .18s;
  white-space: nowrap;
}
.topbar a.link:hover { background: rgba(255,255,255,.24); }
.topbar a.marca-bloque { text-decoration: none; }
.topbar a.marca-bloque:hover img { transform: scale(1.04); }
.topbar a.marca-bloque img { transition: transform .18s; }
.topbar :focus-visible { outline: 2px solid #fff; outline-offset: 2px; }

/* =====================================================================
   NAVEGACIÓN — atrás + ruta  (la arma js/api.js, igual en todas)
   El botón de atrás está siempre en el mismo lugar y dice a dónde va:
   volver no debería obligar a leer la barra entera para encontrarlo.
   ===================================================================== */
.nav-atras {
  display: inline-flex; align-items: center; gap: 5px; flex-shrink: 0;
  color: #fff; text-decoration: none;
  font-size: .82rem; font-weight: 700; white-space: nowrap;
  padding: 7px 14px 7px 9px; border-radius: 999px;
  background: rgba(255,255,255,.14);
  transition: background .18s, transform .18s;
}
.nav-atras:hover { background: rgba(255,255,255,.28); transform: translateX(-2px); }
.nav-atras svg {
  width: 17px; height: 17px; flex-shrink: 0;
  fill: none; stroke: currentColor; stroke-width: 2.4;
  stroke-linecap: round; stroke-linejoin: round;
}

.nav-ruta {
  display: flex; align-items: center; gap: 2px; min-width: 0;
  font-size: .8rem; margin-left: 4px;
}
.nav-ruta a {
  color: rgba(255,255,255,.76); text-decoration: none; white-space: nowrap;
  padding: 4px 8px; border-radius: 8px; transition: background .16s, color .16s;
}
.nav-ruta a:hover { color: #fff; background: rgba(255,255,255,.16); }
.nav-sep { color: rgba(255,255,255,.42); font-size: .8rem; }
/* Dónde estás no se recorta nunca: si falta lugar, cede la franquicia y
   después los niveles intermedios (para volver está el botón de atrás). */
.nav-actual { font-weight: 800; color: #fff; padding: 4px 6px; flex-shrink: 0; }
.nav-franq {
  font-weight: 600; min-width: 70px;
  max-width: 260px; overflow: hidden; text-overflow: ellipsis;
}
@media (max-width: 1180px) { .nav-nivel { display: none; } }

.nav-acciones { display: flex; align-items: center; gap: 8px; }

/* -------- avatar: identidad, cambiar franquicia y salir -------- */
.nav-user {
  display: flex; align-items: center; gap: 4px; flex-shrink: 0;
  border: 0; cursor: pointer; font-family: var(--ph-font);
  padding: 4px 6px 4px 4px; border-radius: 999px;
  background: rgba(255,255,255,.12); transition: background .18s;
}
.nav-user:hover { background: rgba(255,255,255,.26); }
.nav-avatar {
  width: 30px; height: 30px; border-radius: 50%;
  display: grid; place-items: center;
  background: #fff; color: var(--ph-azul);
  font-size: .74rem; font-weight: 800; letter-spacing: .3px;
}
.nav-ham {
  width: 17px; height: 17px; fill: none; stroke: rgba(255,255,255,.9);
  stroke-width: 2.2; stroke-linecap: round;
}

/* =====================================================================
   MENÚ LATERAL (drawer) — lo arma js/api.js en todas las pantallas
   ---------------------------------------------------------------------
   Panel deslizante desde la derecha: identidad arriba, navegación en el
   medio (scrollea) y la salida siempre a mano abajo. Las opciones se
   definen en api.js (MENU_PANTALLAS / MENU_ACCESOS): agregar una opción
   nueva es una línea ahí, sin tocar HTML ni CSS.
   ===================================================================== */
.drawer-fondo {
  position: fixed; inset: 0; z-index: 100;
  background: rgba(6, 18, 48, .45);
  -webkit-backdrop-filter: blur(2px); backdrop-filter: blur(2px);
  opacity: 0; pointer-events: none;
  transition: opacity .24s ease;
}
body.menu-abierta .drawer-fondo { opacity: 1; pointer-events: auto; }
body.menu-abierta { overflow: hidden; }

.drawer {
  position: fixed; top: 0; right: 0; bottom: 0; z-index: 101;
  width: min(350px, 92vw);
  display: flex; flex-direction: column;
  background: var(--ph-superficie);
  box-shadow: -18px 0 50px rgba(0, 15, 60, .28);
  transform: translateX(calc(100% + 60px));
  visibility: hidden;   /* cerrado: fuera del foco y de los lectores */
  transition: transform .28s cubic-bezier(.22,.8,.3,1), visibility 0s .28s;
}
body.menu-abierta .drawer {
  transform: none; visibility: visible;
  transition: transform .28s cubic-bezier(.22,.8,.3,1);
}

/* -------- cabecera: quién sos -------- */
.drawer-cab {
  display: flex; align-items: center; gap: 12px;
  padding: 15px 14px 15px 18px;
  background: var(--ph-azul); color: #fff;
  position: relative; flex-shrink: 0;
}
.drawer-cab::after {   /* mismo filo cyan que remata la topbar */
  content: ""; position: absolute; left: 0; right: 0; bottom: 0; height: 2px;
  background: linear-gradient(90deg, var(--ph-banos), transparent 80%);
}
.drawer-cab .nav-avatar { width: 38px; height: 38px; font-size: .84rem; flex-shrink: 0; }
.drawer-quien { flex: 1; min-width: 0; }
.drawer-quien .who {
  text-align: left; font-size: .72rem; color: rgba(255,255,255,.72); line-height: 1.4;
}
.drawer-quien .who b,
.drawer-quien .who span {
  display: block; white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
.drawer-quien .who b { color: #fff; font-size: .9rem; }
.drawer-cerrar {
  flex-shrink: 0; width: 34px; height: 34px; border: 0; border-radius: 50%;
  display: grid; place-items: center; cursor: pointer;
  background: rgba(255,255,255,.12); color: #fff;
  transition: background .16s;
}
.drawer-cerrar:hover { background: rgba(255,255,255,.26); }
.drawer-cerrar:focus-visible { outline: 2px solid #fff; outline-offset: 2px; }
.drawer-cerrar svg {
  width: 16px; height: 16px; fill: none; stroke: currentColor;
  stroke-width: 2.2; stroke-linecap: round;
}

/* -------- cuerpo: secciones de opciones -------- */
.drawer-nav { flex: 1; min-height: 0; overflow-y: auto; padding: 4px 12px 12px; }
.drawer-nav::-webkit-scrollbar { width: 8px; }
.drawer-nav::-webkit-scrollbar-thumb {
  background: #ccd5e3; border-radius: 999px;
  border: 2px solid transparent; background-clip: content-box;
}
.drawer-sec { padding-top: 14px; }
.drawer-sec + .drawer-sec { margin-top: 8px; border-top: 1px solid var(--ph-borde); }
.drawer-tit {
  font-size: .67rem; font-weight: 800; letter-spacing: 1px; text-transform: uppercase;
  color: var(--ph-texto-3); padding: 0 10px; margin-bottom: 6px;
}

.drawer-item {
  display: flex; align-items: center; gap: 11px;
  padding: 8px 10px; margin-bottom: 2px; border-radius: 11px;
  text-decoration: none; color: var(--ph-texto);
  font-size: .87rem; font-weight: 600;
  transition: background .14s;
}
.drawer-item:hover { background: #eef4fd; }
.drawer-item:focus-visible { outline: none; box-shadow: var(--ph-anillo); }
.drawer-item.act {
  background: #e8f0fd; color: var(--ph-azul);
  box-shadow: inset 3px 0 0 var(--ph-azul);
}
.drawer-item .ico {
  display: grid; place-items: center; flex-shrink: 0;
  width: 32px; height: 32px; border-radius: 9px;
  color: var(--ph-azul); font-size: .95rem;
  background: linear-gradient(135deg, rgba(0,27,114,.07), rgba(0,174,239,.10));
}
.drawer-item .ico .phi { width: 16px; height: 16px; }
.drawer-txt { flex: 1; min-width: 0; }
.drawer-txt b {
  display: block; font-weight: 700; line-height: 1.25;
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
.drawer-txt small {
  display: block; font-size: .71rem; font-weight: 500; line-height: 1.3;
  color: var(--ph-texto-3);
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
.drawer-item .ext { font-size: .74rem; color: var(--ph-texto-3); }
.drawer-item:hover .ext { color: var(--ph-azul); }

/* Acciones de la pantalla (solo mobile): botones apilados a lo ancho. */
.drawer-acciones .nav-acciones {
  display: flex; flex-direction: column; align-items: stretch; gap: 8px; padding: 0 6px;
}
.drawer-acciones .ph-btn { width: 100%; text-align: center; }

/* -------- pie: cambiar de franquicia y salir -------- */
.drawer-pie {
  flex-shrink: 0; padding: 10px 12px;
  border-top: 1px solid var(--ph-borde);
  background: #fbfcfe;
}
.drawer-pie .drawer-item { font-size: .85rem; margin-bottom: 0; }
a.drawer-item.salir { color: #a33432; gap: 11px; }
a.drawer-item.salir .ico { color: #a33432; background: rgba(194,65,63,.09); }
a.drawer-item.salir:hover { background: #fdf1f0; }

@media (prefers-reduced-motion: reduce) {
  .drawer, .drawer-fondo { transition: none; }
}

.page { max-width: 1280px; margin: 18px auto 60px; padding: 0 22px; }
.page > h1 { margin: 0 0 6px; }

/* =====================================================================
   FRANJA DE FILTROS (selección de franquicia)
   Buscador + resumen + accesos generales en una sola fila. El título vive
   en la topbar: apilarlo acá con subtítulo y tarjetas empujaba los países
   fuera de la primera pantalla.
   ===================================================================== */
.barra-filtros {
  display: flex; align-items: center; gap: 12px; flex-wrap: wrap;
  margin: 0 0 16px;
}
.barra-filtros .buscador { margin: 0; flex: 1 1 300px; max-width: 420px; }
.barra-filtros .resumen  { white-space: nowrap; }
.barra-filtros .link-accion { margin-left: 0; }

.accesos-fila { display: flex; align-items: center; gap: 8px; flex-wrap: wrap; margin-left: auto; }
.acceso-chip {
  display: inline-flex; align-items: center; gap: 7px;
  background: var(--ph-superficie);
  border: 1px solid var(--ph-borde);
  border-radius: 999px; padding: 7px 14px;
  font-size: .8rem; font-weight: 600; color: var(--ph-texto-2);
  text-decoration: none; white-space: nowrap;
  box-shadow: var(--ph-elev-1);
  transition: border-color .16s, color .16s, transform .16s cubic-bezier(.22,.8,.3,1), box-shadow .16s;
}
.acceso-chip:hover, .acceso-chip:focus-visible {
  border-color: var(--ph-azul); color: var(--ph-azul);
  transform: translateY(-2px); box-shadow: var(--ph-elev-2); outline: none;
}
.acceso-chip .ico { font-size: .95rem; line-height: 1; display: inline-flex; color: var(--ph-azul); }
.acceso-chip .ext { font-size: .72rem; color: var(--ph-texto-3); }
.acceso-chip:hover .ext { color: var(--ph-azul); }

/* En pantallas chicas los accesos bajan a su propio renglón, completo. */
@media (max-width: 900px) {
  .accesos-fila { margin-left: 0; width: 100%; }
}

/* =====================================================================
   BUSCADOR
   ===================================================================== */
.buscador { position: relative; max-width: 540px; margin: 20px 0 10px; }
.buscador input {
  width: 100%;
  font-family: var(--ph-font); font-size: .95rem;
  padding: .85em 2.6em .85em 2.9em;
  border: 1.5px solid var(--ph-borde-2);
  border-radius: 999px;
  background: var(--ph-superficie);
  box-shadow: var(--ph-elev-1);
  outline: none;
  transition: border-color .18s, box-shadow .18s;
}
.buscador input:focus { border-color: var(--ph-azul); box-shadow: var(--ph-anillo); }
.buscador .lupa {
  position: absolute; left: 1.1em; top: 50%; transform: translateY(-50%);
  color: var(--ph-texto-3); font-size: .95rem; pointer-events: none;
}
.buscador .limpiar {
  position: absolute; right: .9em; top: 50%; transform: translateY(-50%);
  border: 0; background: transparent; color: var(--ph-texto-3);
  cursor: pointer; font-size: 1rem; line-height: 1; padding: 4px 6px;
  border-radius: 999px; transition: color .18s, background .18s;
}
.buscador .limpiar:hover { color: var(--ph-azul); background: #eef3fb; }

.resumen-row { display: flex; align-items: center; gap: 12px; flex-wrap: wrap; margin-bottom: 18px; }
.resumen { font-size: .82rem; margin: 0; }
.link-accion {
  margin-left: auto;
  border: 0; background: transparent; cursor: pointer;
  font-family: var(--ph-font); font-size: .8rem; font-weight: 700;
  color: var(--ph-azul);
  padding: 6px 13px; border-radius: 999px;
  transition: background .16s;
}
.link-accion:hover { background: #e9f0fb; }
.link-accion:focus-visible { outline: none; box-shadow: var(--ph-anillo); }

/* =====================================================================
   ACCESOS TRANSVERSALES (no dependen de la franquicia)
   ===================================================================== */
.transversal { margin: 22px 0 6px; }
.transversal-tit {
  font-size: .7rem; font-weight: 700; letter-spacing: 1px;
  text-transform: uppercase; color: var(--ph-texto-3); margin-bottom: 10px;
}
.transversal-grid { display: flex; flex-wrap: wrap; gap: 14px; }
.transversal-grid .card-opcion.compacto { flex: 1 1 300px; max-width: 380px; }

/* =====================================================================
   TARJETAS DE OPCIÓN (menú y accesos)
   ===================================================================== */
.grid-opciones {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(260px, 1fr));
  gap: 18px; margin-top: 22px; max-width: 780px;
}
.card-opcion {
  display: block; position: relative;
  background: var(--ph-superficie);
  border: 1px solid var(--ph-borde);
  border-radius: var(--ph-r-lg);
  padding: 26px 24px;
  text-decoration: none; color: inherit; cursor: pointer;
  box-shadow: var(--ph-elev-1);
  overflow: hidden;
  transition: transform .16s cubic-bezier(.22,.8,.3,1), box-shadow .16s, border-color .16s;
}
/* filo de color que aparece al pasar el mouse */
.card-opcion::before {
  content: ""; position: absolute; left: 0; top: 0; bottom: 0; width: 4px;
  background: linear-gradient(180deg, var(--ph-banos), var(--ph-azul));
  transform: scaleY(0); transform-origin: top;
  transition: transform .22s cubic-bezier(.22,.8,.3,1);
}
.card-opcion:hover, .card-opcion:focus-visible {
  transform: translateY(-3px);
  box-shadow: var(--ph-elev-2);
  border-color: #cfdcf0;
  outline: none;
}
.card-opcion:hover::before, .card-opcion:focus-visible::before { transform: scaleY(1); }
/* El ícono va en un chip tintado: le da peso y color de marca a la card
   sin depender del render del emoji/ícono en cada sistema. */
.card-opcion .ico {
  display: grid; place-items: center;
  width: 46px; height: 46px; border-radius: 13px;
  font-size: 1.5rem; line-height: 1; margin-bottom: 14px;
  color: var(--ph-azul);
  background: linear-gradient(135deg, rgba(0,27,114,.08), rgba(0,174,239,.12));
}
.card-opcion .ico .phi { width: 23px; height: 23px; stroke-width: 1.8; }
.card-opcion .tit  { font-weight: 800; color: var(--ph-azul); font-size: 1.08rem; margin-bottom: 6px; }
.card-opcion .desc { font-size: .85rem; color: var(--ph-texto-2); line-height: 1.5; }

.card-opcion.compacto { max-width: 360px; padding: 16px 18px; }
.card-opcion.compacto .ico  { width: 36px; height: 36px; border-radius: 10px; font-size: 1.1rem; margin-bottom: 8px; }
.card-opcion.compacto .ico .phi { width: 18px; height: 18px; }
.card-opcion.compacto .tit  { font-size: .98rem; margin-bottom: 2px; }
.card-opcion.compacto .desc { font-size: .8rem; }

/* =====================================================================
   SECCIÓN POR PAÍS  (encabezado suave, no un bloque macizo)
   ===================================================================== */
/* La lista de países es una grilla de DOS columnas: las secciones con
   pocas franquicias (sin .ancha) ocupan media fila y conviven de a dos;
   las grandes van a fila completa. align-items:start evita que una
   sección corta se estire para igualar a su vecina alta. */
#lista {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: 12px;
  align-items: start;
}
.pais-sec.ancha { grid-column: 1 / -1; }
@media (max-width: 900px) {
  #lista { grid-template-columns: 1fr; }
}

/* Los colores de bandera los inyecta seleccion.js como --f1/--f2/--f3.
   El azul de marca es el respaldo si un país no está en el mapa. */
.pais-sec {
  --f1: var(--ph-azul); --f2: #7a97cf; --f3: var(--ph-azul-claro);
  position: relative;
  background: var(--ph-superficie);
  border: 1px solid var(--ph-borde);
  border-radius: var(--ph-r-lg);
  overflow: hidden;
  box-shadow: var(--ph-elev-1);
  animation: ph-in .3s ease both;
  transition: box-shadow .18s, transform .18s cubic-bezier(.22,.8,.3,1);
}
/* Un país abierto se despega del resto; cerrado queda al ras. */
.pais-sec:not(.cerrada) { box-shadow: var(--ph-elev-2); }
/* Canto lateral con el color del país: recorre todo el bloque y lo ancla,
   como la pestaña de una carpeta. Reemplaza al filete superior, que flotaba
   suelto sobre el encabezado. */
.pais-sec::before {
  content: ""; position: absolute; top: 0; bottom: 0; left: 0; width: 4px; z-index: 2;
  background: linear-gradient(180deg, var(--f1), var(--f3));
}
.pais-head {
  width: 100%;
  display: flex; align-items: center; gap: 10px;
  padding: 10px 14px;
  background: linear-gradient(90deg, rgba(0,27,114,.07), rgba(0,174,239,.05));
  border: 0; border-bottom: 1px solid var(--ph-borde);
  font-family: var(--ph-font); text-align: left;
  cursor: pointer;
  transition: background .18s, border-color .18s;
}
/* Tinte del país sobre el encabezado, muy suave. Va después del gradiente
   de marca: si el navegador no soporta color-mix, ignora la regla y queda
   el azul institucional. */
/* El tinte nace en el canto de color y se apaga enseguida: sugiere el país
   sin teñir la fila entera (con banderas como la de Bolivia, un degradado
   largo terminaba pareciendo un arcoíris). */
.pais-head {
  background: linear-gradient(90deg,
    color-mix(in srgb, var(--f1) 15%, transparent),
    transparent 44%);
}
.pais-head:hover { background: linear-gradient(90deg, rgba(0,27,114,.12), rgba(0,174,239,.09)); }
.pais-head:hover {
  background: linear-gradient(90deg,
    color-mix(in srgb, var(--f1) 26%, transparent),
    color-mix(in srgb, var(--f1) 6%, transparent) 55%,
    transparent 78%);
}
.pais-head:focus-visible { outline: none; box-shadow: var(--ph-anillo) inset; }

/* Chevron que gira al abrir/cerrar */
.pais-head .chev {
  display: inline-block; color: var(--ph-azul); font-size: .72rem;
  transition: transform .22s cubic-bezier(.22,.8,.3,1);
}
.pais-sec:not(.cerrada) .pais-head .chev { transform: rotate(90deg); }

/* Colapsada: se oculta el cuerpo y el borde del encabezado */
.pais-sec.cerrada .pais-body   { display: none; }
.pais-sec.cerrada .pais-head   { border-bottom-color: transparent; }
.pais-head .nom {
  font-weight: 800; font-size: .86rem; letter-spacing: .5px;
  color: var(--ph-azul);
}
/* Bandera del país, dibujada en CSS (el fondo lo inyecta seleccion.js).
   El anillo la despega del blanco: sin él, las franjas blancas de Perú o
   Argentina se fundirían con la tarjeta. */
.pais-head .flag {
  width: 26px; height: 18px; border-radius: 3px; flex-shrink: 0;
  /* Sin background-size acá: las banderas con cantón (EE.UU., Chile, Panamá,
     Uruguay) traen el tamaño de cada capa en su propio shorthand, y un
     `cover` global lo pisaría dejándolas como un bloque de color. */
  background: var(--flag, linear-gradient(135deg, var(--ph-azul), var(--ph-azul-claro)));
  box-shadow: 0 0 0 1px rgba(10, 26, 58, .22), 0 1px 3px rgba(10, 26, 58, .20);
  transition: transform .18s cubic-bezier(.22,.8,.3,1);
}
.pais-head:hover .flag { transform: scale(1.08); }
.pais-metas { margin-left: auto; display: flex; align-items: center; gap: 8px; flex-shrink: 0; }
.pais-head .cant {
  font-size: .7rem; font-weight: 600;
  color: var(--ph-azul);
  background: rgba(255,255,255,.75);
  border: 1px solid var(--ph-borde);
  padding: 2px 9px; border-radius: 999px;
  white-space: nowrap;
}
/* Usuarios: se diferencia de sucursales con el cyan de marca */
.pais-head .cant.usu {
  color: var(--ph-banos-texto);
  background: rgba(0,174,239,.10);
  border-color: rgba(0,174,239,.28);
}
@media (max-width: 620px) {
  .pais-head .cant.usu { display: none; }   /* en mobile prima la sucursal */
}
.pais-body {
  padding: 12px;
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(205px, 1fr));
  gap: 10px;
}

/* Tarjeta de franquicia: todas las sucursales con la misma jerarquía */
.card-franq2 {
  background: var(--ph-superficie);
  border: 1px solid var(--ph-borde);
  border-radius: var(--ph-r-md);
  padding: 10px 12px;
  cursor: pointer;
  transition: transform .16s cubic-bezier(.22,.8,.3,1), box-shadow .16s, border-color .16s;
}
.card-franq2:hover, .card-franq2:focus-visible {
  transform: translateY(-3px);
  box-shadow: var(--ph-elev-2);
  border-color: #cfdcf0;
  outline: none;
}
.card-franq2 .head { display: flex; align-items: center; gap: 8px; margin-bottom: 7px; }
.card-franq2 .cod {
  background: linear-gradient(135deg, var(--ph-azul), var(--ph-azul-claro));
  color: #fff; font-weight: 700; font-size: .74rem;
  padding: 3px 11px; border-radius: 999px;
  letter-spacing: .3px;
}
.card-franq2 .cant { margin-left: auto; font-size: .71rem; color: var(--ph-texto-3); }
.card-franq2 ul { list-style: none; margin: 0; padding: 0; }
.card-franq2 li {
  font-size: .8rem; font-weight: 600; color: var(--ph-texto);
  padding: 4px 0; border-top: 1px solid #f1f5fa;
  line-height: 1.3;
}
.card-franq2 li:first-child { border-top: 0; padding-top: 0; }
mark { background: #fff0b8; color: inherit; border-radius: 4px; padding: 0 2px; }

/* =====================================================================
   PANTALLA DE ROLES — app de alto completo, sin scroll de página.
   Cada lista scrollea por dentro; el layout nunca crece hacia abajo.
   ===================================================================== */
body.ph.app-full {
  height: 100vh; overflow: hidden;
  display: flex; flex-direction: column;
}
.app-full .topbar { flex-shrink: 0; gap: 12px; }
/* Título de pantalla: solo lo usa la selección de franquicia, que no tiene
   ruta (es la raíz). En el resto, api.js lo pasa a la ruta y lo saca de acá. */
.tit-pantalla { font-weight: 800; font-size: .95rem; letter-spacing: .3px; }

.area {
  flex: 1; min-height: 0;
  display: grid; grid-template-columns: 310px 1fr;
  gap: 14px; padding: 14px; overflow: hidden;
}
.area .panel { min-height: 0; display: flex; flex-direction: column; overflow: hidden; padding: 14px; }
@media (max-width: 1100px) { .area { grid-template-columns: 260px 1fr; } }
@media (max-width: 860px)  { .area { grid-template-columns: 1fr; grid-template-rows: 40% 60%; } }

/* -------- columna de usuarios -------- */
.buscador.chico { margin: 0 0 9px; max-width: none; }
.buscador.chico input { padding: .55em 2.1em .55em 2.4em; font-size: .85rem; }
.buscador.chico .lupa { font-size: .82rem; left: .85em; }

.barra-lista { display: flex; align-items: center; gap: 8px; margin-bottom: 9px; }

/* -------- Filtros de la lista de usuarios --------
   Chips de estado + tres combos que se arman con los datos reales de la
   franquicia. Densos a propósito: la columna mide 310 px y no debe robarle
   alto a la lista. */
.chips-estado { display: flex; gap: 4px; margin-left: auto; }
.chip-f {
  border: 1px solid var(--ph-borde-2); background: #fff; cursor: pointer;
  font-family: var(--ph-font); font-size: .69rem; font-weight: 600; color: var(--ph-texto-2);
  padding: 3px 9px; border-radius: 999px; white-space: nowrap;
  transition: background .14s, border-color .14s, color .14s;
}
.chip-f:hover { border-color: var(--ph-azul); color: var(--ph-azul); background: #eef4fd; }
.chip-f:focus-visible { outline: none; box-shadow: var(--ph-anillo); }
.chip-f.act {
  background: var(--ph-azul); border-color: var(--ph-azul); color: #fff;
}

.barra-lista.filtros-usr { gap: 5px; margin-bottom: 6px; }
.filtros-usr .mini-select { margin-left: 0; flex: 1 1 0; min-width: 0; max-width: none; }
/* Un combo con filtro puesto se distingue del que está en "todos". */
.mini-select.activo {
  border-color: var(--ph-azul); color: var(--ph-azul); font-weight: 600;
  background: #eef4fd;
}

.limpiar-filtros {
  align-self: flex-start;
  border: 0; background: transparent; cursor: pointer;
  font-family: var(--ph-font); font-size: .71rem; font-weight: 600;
  color: var(--ph-texto-3);
  padding: 2px 6px; margin: -3px 0 7px; border-radius: 999px;
  transition: color .14s, background .14s;
}
.limpiar-filtros:hover { color: var(--ph-azul); background: #eef4fd; }
.contador {
  font-size: .7rem; font-weight: 700; color: var(--ph-azul);
  background: rgba(0,27,114,.08); border-radius: 999px; padding: 2px 8px;
}
.chk-inline { display: flex; align-items: center; gap: 6px; font-size: .76rem; color: var(--ph-texto-2); white-space: nowrap; }
.mini-select {
  margin-left: auto; font-family: var(--ph-font); font-size: .76rem;
  color: var(--ph-texto-2); background: #fbfcfe;
  border: 1.5px solid var(--ph-borde-2); border-radius: 8px; padding: .3em .5em; outline: none;
  max-width: 130px;
}
.mini-select:focus { border-color: var(--ph-azul); box-shadow: var(--ph-anillo); }
.mini-select:disabled { opacity: .55; }

.lista-usuarios {
  list-style: none; margin: 0 -8px -6px; padding: 2px 4px 8px;
  flex: 1; min-height: 0; overflow: auto;
}
.item-usuario {
  display: flex; align-items: center; gap: 10px;
  padding: 7px 9px; border-radius: 10px; cursor: pointer;
  transition: background .12s;
}
.item-usuario:hover { background: #f4f8ff; }
.item-usuario:focus-visible { outline: none; box-shadow: var(--ph-anillo); }
.item-usuario.act { background: #e8f0fd; box-shadow: inset 3px 0 0 var(--ph-azul); }

.avatar {
  flex-shrink: 0; width: 30px; height: 30px; border-radius: 50%;
  display: grid; place-items: center;
  background: linear-gradient(135deg, var(--ph-azul), var(--ph-azul-claro));
  color: #fff; font-size: .68rem; font-weight: 700;
}
.avatar.grande { width: 42px; height: 42px; font-size: .9rem; }

.item-datos { display: flex; flex-direction: column; min-width: 0; gap: 1px; }
.item-nom  { font-size: .83rem; font-weight: 600; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.item-meta { font-size: .71rem; color: var(--ph-texto-3); }
.item-tags { display: flex; gap: 4px; margin-top: 2px; overflow: hidden; }
.tag {
  font-size: .65rem; font-weight: 600; padding: 1px 7px; border-radius: 999px;
  background: rgba(0,27,114,.07); color: var(--ph-azul);
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis; max-width: 140px;
}
.tag.jer   { background: rgba(0,174,239,.10); color: var(--ph-banos-texto); }
.tag.vacio { background: #f1f4f9; color: var(--ph-texto-3); font-weight: 500; }

/* -------- detalle -------- */
.det-flex { display: flex; flex-direction: column; min-height: 0; flex: 1; }
.det-empty.grande { margin: auto; padding: 30px; }
.det-empty .ico-vacio { font-size: 2.4rem; margin-bottom: 8px; opacity: .5; }
.det-empty p { margin: 2px 0; }

.det-head {
  display: flex; align-items: center; gap: 12px;
  padding-bottom: 12px; margin-bottom: 12px;
  border-bottom: 1px solid var(--ph-borde);
  flex-wrap: wrap;
}
.det-ident { min-width: 0; }
.det-ident h2 { margin: 0; font-size: 1.05rem; }
.det-ident .ph-muted { font-size: .75rem; }

.resumen-chips { display: flex; flex-wrap: wrap; gap: 6px; }
.rchip {
  font-size: .72rem; font-weight: 600; padding: 3px 10px; border-radius: 999px;
  background: rgba(0,27,114,.07); color: var(--ph-azul); white-space: nowrap;
}
.rchip.ok    { background: rgba(244,117,33,.13); color: var(--ph-pisos-texto); }
.rchip.vacio { background: #f1f4f9; color: var(--ph-texto-3); font-weight: 500; }

.det-acciones { display: flex; align-items: center; gap: 8px; margin-left: auto; }
.estado { font-size: .73rem; font-weight: 600; color: var(--ph-texto-3); white-space: nowrap; }
.estado.editando { color: var(--ph-azul); }
.estado.cambios  { color: var(--ph-pisos-texto); }

/* -------- las tres listas, lado a lado -------- */
.cols-detalle {
  flex: 1; min-height: 0;
  display: grid; grid-template-columns: repeat(3, 1fr); gap: 12px;
}
/* Bajado de 1280: al sacarse la columna de usuarios las tres listas tienen
   ~310 px más y entran cómodas mucho antes. Por debajo de 860 no hace falta
   un tercer escalón: ahí manda el modo solapas (ver media query de mobile). */
@media (max-width: 1000px) { .cols-detalle { grid-template-columns: repeat(2, 1fr); } }

.col-lista {
  min-height: 0; display: flex; flex-direction: column; overflow: hidden;
  border: 1px solid var(--ph-borde); border-radius: var(--ph-r-md); background: #fbfcfe;
}
.col-head {
  display: flex; align-items: center; gap: 7px;
  padding: 9px 11px; border-bottom: 1px solid var(--ph-borde);
  background: linear-gradient(90deg, rgba(0,27,114,.05), rgba(0,174,239,.03));
}
.col-tit { font-size: .78rem; font-weight: 800; color: var(--ph-azul); white-space: nowrap; }
.col-head .mini-select { max-width: 118px; }

.col-tools { display: flex; align-items: center; gap: 6px; padding: 7px 9px 5px; }
.mini-accion {
  border: 1px solid var(--ph-borde-2); background: #fff; cursor: pointer;
  font-family: var(--ph-font); font-size: .69rem; font-weight: 600; color: var(--ph-texto-2);
  padding: 3px 9px; border-radius: 999px; transition: all .14s;
}
.mini-accion:hover:not(:disabled) { border-color: var(--ph-azul); color: var(--ph-azul); background: #eef4fd; }
.mini-accion:disabled { opacity: .4; cursor: default; }
.mini-busca {
  margin-left: auto; width: 82px; font-family: var(--ph-font); font-size: .72rem;
  border: 1px solid var(--ph-borde-2); border-radius: 999px; padding: 3px 9px;
  background: #fff; outline: none; transition: width .18s, border-color .14s;
}
.mini-busca:focus { width: 120px; border-color: var(--ph-azul); }

.lista-opciones { list-style: none; margin: 0; padding: 3px 5px 6px; flex: 1; min-height: 0; overflow: auto; }
.opcion {
  display: flex; align-items: center; gap: 6px;
  padding: 4px 7px; border-radius: 8px; transition: background .1s;
}
.opcion:hover { background: #eef4fd; }
.opcion.on { background: #e8f0fd; }
.opcion.pri { box-shadow: inset 0 0 0 1.5px var(--ph-pisos); }
.opcion.bloq { opacity: .5; }

.op-check { display: flex; align-items: center; gap: 8px; flex: 1; cursor: pointer; min-width: 0; }
.op-check input[type=checkbox] { width: 14px; height: 14px; accent-color: var(--ph-azul); cursor: pointer; flex-shrink: 0; }
.op-check input:disabled { cursor: default; }
.op-nom { font-size: .78rem; font-weight: 600; line-height: 1.25; }
.opcion.on .op-nom { color: var(--ph-azul); }

.op-pri { cursor: pointer; padding: 1px 3px; border-radius: 5px; position: relative; }
.op-pri input { position: absolute; opacity: 0; width: 0; height: 0; }
.op-pri .estrella { color: #ccd5e3; font-size: .95rem; transition: color .14s, transform .12s; }
.op-pri:hover .estrella { color: var(--ph-pisos); transform: scale(1.18); }
.op-pri input:checked + .estrella { color: var(--ph-pisos); }
.op-pri input:disabled:not(:checked) + .estrella { opacity: .3; }
.op-pri input:focus-visible + .estrella { outline: 2px solid var(--ph-azul); outline-offset: 2px; border-radius: 3px; }

.det-pie { padding-top: 9px; margin-top: 10px; border-top: 1px solid var(--ph-borde); }
.ayuda { font-size: .72rem; color: var(--ph-texto-3); }
kbd {
  font-family: var(--ph-font); font-size: .68rem; font-weight: 700;
  background: #eef2f8; border: 1px solid var(--ph-borde-2); border-bottom-width: 2px;
  border-radius: 5px; padding: 1px 5px; color: var(--ph-texto-2);
}

/* error flotante: no empuja el layout */
.alert.flotante {
  position: fixed; left: 50%; bottom: 20px; transform: translateX(-50%);
  z-index: 90; margin: 0; max-width: 560px; box-shadow: var(--ph-elev-2);
}

#det.editando .lista-opciones { background: #fff; }
#det.editando .col-lista { border-color: var(--ph-borde-2); }

.volver, .tabs-detalle { display: none; }

/* =====================================================================
   MOBILE  (≤ 860 px)
   ---------------------------------------------------------------------
   No es el diseño de escritorio encogido: cambia la navegación.
   · La topbar deja a la vista lo único que se necesita para moverse:
     atrás y dónde estoy. Usuario y acciones, detrás del avatar.
   · Roles pasa a maestro→detalle: primero la lista, después la ficha
     a pantalla completa, con "atrás".
   · Las tres listas del detalle se ven de a una, por solapas.
   · Los blancos de toque suben a ~44 px (guía de accesibilidad táctil).
   ===================================================================== */
@media (max-width: 860px) {

  /* -------- topbar -------- */
  .topbar { gap: 8px; padding: 0 8px 0 0; min-height: 52px; }
  .marca-bloque { padding: 0 14px; margin-right: 6px; }
  .marca-bloque img { height: 19px; }
  .marca-sub { display: none; }
  .marca-bloque::after { right: -9px; width: 9px; }
  .tit-pantalla { font-size: .82rem; }

  /* El botón atrás queda redondo: el ícono solo, pero con 40 px de toque. */
  .nav-atras { width: 40px; height: 40px; padding: 0; justify-content: center; }
  .nav-atras span { display: none; }
  .nav-atras:hover, .nav-atras:active { transform: none; }
  /* De la ruta sobrevive sólo dónde estás; para el resto está el atrás. */
  .nav-ruta { margin-left: 0; }
  .nav-ruta a, .nav-sep { display: none; }
  .nav-actual { font-size: .86rem; padding: 0; }
  .nav-user { padding: 3px 8px 3px 3px; }
  .drawer { width: min(330px, 90vw); }
  .drawer-item { padding: 11px 10px; }   /* blancos de toque de 44 px */

  /* -------- páginas con scroll normal -------- */
  .page { margin-top: 12px; padding: 0 14px; }
  .barra-filtros { gap: 10px; }
  .barra-filtros .buscador { flex: 1 1 100%; max-width: none; }
  .accesos-fila { margin-left: 0; width: 100%; }
  .acceso-chip { flex: 1 1 auto; justify-content: center; padding: 9px 12px; }
  .pais-metas { flex-wrap: wrap; justify-content: flex-end; }
  .pais-head { padding: 12px 14px; gap: 9px; }
  .pais-body { padding: 12px; gap: 12px; grid-template-columns: 1fr; }
  .grid-opciones { grid-template-columns: 1fr; gap: 14px; }

  /* -------- roles: maestro → detalle -------- */
  .area {
    grid-template-columns: 1fr; grid-template-rows: 1fr;
    padding: 10px; gap: 0;
  }
  .area .panel { padding: 12px; }
  /* Los selectores llevan `.area` a propósito: `.area .panel` ya define
     display:flex y con un solo nombre de clase esta regla perdía por
     especificidad, no por orden. */
  .area .col-detalle { display: none; }
  body.ver-detalle .area .col-usuarios { display: none; }
  body.ver-detalle .area .col-detalle  { display: flex; }

  .volver {
    display: grid; place-items: center; flex-shrink: 0;
    width: 38px; height: 38px; border-radius: 50%;
    border: 1px solid var(--ph-borde-2); background: #fff;
    color: var(--ph-azul); font-size: 1.15rem; line-height: 1; cursor: pointer;
  }
  .volver:active { background: #eef4fd; }

  /* Cabecera del detalle: identidad arriba, resumen debajo, acciones a lo
     ancho y al alcance del pulgar. */
  .det-head { flex-wrap: wrap; gap: 10px; padding-bottom: 10px; margin-bottom: 10px; }
  .det-ident { flex: 1 1 auto; }
  .det-ident h2 { font-size: .98rem; }
  .avatar.grande { width: 38px; height: 38px; font-size: .82rem; }
  .resumen-chips { order: 2; width: 100%; }
  .det-acciones { order: 3; width: 100%; margin-left: 0; flex-wrap: wrap; }
  .det-acciones .ph-btn { flex: 1 1 auto; min-height: 40px; }
  .det-acciones .estado { width: 100%; }
  .det-pie { display: none; }        /* atajos de teclado: no aplican acá */

  /* -------- solapas de las tres listas -------- */
  .tabs-detalle {
    display: flex; gap: 4px; margin-bottom: 10px;
    background: #eef2f8; padding: 4px; border-radius: 999px;
  }
  .tabs-detalle button {
    flex: 1; border: 0; background: transparent; cursor: pointer;
    font-family: var(--ph-font); font-size: .76rem; font-weight: 700;
    color: var(--ph-texto-2); padding: 9px 6px; border-radius: 999px;
    transition: background .16s, color .16s;
  }
  .tabs-detalle button.act { background: #fff; color: var(--ph-azul); box-shadow: var(--ph-elev-1); }

  .cols-detalle { display: block; }
  .col-lista { display: none; height: 100%; }
  .col-lista.act { display: flex; }

  /* -------- blancos de toque -------- */
  .item-usuario { padding: 10px 9px; gap: 12px; }
  .opcion { padding: 9px 8px; gap: 10px; }
  .op-check input[type=checkbox] { width: 19px; height: 19px; }
  .op-pri .estrella { font-size: 1.25rem; }
  .op-pri { padding: 4px 6px; }
  .mini-accion { padding: 7px 12px; font-size: .74rem; }
  .mini-busca { width: 90px; padding: 6px 11px; }
  .mini-busca:focus { width: 110px; }
  .chip-f { padding: 7px 12px; font-size: .73rem; }
  .mini-select { padding: .5em .5em; font-size: .8rem; }
  /* iOS hace zoom automático en los campos con letra < 16px */
  .buscador input, .mini-busca, .mini-select, .login-body input { font-size: 16px; }
  .buscador.chico input { font-size: 16px; padding: .6em 2.1em .6em 2.4em; }

  .alert.flotante { left: 10px; right: 10px; bottom: 10px; transform: none; max-width: none; }
  .toast-cont { left: 10px; right: 10px; bottom: 10px; align-items: stretch; }
  .toast { max-width: none; }
  .modal { width: 100%; }
}

/* Teléfonos angostos: el logo se lleva media barra. */
@media (max-width: 430px) {
  .tit-pantalla { display: none; }
  .marca-bloque { padding: 0 11px; }
  .chips-estado { margin-left: 0; width: 100%; }
  .barra-lista { flex-wrap: wrap; }
  .acceso-chip { font-size: .76rem; }
}

.det-tit { display: flex; align-items: center; gap: 8px; }
.badge-off {
  font-size: .66rem; font-weight: 700; letter-spacing: .3px; text-transform: uppercase;
  padding: 2px 8px; border-radius: 999px;
  background: rgba(197,48,48,.10); color: #a12b2b;
}

/* =====================================================================
   DIÁLOGO DE CONFIRMACIÓN Y TOASTS (usados por ui.js)
   ===================================================================== */
@keyframes ph-fade { from { opacity: 0; } to { opacity: 1; } }
@keyframes ph-sube { from { opacity: 0; transform: translateY(14px) scale(.97); }
                     to   { opacity: 1; transform: none; } }

.modal-fondo {
  position: fixed; inset: 0; z-index: 120;
  background: rgba(10, 26, 58, .45);
  -webkit-backdrop-filter: blur(3px); backdrop-filter: blur(3px);
  display: grid; place-items: center; padding: 20px;
  animation: ph-fade .15s ease;
}
.modal {
  background: #fff; border-radius: 16px; padding: 22px 24px 18px;
  width: min(440px, 100%); box-shadow: 0 18px 50px rgba(10, 26, 58, .35);
  animation: ph-sube .18s ease;
}
.modal h3 { margin: 0 0 8px; font-size: 1rem; color: var(--ph-azul); }
.modal p  { margin: 0 0 18px; font-size: .86rem; color: var(--ph-texto-2); line-height: 1.5; }
.modal .acciones { display: flex; justify-content: flex-end; gap: 8px; }

.toast-cont {
  position: fixed; right: 18px; bottom: 18px; z-index: 130;
  display: flex; flex-direction: column; align-items: flex-end; gap: 8px;
}
.toast {
  background: var(--ph-azul); color: #fff;
  padding: 10px 16px; border-radius: 12px;
  font-size: .82rem; font-weight: 600; max-width: 360px;
  box-shadow: var(--ph-elev-2);
  animation: ph-sube .22s ease;
  transition: opacity .25s, transform .25s;
}
.toast.err { background: #a12b2b; }
.toast.saliendo { opacity: 0; transform: translateY(10px); }

/* =====================================================================
   PULIDO: scrollbars finas, avatares con matiz propio, esqueletos,
   entrada animada del detalle y aviso de cambios latiendo.
   ===================================================================== */
.lista-usuarios::-webkit-scrollbar,
.lista-opciones::-webkit-scrollbar { width: 8px; }
.lista-usuarios::-webkit-scrollbar-track,
.lista-opciones::-webkit-scrollbar-track { background: transparent; }
.lista-usuarios::-webkit-scrollbar-thumb,
.lista-opciones::-webkit-scrollbar-thumb {
  background: #ccd5e3; border-radius: 999px; border: 2px solid transparent; background-clip: content-box;
}
.lista-usuarios::-webkit-scrollbar-thumb:hover,
.lista-opciones::-webkit-scrollbar-thumb:hover { background: #a9b8d0; background-clip: content-box; }
.lista-usuarios, .lista-opciones { scrollbar-width: thin; scrollbar-color: #ccd5e3 transparent; }

/* cada persona con su matiz, siempre dentro de la familia azul de marca */
.avatar.av0 { background: linear-gradient(135deg, #001B72, #00AEEF); }
.avatar.av1 { background: linear-gradient(135deg, #0d2f6b, #2b6cd4); }
.avatar.av2 { background: linear-gradient(135deg, #0f6f96, #2bc5d8); }
.avatar.av3 { background: linear-gradient(135deg, #23499b, #7a9be0); }
.avatar.av4 { background: linear-gradient(135deg, #0a5c8f, #47b5e8); }

@keyframes ph-shimmer { from { background-position: -200px 0; } to { background-position: 200px 0; } }
.skel {
  height: 26px; margin: 6px 7px; border-radius: 8px;
  background: linear-gradient(90deg, #eef2f8 25%, #f7f9fc 50%, #eef2f8 75%);
  background-size: 400px 100%;
  animation: ph-shimmer 1.1s linear infinite;
  list-style: none;
}

.det-flex.anim { animation: ph-sube .2s ease; }

@keyframes ph-late { 0%, 100% { opacity: 1; } 50% { opacity: .45; } }
.estado.cambios { animation: ph-late 1.6s ease-in-out infinite; }

#det.editando .det-head {
  border-bottom-color: var(--ph-azul-claro);
  box-shadow: 0 1px 0 rgba(0, 174, 239, .25);
}
/* =====================================================================
   FICHA DE OPERADOR (operadores.html)
   Es una ficha de ERP, no un formulario de alta público: la gente la edita
   todos los días, así que los controles son densos (los de .field genéricos
   miden 60 px de alto: sirven para el login, acá obligaban a scrollear).
   Todo lo denso va scopeado a #f-ope para no tocar las otras pantallas.

   Tuvo dos columnas cuando eran 22 campos. Al mudarse sector, jerarquía,
   supervisor, sucursal y tipos a Roles quedaron 6 campos y 2 opciones: en dos
   columnas la derecha quedaba vacía y la ficha parecía a medio hacer. Ahora es
   UNA columna de ancho legible, centrada en el panel.
   ===================================================================== */

/* La pantalla ya no tiene lista propia: una sola columna, y en mobile no hay
   nada de lo que "volver", así que la ficha se muestra siempre. */
.area.area-ficha { grid-template-columns: 1fr; }

.ficha-scroll {
  flex: 1;
  min-height: 0;
  overflow-y: auto;
  padding-right: 6px;
}
.ficha-scroll::-webkit-scrollbar { width: 8px; }
.ficha-scroll::-webkit-scrollbar-track { background: transparent; }
.ficha-scroll::-webkit-scrollbar-thumb {
  background: #ccd5e3; border-radius: 999px;
  border: 2px solid transparent; background-clip: content-box;
}

/* Una columna, ancho de lectura cómodo y centrada: en un panel de 1300 px
   estirar 6 campos de punta a punta deja etiquetas separadas de su dato. */
.ficha-uno {
  max-width: 940px;
  margin: 0 auto;
  padding-top: 2px;
}
/* Cabecera, alerta y pie alineados con el formulario: si el nombre y los
   botones se van al borde del panel y el form queda centrado, se leen como
   dos cosas distintas. Solo en la ficha de datos (.angosta): la de roles usa
   todo el ancho para sus tres listas. */
.col-detalle.angosta .det-head,
.col-detalle.angosta #det-alert,
.col-detalle.angosta .det-pie {
  width: 100%;
  max-width: 940px;
  margin-left: auto;
  margin-right: auto;
}

.bloque-form {
  border: 1px solid var(--ph-borde);
  border-radius: var(--ph-r-md);
  padding: 10px 13px 2px;
  margin: 0 0 12px;
  background: #fbfcfe;
}
.bloque-form legend {
  font-size: .7rem;
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: .05em;
  color: var(--ph-azul);
  padding: 0 5px;
}
.ayuda-bloque {
  font-size: .72rem;
  color: var(--ph-texto-3);
  margin: 0 0 9px;
}

/* minmax chico a propósito: con 130px entran 3 campos por fila en cada
   columna de la ficha, y "Identificación" pasa de 3 filas a 2. */
.form-grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(130px, 1fr));
  gap: 0 10px;
}
.form-grid.codigos { grid-template-columns: repeat(3, minmax(80px, 1fr)); }

/* Rejilla de 4 unidades para la ficha de una columna:
   Usuario · Nombre(2) · Iniciales  /  Correo(2) · Teléfono · Idioma.
   Dos filas parejas, y cada campo con el ancho que pide su contenido en vez
   del reparto automático (que le daba lo mismo a "Iniciales" que a "Correo"). */
.ficha-uno .form-grid { grid-template-columns: repeat(4, 1fr); gap: 0 12px; }
.ficha-uno .form-grid .sp2 { grid-column: span 2; }

@media (max-width: 880px) {
  .ficha-uno .form-grid { grid-template-columns: repeat(2, 1fr); }
}
@media (max-width: 560px) {
  .ficha-uno .form-grid { grid-template-columns: 1fr; }
  .ficha-uno .form-grid .sp2 { grid-column: auto; }
}
/* En mobile la ficha es toda la pantalla: no hay lista que la tape. */
@media (max-width: 860px) {
  .area.area-ficha { grid-template-rows: 1fr; }
  .area.area-ficha .col-detalle { display: flex; }
}

/* -------- controles densos, solo dentro de la ficha -------- */
#f-ope .field { margin-bottom: 9px; }
#f-ope .field label {
  font-size: .71rem;
  font-weight: 600;
  margin-bottom: 3px;
  color: var(--ph-texto-3);
}
#f-ope .field input,
#f-ope .field select {
  font-size: .85rem;
  padding: .34em .55em;
  border-width: 1px;
  border-radius: 8px;
}
#f-ope .field.angosto { max-width: 100%; }

#f-ope .field .hint {
  display: block;
  font-size: .67rem;
  color: var(--ph-texto-3);
  margin-top: 2px;
  line-height: 1.25;
}
#f-ope .field.error input,
#f-ope .field.error select { border-color: #d9534f; background: #fdf6f6; }
#f-ope .field.error .hint  { color: #9a2b28; }

/* Checkbox como píldora clickeable: blanco de click grande, estado evidente. */
.chks-grid {
  display: flex;
  flex-wrap: wrap;
  gap: 6px;
  margin-bottom: 10px;
}
.chk-caja {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  padding: 5px 11px;
  border: 1px solid var(--ph-borde-2);
  border-radius: 999px;
  background: var(--ph-superficie);
  font-size: .78rem;
  font-weight: 600;
  color: var(--ph-texto-2);
  cursor: pointer;
  user-select: none;
  transition: border-color .16s, color .16s, background .16s;
}
.chk-caja:hover { border-color: #c3d1e6; }
.chk-caja input { accent-color: var(--ph-azul); width: 14px; height: 14px; cursor: pointer; }
.chk-caja:has(input:checked) {
  border-color: var(--ph-azul);
  color: var(--ph-azul);
  background: #f2f6fd;
}
.chk-caja:has(input:focus-visible) { box-shadow: var(--ph-anillo); }
.chk-caja.peligro input { accent-color: #d9534f; }
.chk-caja.peligro:has(input:checked) {
  border-color: #d9534f;
  color: #9a2b28;
  background: #fdf1f0;
}
/* Sin :has() (navegadores viejos) igual se ve el check nativo: no se pierde
   la información, solo el resaltado de la píldora. */

/* Campos que el ABM no edita pero conviene ver (ID SalesForce, ruta, fechas). */
.datos-solo-lectura {
  display: flex;
  flex-wrap: wrap;
  gap: 4px 14px;
  font-size: .72rem;
  color: var(--ph-texto-3);
  padding: 2px 0 10px;
}
.datos-solo-lectura b { color: var(--ph-texto-2); font-weight: 600; }

@media (max-width: 700px) {
  .bloque-form { padding: 10px 11px 2px; }
  .form-grid { grid-template-columns: 1fr; }
  .form-grid.codigos { grid-template-columns: repeat(3, 1fr); }
}

/* Selector "Agrupar por" de la pantalla de selección de franquicia. */
.agrupar-por {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  font-size: .78rem;
  font-weight: 600;
  color: var(--ph-texto-3);
  white-space: nowrap;
}
.agrupar-por .mini-select { margin-left: 0; max-width: none; }

/* Encabezado de sección cuando NO se agrupa por país (grupo económico o
   regional): el canto queda en azul de marca salvo que el grupo sea de un
   solo país, y el lugar de la bandera lo ocupan las banderas de los países
   que abarca. */
.pais-sec.es-grupo { --f1: var(--ph-azul); --f2: #5b7fc0; --f3: var(--ph-azul-claro); }
/* Franquicias sin país cargado: no hay bandera que mostrar. */
.pais-head .flag.sin-pais {
  background: linear-gradient(135deg, var(--ph-azul), var(--ph-azul-claro));
}

/* Pila de banderas: superpuestas como un mazo de cartas para que entren
   varias sin correr el nombre del grupo. Al pasar el mouse se separan para
   poder distinguirlas. */
.pais-head .flag-pila {
  display: inline-flex; align-items: center; flex-shrink: 0;
  padding-right: 2px;
}
.pais-head .flag-pila .flag {
  margin-left: -11px;
  /* Aro blanco: sin él, dos banderas vecinas con franja blanca (Argentina y
     Perú, por ejemplo) se leerían como una sola. */
  box-shadow: 0 0 0 1.5px #fff, 0 0 0 2.5px rgba(10, 26, 58, .22),
              0 1px 3px rgba(10, 26, 58, .20);
  transition: margin-left .18s cubic-bezier(.22,.8,.3,1),
              transform .18s cubic-bezier(.22,.8,.3,1);
}
.pais-head .flag-pila .flag:first-child { margin-left: 0; }
.pais-head:hover .flag-pila .flag { margin-left: -3px; }
.pais-head:hover .flag-pila .flag:first-child { margin-left: 0; }
/* Resto de países que no entraron en la pila */
.pais-head .flag-mas {
  margin-left: 5px;
  font-size: .66rem; font-weight: 700; line-height: 1;
  color: var(--ph-azul);
  background: rgba(255,255,255,.75);
  border: 1px solid var(--ph-borde);
  padding: 3px 5px; border-radius: 999px;
}
@media (max-width: 620px) {
  /* En mobile no se esconden banderas (el "+N" mentiría): se comprimen. */
  .pais-head .flag-pila .flag { width: 22px; height: 15px; margin-left: -14px; }
  .pais-head:hover .flag-pila .flag { margin-left: -8px; }
}

/* =====================================================================
   REPORTE DASHBOARD OPERATIVO (abm.html)
   ---------------------------------------------------------------------
   Pantalla de un solo propósito: tres decisiones (período, unidad de
   negocio y etiquetas) y un botón. Va en UNA tarjeta centrada y angosta
   —no estirada a los 1280 de .page, que dejaba media pantalla vacía— con
   las decisiones numeradas para que se lean como pasos.
   ===================================================================== */
/* Sólo acota el ancho: el centrado y los márgenes verticales los pone .page
   (si acá se redeclara `margin`, se pierden los 18px/60px de arriba y abajo). */
.rep-wrap { max-width: 760px; }

.rep-card {
  background: var(--ph-superficie);
  border: 1px solid var(--ph-borde);
  border-radius: var(--ph-r-lg);
  box-shadow: var(--ph-elev-1);
  overflow: hidden;
}

/* -------- cada decisión es un paso -------- */
.rep-paso { padding: 18px 22px; }
.rep-paso + .rep-paso { border-top: 1px solid var(--ph-borde); }

.rep-paso-head { display: flex; align-items: baseline; gap: 10px; margin-bottom: 14px; }
.rep-num {
  flex: none;
  width: 22px; height: 22px; border-radius: 50%;
  background: var(--ph-azul); color: #fff;
  font-size: .72rem; font-weight: 700;
  display: grid; place-items: center;
  transform: translateY(3px);
}
.rep-paso-head h2 { font-size: .95rem; margin: 0; color: var(--ph-texto); }
.rep-paso-head .ayuda { margin: 2px 0 0; }
/* Acción secundaria del paso (ej. "Limpiar"), pegada a la derecha. */
.rep-paso-head .acc { margin-left: auto; }

/* -------- período + unidad de negocio -------- */
.rep-campos {
  display: grid;
  grid-template-columns: minmax(150px, 190px) minmax(0, 1fr);
  gap: 0 16px;
}
.rep-campos .field { margin-bottom: 0; }

/* Atajos de período: evitan pelear con el date picker para el caso habitual. */
.rep-atajos { display: flex; gap: 6px; flex-wrap: wrap; margin-top: 9px; }
.rep-atajo {
  font-family: var(--ph-font); font-size: .72rem; font-weight: 600;
  color: var(--ph-texto-2); background: #fff;
  border: 1px solid var(--ph-borde-2); border-radius: 999px;
  padding: 3px 11px; cursor: pointer;
  transition: border-color .14s, color .14s, background .14s;
}
.rep-atajo:hover { border-color: var(--ph-azul); color: var(--ph-azul); }
.rep-atajo.act   { border-color: var(--ph-azul); color: var(--ph-azul); background: #f2f6fd; }

/* -------- etiquetas -------- */
.rep-cuenta { font-size: .74rem; color: var(--ph-texto-3); font-weight: 600; }
/* Puede haber muchas: se acota y hace scroll para que el botón no se vaya
   de la pantalla. */
.rep-etiquetas { max-height: 190px; overflow-y: auto; margin-bottom: 0; padding: 1px; }

/* -------- pie: resumen de lo pedido + botón -------- */
.rep-pie {
  display: flex; align-items: center; gap: 16px; flex-wrap: wrap;
  padding: 15px 22px;
  border-top: 1px solid var(--ph-borde);
  background: #f7f9fd;
}
.rep-pie .ph-btn { flex: none; }
.rep-resumen { font-size: .78rem; color: var(--ph-texto-2); line-height: 1.45; min-width: 0; }
.rep-resumen b { color: var(--ph-texto); }

/* -------- mientras genera --------
   La llamada al webservice es sincrónica y tarda ~1 min (recorre el ABM del
   año y publica los XML). Sin señal de avance la pantalla parece colgada, así
   que se muestra una barra indeterminada —no fingimos un porcentaje que no
   tenemos— y el tiempo transcurrido. */
.rep-progreso { padding: 15px 22px; border-top: 1px solid var(--ph-borde); background: #f7f9fd; }
.rep-progreso-txt {
  display: flex; align-items: baseline; gap: 8px; flex-wrap: wrap;
  font-size: .8rem; color: var(--ph-texto-2); margin-bottom: 9px;
}
.rep-progreso-txt b { color: var(--ph-azul); }
.rep-crono { margin-left: auto; font-variant-numeric: tabular-nums; color: var(--ph-texto-3); font-size: .74rem; }
.rep-barra { height: 5px; border-radius: 999px; background: #dfe7f5; overflow: hidden; }
.rep-barra span {
  display: block; height: 100%; width: 35%; border-radius: 999px;
  background: linear-gradient(90deg, var(--ph-azul), var(--ph-azul-claro));
  animation: rep-desliza 1.5s ease-in-out infinite;
}
@keyframes rep-desliza {
  0%   { transform: translateX(-100%); }
  100% { transform: translateX(320%); }
}
@media (prefers-reduced-motion: reduce) {
  .rep-barra span { animation: none; width: 100%; opacity: .55; }
}

/* -------- resultado --------
   El enlace queda a la vista (no sólo window.open) porque el bloqueador de
   ventanas emergentes corta la apertura automática después de una espera
   larga: si eso pasa, el botón es la única salida. */
.rep-listo {
  margin-top: 18px;
  border: 1px solid #c3e8d2;
  border-radius: var(--ph-r-lg);
  background: linear-gradient(180deg, #f0faf4 0%, #e9f7ef 100%);
  box-shadow: var(--ph-elev-1);
  padding: 20px 22px;
  animation: ph-in .3s ease both;
}
.rep-listo-head { display: flex; align-items: center; gap: 12px; margin-bottom: 14px; }
.rep-tilde {
  flex: none; width: 34px; height: 34px; border-radius: 50%;
  background: #2fa36b; color: #fff;
  display: grid; place-items: center; font-size: 1.05rem; font-weight: 700;
}
.rep-listo h2 { font-size: 1.02rem; margin: 0; color: #17603a; }
.rep-listo-sub { font-size: .8rem; color: #2c6b4a; margin: 2px 0 0; }
.rep-listo-acc { display: flex; align-items: center; gap: 10px; flex-wrap: wrap; }
.rep-url {
  display: block; margin-top: 12px;
  font-size: .7rem; color: var(--ph-texto-3);
  word-break: break-all; line-height: 1.5;
}

@media (max-width: 620px) {
  .rep-campos { grid-template-columns: 1fr; gap: 0; }
  .rep-campos .field:first-child { margin-bottom: 14px; }
  .rep-paso, .rep-pie, .rep-progreso { padding-left: 16px; padding-right: 16px; }
  .rep-pie .ph-btn { width: 100%; text-align: center; }
}

/* Aviso de qué se administra en otra pantalla. Sin esto, los campos que
   faltan se leen como que la pantalla está incompleta. */
.nota-remite {
  font-size: .74rem;
  line-height: 1.5;
  color: var(--ph-texto-3);
  margin: 2px 2px 10px;
}
.nota-remite a { font-weight: 600; }

/* =====================================================================
   BROWSE — tabla de trabajo (padrón de usuarios y, más adelante, otros)
   ---------------------------------------------------------------------
   Reemplaza a la columna angosta de 310 px: en un ABM lo primero que se
   hace es BUSCAR a alguien, y para eso hace falta ver varios datos de
   cada fila a la vez. Scrollea por dentro, con el encabezado fijo.
   ===================================================================== */
.area-browse {
  flex: 1; min-height: 0;
  display: flex; flex-direction: column; gap: 12px;
  padding: 14px;
}
.barra-browse { display: flex; align-items: center; gap: 10px; flex-wrap: wrap; }
.barra-browse .buscador { margin: 0; flex: 0 1 320px; }
.barra-browse .chips-estado { margin-left: 0; }
.barra-browse .contador { margin-left: auto; }

.browse-wrap {
  flex: 1; min-height: 0; overflow: auto;
  background: var(--ph-superficie);
  border: 1px solid var(--ph-borde); border-radius: var(--ph-r-md);
}
table.browse { width: 100%; border-collapse: collapse; font-size: .84rem; }
table.browse thead th {
  position: sticky; top: 0; z-index: 1; text-align: left; white-space: nowrap;
  background: #fff; color: var(--ph-texto-3);
  font-size: .69rem; font-weight: 800; letter-spacing: .4px; text-transform: uppercase;
  padding: 11px 12px; border-bottom: 1px solid var(--ph-borde-2);
  /* La sombra sobrevive al sticky (el border se pierde al pegarse). */
  box-shadow: inset 0 -1.5px 0 var(--ph-borde-2);
}
table.browse thead th.ord { cursor: pointer; user-select: none; }
table.browse thead th.ord:hover { color: var(--ph-azul); }
table.browse thead th .flecha { opacity: 0; margin-left: 4px; }
table.browse thead th[aria-sort] { color: var(--ph-azul); }
table.browse thead th[aria-sort] .flecha { opacity: 1; }
table.browse tbody td { padding: 8px 12px; border-bottom: 1px solid var(--ph-borde); }
table.browse tbody tr { cursor: pointer; }
table.browse tbody tr:hover { background: #f4f8ff; }
table.browse tbody tr.act { background: #eaf1ff; box-shadow: inset 3px 0 0 var(--ph-azul); }
table.browse tbody tr:focus-visible { outline: none; background: #eaf1ff; box-shadow: inset 0 0 0 2px var(--ph-azul); }

.celda-persona { display: flex; align-items: center; gap: 10px; min-width: 0; }
.celda-persona .avatar { width: 30px; height: 30px; font-size: .66rem; flex-shrink: 0; }
.cp-nom { font-weight: 700; display: block; }
.cp-usr { font-size: .7rem; color: var(--ph-texto-3); }
.celda-vacia { color: var(--ph-texto-3); }
.celda-aviso { color: var(--ph-pisos-texto); font-weight: 700; }
.acciones-fila { display: flex; gap: 6px; justify-content: flex-end; }

/* Fila de un perfil (usuario "%algo"): no es una persona. */
.tag-perfil {
  font-size: .66rem; font-weight: 800; text-transform: uppercase; letter-spacing: .3px;
  background: #eef2f8; color: var(--ph-texto-2); padding: 2px 8px; border-radius: 999px;
}

@media (max-width: 1100px) {
  .browse .col-jer { display: none; }
}
@media (max-width: 860px) {
  .area-browse { padding: 10px; gap: 10px; }
  .barra-browse .buscador { flex: 1 1 100%; }
  .barra-browse .contador { margin-left: 0; }
  /* En un teléfono la tabla se queda con lo que se mira para decidir:
     quién es, qué puede hacer y si está activo. El resto está en la ficha. */
  .browse .col-mail { display: none; }
  table.browse tbody td { padding: 10px; }
}

/* =====================================================================
   ÍCONOS SVG (js/iconos.js)
   Trazos 24×24 teñidos con currentColor. El tamaño lo da el font-size
   del contenedor (heredado de cuando eran emojis), así ningún llamador
   tuvo que cambiar.
   ===================================================================== */
.phi {
  width: 1.05em; height: 1.05em;
  fill: none; stroke: currentColor; stroke-width: 2;
  stroke-linecap: round; stroke-linejoin: round;
  display: inline-block; vertical-align: -0.15em;
  flex-shrink: 0;
}
.buscador .lupa .phi { display: block; }
.det-empty .ico-vacio .phi { stroke-width: 1.5; }   /* a 2.4rem, el trazo 2 pesa de más */
.lock .phi { width: .95em; height: .95em; }

/* =====================================================================
   PANEL — superficie de trabajo (roles, operadores)
   Antes no tenía estilo propio: las columnas eran cajas transparentes
   apoyadas directo sobre el fondo y la pantalla se leía "sin terminar".
   ===================================================================== */
.panel {
  background: var(--ph-superficie);
  border: 1px solid var(--ph-borde);
  border-radius: var(--ph-r-lg);
  box-shadow: var(--ph-elev-1);
}

/* =====================================================================
   LOADER — estado "cargando" con señal de vida
   También era texto suelto sin estilo. Anillo girando + texto apagado.
   ===================================================================== */
.loader {
  display: flex; align-items: center; justify-content: center; gap: 10px;
  padding: 34px 16px;
  color: var(--ph-texto-3);
  font-size: .86rem; font-weight: 600;
}
.loader::before {
  content: "";
  width: 18px; height: 18px; border-radius: 50%;
  border: 2.5px solid var(--ph-borde-2);
  border-top-color: var(--ph-azul);
  animation: ph-gira .8s linear infinite;
}
@keyframes ph-gira { to { transform: rotate(360deg); } }
@media (prefers-reduced-motion: reduce) {
  .loader::before { animation: none; border-top-color: var(--ph-borde-2); }
}

/* Estado vacío: centrado y apagado, con el ícono grande arriba. */
.det-empty {
  text-align: center;
  color: var(--ph-texto-2);
  font-size: .88rem;
  padding: 26px 16px;
}
.det-empty .ico-vacio { color: var(--ph-texto-3); }
