/* =============================================================
   Team Abogados — Admin Console
   Dark theme on top of the brand design-system tokens.
   Black canvas, cream ink, gold accents.
   ============================================================= */

@import url('./tokens.css');

:root {
  /* Re-bind the semantic tokens for the inverted (dark) admin context.
     The raw palette (--ta-*) is untouched — only the meaning of
     --bg / --fg / --surface / --line is flipped. */

  --bg:             var(--ta-black);
  --bg-soft:        #131315;          /* one step up from --ta-black */
  --bg-paper:       #18181A;          /* card surfaces */
  --bg-pressed:     #222224;
  --surface:        #18181A;
  --surface-ink:    var(--ta-cream);  /* "block" sections invert again */
  --surface-ink-fg: var(--ta-black);

  --fg:             var(--ta-cream);
  --fg-muted:       #B9B9BA;          /* --ta-black-20 reads as muted on black */
  --fg-subtle:      #7C7C7D;
  --fg-inverse:     var(--ta-black);

  --accent:         var(--ta-gold-500);
  --accent-strong:  var(--ta-gold-400);   /* brighter on dark, vs --gold-700 on cream */
  --accent-soft:    rgba(208,184,132,0.12);
  --accent-ink:     var(--ta-gold-400);   /* gold-on-black type — was --gold-900 on cream */

  --line:           rgba(244,238,223,0.08);
  --line-strong:    rgba(244,238,223,0.16);
  --line-gold:      var(--ta-gold-700);

  --focus-ring:     0 0 0 2px var(--ta-black), 0 0 0 4px var(--ta-gold-500);

  /* Admin-only sizing — denser than marketing */
  --nav-w:          240px;             /* sidebar width */
  --topbar-h:       64px;
  --row-h:          52px;              /* table row */
  --row-h-compact:  40px;
}

/* ============ BASE ============ */

* { box-sizing: border-box; }
html, body { margin: 0; }
body {
  background: var(--bg);
  color: var(--fg);
  font-family: var(--font-sans);
  font-size: var(--fs-sm);            /* admin baseline 14px, denser than marketing */
  line-height: var(--lh-base);
}

/* Heading recalibration for admin context — smaller, tighter */
h1, .h1 { font-size: var(--fs-3xl); color: var(--fg); }
h2, .h2 { font-size: var(--fs-2xl); }
h3, .h3 { font-size: var(--fs-xl); }
h4, .h4 { font-size: var(--fs-lg); }

a { color: var(--fg); border-bottom-color: var(--accent); }
a:hover { color: var(--accent-strong); border-color: var(--accent-strong); }
a.plain { border-bottom: none; }

::selection { background: var(--accent); color: var(--ta-black); }

/* Scrollbar — barely visible */
::-webkit-scrollbar { width: 10px; height: 10px; }
::-webkit-scrollbar-track { background: transparent; }
::-webkit-scrollbar-thumb { background: rgba(244,238,223,0.08); border-radius: 6px; border: 2px solid var(--bg); }
::-webkit-scrollbar-thumb:hover { background: rgba(244,238,223,0.16); }

/* ============ APP SHELL ============ */

.app {
  display: grid;
  grid-template-columns: var(--nav-w) 1fr;
  min-height: 100vh;
}

/* --- Sidebar (variant A) --- */
.sidebar {
  /* Translúcida + blur (no opaca) para que el fondo decorativo "LightRays"
     (position:fixed detrás de .app, ver dashboard.html/v3.html) se note en
     vez de quedar completamente tapado por un panel sólido. */
  background: rgba(11,11,12,0.55);
  backdrop-filter: blur(20px);
  -webkit-backdrop-filter: blur(20px);
  border-right: 1px solid var(--line);
  /* 📌 Andres, 2026-08-29: "quiero ver todas las opciones a la vez, sin
     scroll, en admin/dev/usuario". El espaciado de aquí para abajo (marca,
     secciones, ítems, pie) se ajustó más apretado que el resto de la consola
     A PROPÓSITO — es el único sitio donde "denso" gana sobre "aireado",
     porque el objetivo es que quepan hasta 12 ítems (nivel dev) sin cortar.
     `overflow-y:auto` de .sidebar__nav (abajo) se queda como red de
     seguridad para una ventana verdaderamente diminuta — nunca se rompe,
     solo se usa menos. */
  padding: var(--s-4) var(--s-4);
  display: flex;
  flex-direction: column;
  gap: var(--s-4);
  position: sticky;
  top: 0;
  height: 100vh;
}
/* Solo el MENU hace scroll: la marca se queda arriba y el usuario abajo.
   • `min-height: 0` no es opcional aqui, es lo que hace que funcione. Un hijo
     de un contenedor flex tiene por defecto `min-height: auto`, que significa
     "nunca te encojas por debajo de tu contenido" — con eso el hijo empuja al
     padre y el `overflow-y: auto` no llega a activarse nunca. Es la trampa
     clasica de "le puse overflow y no scrollea".
   Antes de esto (2026-08-21) el menu no tenia scroll en ningun sitio: en una
   ventana de 551 px de alto, Registro, Equipo, Ajustes y Ayuda quedaban fuera
   de la pantalla y no habia forma de llegar a ellos. */
.sidebar__nav {
  flex: 1 1 auto;
  min-height: 0;
  overflow-y: auto;
  overscroll-behavior: contain;      /* al llegar al final no arrastra la pagina */
  display: flex;
  flex-direction: column;
  gap: var(--s-3);
  /* Barra fina y discreta: el menu es oscuro y la barra por defecto canta. */
  scrollbar-width: thin;
  scrollbar-color: var(--line) transparent;
}
.sidebar__nav::-webkit-scrollbar { width: 6px; }
.sidebar__nav::-webkit-scrollbar-track { background: transparent; }
.sidebar__nav::-webkit-scrollbar-thumb { background: var(--line); border-radius: 3px; }
.sidebar__nav:hover::-webkit-scrollbar-thumb { background: var(--fg-subtle); }

.sidebar__brand {
  flex-shrink: 0;
  display: flex;
  align-items: center;
  gap: 10px;
  padding-bottom: var(--s-3);
  border-bottom: 1px solid var(--line);
}
.sidebar__brand img { width: 28px; height: 28px; object-fit: contain; }
.sidebar__brand-name {
  font-family: var(--font-display);
  font-weight: 500;
  font-size: 11px;
  letter-spacing: var(--ls-eyebrow);
  text-transform: uppercase;
  color: var(--fg);
  line-height: 1.1;
}
.sidebar__brand-sub {
  font-family: var(--font-display);
  font-size: 9px;
  letter-spacing: var(--ls-eyebrow);
  color: var(--accent-ink);
  text-transform: uppercase;
}

.nav-section {
  display: flex;
  flex-direction: column;
  gap: 2px;
}
.nav-section__label {
  font-family: var(--font-display);
  font-size: 10px;
  letter-spacing: var(--ls-eyebrow);
  text-transform: uppercase;
  color: var(--fg-subtle);
  padding: 0 var(--s-3) 4px;
}

.nav-item {
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 7px var(--s-3);
  color: var(--fg-muted);
  border-radius: var(--r-sm);
  border-bottom: none;
  font-size: 13px;
  line-height: 1.25;
  font-weight: 500;
  transition: background var(--dur-fast) var(--ease-out), color var(--dur-fast) var(--ease-out);
  position: relative;
}
.nav-item .icon { width: 17px; height: 17px; flex-shrink: 0; opacity: .85; }
.nav-item:hover { background: rgba(244,238,223,0.04); color: var(--fg); }
.nav-item.is-active {
  color: var(--fg);
  background: rgba(208,184,132,0.06);
}
.nav-item.is-active::before {
  content: "";
  position: absolute;
  left: -8px;
  top: 50%;
  transform: translateY(-50%);
  width: 2px;
  height: 18px;
  background: var(--accent);
}
.nav-item__count {
  margin-left: auto;
  font-size: 11px;
  color: var(--fg-subtle);
  font-variant-numeric: tabular-nums;
}

/* Item de navegación deshabilitado a propósito (todavía no existe esa pantalla) —
   nunca un href="#" silencioso: se ve claramente inerte y explica por qué. */
.nav-item--disabled {
  cursor: default;
  color: var(--fg-subtle);
  opacity: .55;
}
.nav-item--disabled:hover { background: none; color: var(--fg-subtle); }
.nav-item--disabled .nav-item__soon {
  margin-left: auto;
  font-size: 9px;
  letter-spacing: .06em;
  text-transform: uppercase;
  color: var(--fg-subtle);
  border: 1px solid var(--line);
  border-radius: var(--r-pill, 999px);
  padding: 1px 6px;
}

.sidebar__footer {
  flex-shrink: 0;
  margin-top: auto;
  padding-top: var(--s-3);
  border-top: 1px solid var(--line);
  display: flex;
  align-items: center;
  gap: 10px;
}
.avatar {
  width: 30px; height: 30px;
  border-radius: var(--r-pill);
  background: var(--bg-paper);
  border: 1px solid var(--line-strong);
  display: grid;
  place-items: center;
  font-family: var(--font-display);
  font-size: 11px;
  letter-spacing: 0.04em;
  color: var(--accent);
  flex-shrink: 0;
}
.user-meta { line-height: 1.3; min-width: 0; }
.user-meta__name { font-size: 13px; font-weight: 600; color: var(--fg); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.user-meta__role { font-size: 11px; color: var(--fg-subtle); }

/* --- Main column --- */
.main { min-width: 0; display: flex; flex-direction: column; }

.topbar {
  height: var(--topbar-h);
  padding: 0 var(--s-8);
  border-bottom: 1px solid var(--line);
  display: flex;
  align-items: center;
  gap: var(--s-6);
  /* Translúcida (antes opaca) — el blur ya estaba pero no tenía nada
     transparente que revelar; ver comentario igual en .sidebar arriba. */
  background: rgba(11,11,12,0.55);
  position: sticky; top: 0; z-index: 10;
  backdrop-filter: blur(14px);
  -webkit-backdrop-filter: blur(14px);
}
.topbar__title {
  font-family: var(--font-serif);
  font-size: var(--fs-lg);
  font-weight: 500;
  color: var(--fg);
}
.topbar__title-eyebrow {
  font-family: var(--font-display);
  font-size: 10px;
  letter-spacing: var(--ls-eyebrow);
  text-transform: uppercase;
  color: var(--accent-ink);
  display: block;
  margin-bottom: 2px;
}
.topbar__actions { margin-left: auto; display: flex; align-items: center; gap: var(--s-3); }

/* Topbar nav variant — pills */
.topnav {
  display: flex;
  align-items: center;
  gap: var(--s-2);
}
.topnav__item {
  font-family: var(--font-display);
  font-size: 11px;
  letter-spacing: var(--ls-eyebrow);
  text-transform: uppercase;
  color: var(--fg-muted);
  padding: 8px 14px;
  border-radius: var(--r-sm);
  border-bottom: none;
  transition: color var(--dur-fast) var(--ease-out), background var(--dur-fast) var(--ease-out);
}
.topnav__item:hover { color: var(--fg); background: rgba(244,238,223,0.04); }
.topnav__item.is-active { color: var(--ta-black); background: var(--accent); }

/* Page area */
.page {
  padding: var(--s-8) var(--s-8) var(--s-16);
  max-width: 1440px;
  width: 100%;
}
.page--narrow { max-width: var(--container-md); }
.page--wide { max-width: none; }

.page__head {
  display: flex;
  align-items: flex-end;
  justify-content: space-between;
  gap: var(--s-6);
  margin-bottom: var(--s-8);
  padding-bottom: var(--s-5);
  border-bottom: 1px solid var(--line);
}
.page__title {
  font-family: var(--font-serif);
  font-size: var(--fs-3xl);
  font-weight: 500;
  line-height: 1.1;
  letter-spacing: var(--ls-tight);
  color: var(--fg);
  margin: 0;
}
.page__sub {
  color: var(--fg-muted);
  font-size: var(--fs-md);
  font-family: var(--font-serif);
  font-style: italic;
  margin-top: var(--s-2);
}

/* ============ BUTTONS ============ */

.btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 8px;
  height: 36px;
  padding: 0 16px;
  border-radius: var(--r-sm);
  border: 1px solid transparent;
  background: transparent;
  color: var(--fg);
  font-family: var(--font-sans);
  font-size: 13px;
  font-weight: 600;
  letter-spacing: 0.01em;
  cursor: pointer;
  transition: background var(--dur-fast) var(--ease-out), border-color var(--dur-fast) var(--ease-out), transform 80ms var(--ease-in-out);
  user-select: none;
  white-space: nowrap;
}
.btn:active { transform: scale(0.98); }
.btn:focus-visible { outline: none; box-shadow: var(--focus-ring); }
.btn .icon { width: 16px; height: 16px; }

.btn--primary {
  background: var(--accent);
  color: var(--ta-black);
}
.btn--primary:hover { background: var(--ta-gold-400); }

/* ⚠️ Un botón escrito como <a> (ej. "Nuevo caso" en la barra de V3 · Casos)
   heredaba la regla global `a:hover { color: var(--accent-strong) }`, que es
   dorada — y como el fondo del botón primario TAMBIÉN es dorado, el texto
   desaparecía al pasar el mouse. Andres lo reportó el 2026-08-10: "cuando
   hover en nuevo caso este desaparece".
   Gana por especificidad (0,2,1 contra 0,1,1) y se escribe una vez para
   todas las variantes: un botón es un botón, sea <button> o <a>. */
a.btn--primary:hover  { color: var(--ta-black); border-color: transparent; }
a.btn--secondary:hover,
a.btn--ghost:hover    { color: var(--fg); }
a.btn--danger:hover   { color: var(--ta-danger); }

.btn--secondary {
  border-color: var(--line-strong);
  color: var(--fg);
}
.btn--secondary:hover { background: rgba(244,238,223,0.04); border-color: rgba(244,238,223,0.28); }

.btn--ghost { color: var(--fg-muted); }
.btn--ghost:hover { color: var(--fg); background: rgba(244,238,223,0.04); }

.btn--danger { color: var(--ta-danger); border: 1px solid rgba(142,42,42,0.4); }
.btn--danger:hover { background: rgba(142,42,42,0.08); border-color: var(--ta-danger); }

.btn--sm { height: 28px; padding: 0 10px; font-size: 12px; }
.btn--lg { height: 44px; padding: 0 22px; font-size: 14px; }

.btn--icon { width: 36px; padding: 0; }
.btn--sm.btn--icon { width: 28px; }

/* ============ INPUTS ============ */

.input, .select, .textarea {
  width: 100%;
  height: 36px;
  padding: 0 12px;
  background: var(--bg-paper);
  border: 1px solid var(--line);
  border-radius: var(--r-xs);
  color: var(--fg);
  font-family: var(--font-sans);
  font-size: 13px;
  transition: border-color var(--dur-fast) var(--ease-out), background var(--dur-fast) var(--ease-out);
}
.input::placeholder, .textarea::placeholder { color: var(--fg-subtle); }
.input:hover, .select:hover { border-color: var(--line-strong); }
.input:focus, .select:focus, .textarea:focus {
  outline: none;
  border-color: var(--accent);
  background: var(--bg-soft);
}
.textarea { height: auto; padding: 10px 12px; resize: vertical; min-height: 96px; line-height: 1.5; }

.input-group {
  position: relative;
  display: flex;
  align-items: center;
}
.input-group .icon {
  position: absolute;
  left: 12px;
  width: 16px; height: 16px;
  color: var(--fg-subtle);
  pointer-events: none;
}
.input-group .input { padding-left: 36px; }
.input-group kbd {
  position: absolute;
  right: 10px;
  font-family: var(--font-mono);
  font-size: 10px;
  color: var(--fg-subtle);
  padding: 2px 6px;
  border: 1px solid var(--line);
  border-radius: 3px;
  background: var(--bg);
}

.label {
  display: block;
  font-family: var(--font-display);
  font-size: 10px;
  letter-spacing: var(--ls-eyebrow);
  text-transform: uppercase;
  color: var(--fg-subtle);
  margin-bottom: var(--s-2);
}

.field { margin-bottom: var(--s-5); }

/* ============ CARDS ============ */

.card {
  background: var(--bg-paper);
  border: 1px solid var(--line);
  border-radius: var(--r-md);
  padding: var(--s-6);
}
.card--featured { position: relative; }
.card--featured::before {
  content: "";
  position: absolute;
  inset: 0 0 auto 0;
  height: 1px;
  background: var(--accent);
  border-radius: var(--r-md) var(--r-md) 0 0;
}
.card--inset {
  background: var(--bg-soft);
}
.card__head {
  display: flex;
  align-items: flex-start;
  justify-content: space-between;
  gap: var(--s-4);
  margin-bottom: var(--s-5);
}
.card__title {
  font-family: var(--font-serif);
  font-size: var(--fs-lg);
  font-weight: 500;
  letter-spacing: var(--ls-tight);
  color: var(--fg);
  margin: 0;
}

/* ============ BADGES & CHIPS ============ */

.badge {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  height: 22px;
  padding: 0 8px;
  border-radius: var(--r-xs);
  background: rgba(244,238,223,0.06);
  color: var(--fg-muted);
  font-size: 11px;
  font-weight: 600;
  letter-spacing: 0.02em;
  border: 1px solid var(--line);
}
.badge--gold { background: rgba(208,184,132,0.10); color: var(--accent); border-color: rgba(208,184,132,0.25); }
.badge--success { background: rgba(79,107,62,0.12); color: #9CB78A; border-color: rgba(79,107,62,0.3); }
.badge--warning { background: rgba(176,125,44,0.14); color: #DCAE6A; border-color: rgba(176,125,44,0.32); }
.badge--danger  { background: rgba(142,42,42,0.16); color: #D27C7C; border-color: rgba(142,42,42,0.4); }
.badge--info    { background: rgba(47,74,107,0.18); color: #8FB1D8; border-color: rgba(47,74,107,0.4); }

.dot { width: 6px; height: 6px; border-radius: var(--r-pill); background: currentColor; }

/* ============ TABLES ============ */

.table {
  width: 100%;
  border-collapse: collapse;
  font-size: 13px;
}
.table thead th {
  text-align: left;
  font-family: var(--font-display);
  font-size: 10px;
  letter-spacing: var(--ls-eyebrow);
  text-transform: uppercase;
  font-weight: 500;
  color: var(--fg-subtle);
  padding: 0 var(--s-4) var(--s-3);
  border-bottom: 1px solid var(--line);
}
.table tbody td {
  padding: var(--s-4);
  border-bottom: 1px solid var(--line);
  color: var(--fg);
  vertical-align: middle;
}
.table tbody tr { transition: background var(--dur-fast) var(--ease-out); cursor: pointer; }
.table tbody tr:hover { background: rgba(244,238,223,0.03); }
.table tbody tr:hover td:first-child { box-shadow: inset 2px 0 0 var(--accent); }
.table .num { font-variant-numeric: tabular-nums; }
.table .muted { color: var(--fg-muted); }

.cell-id {
  font-family: var(--font-mono);
  font-size: 11px;
  color: var(--accent);
  letter-spacing: 0.02em;
}
.cell-primary { font-weight: 600; color: var(--fg); }
.cell-sub { font-size: 11px; color: var(--fg-subtle); margin-top: 2px; }

/* ============ STAT TILES ============ */

.stat-grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(200px, 1fr));
  gap: var(--s-4);
  margin-bottom: var(--s-8);
}
.stat {
  background: var(--bg-paper);
  border: 1px solid var(--line);
  border-radius: var(--r-md);
  padding: var(--s-5);
  position: relative;
}
.stat__label {
  font-family: var(--font-display);
  font-size: 10px;
  letter-spacing: var(--ls-eyebrow);
  text-transform: uppercase;
  color: var(--fg-subtle);
}
.stat__value {
  font-family: var(--font-serif);
  font-size: var(--fs-3xl);
  font-weight: 500;
  letter-spacing: var(--ls-tight);
  color: var(--fg);
  margin-top: 6px;
  line-height: 1.05;
  font-variant-numeric: tabular-nums;
}
.stat__delta {
  font-size: 11px;
  margin-top: var(--s-3);
  color: var(--fg-muted);
  display: flex;
  align-items: center;
  gap: 4px;
}
.stat__delta--up { color: #9CB78A; }
.stat__delta--down { color: #D27C7C; }

/* ============ UTILITY ============ */

.row { display: flex; align-items: center; gap: var(--s-3); }
.col { display: flex; flex-direction: column; gap: var(--s-3); }
.stack-xs { display: flex; flex-direction: column; gap: var(--s-2); }
.stack-sm { display: flex; flex-direction: column; gap: var(--s-3); }
.stack    { display: flex; flex-direction: column; gap: var(--s-5); }
.stack-lg { display: flex; flex-direction: column; gap: var(--s-8); }
.spacer { flex: 1; }
.divider { height: 1px; background: var(--line); margin: var(--s-5) 0; }
.divider--gold { background: var(--accent); width: 28px; height: 1px; margin: var(--s-3) 0; }

.eyebrow-sm {
  font-family: var(--font-display);
  font-size: 10px;
  letter-spacing: var(--ls-eyebrow);
  text-transform: uppercase;
  color: var(--accent-ink);
}
.text-muted { color: var(--fg-muted); }
.text-subtle { color: var(--fg-subtle); }
.text-gold { color: var(--accent); }
.text-serif { font-family: var(--font-serif); }
.text-display { font-family: var(--font-display); text-transform: uppercase; letter-spacing: var(--ls-eyebrow); }

.grid-2 { display: grid; grid-template-columns: 1fr 1fr; gap: var(--s-6); }
.grid-3 { display: grid; grid-template-columns: repeat(3, 1fr); gap: var(--s-6); }
.grid-sidebar { display: grid; grid-template-columns: 1fr 320px; gap: var(--s-8); }

/* ============ ICON (lucide) ============ */
[data-lucide] {
  stroke-width: 1.5;
  width: 18px;
  height: 18px;
}

/* ============================================================
   RESPONSIVE — teléfono / pantalla angosta (≤820px)
   Todo lo de aquí abajo SOLO aplica bajo ese ancho — la vista de
   escritorio queda exactamente igual que antes. Un solo lugar
   arregla las 7 pantallas de la consola que comparten .app/.sidebar.
   Estrategia: el menú lateral (antes fijo, a la izquierda, 240px)
   se convierte en una franja horizontal arriba de la página, con
   scroll lateral — así ninguna pantalla queda inalcanzable en un
   teléfono, sin agregar JavaScript ni tocar el HTML de cada página.
   ============================================================ */
@media (max-width: 820px) {
  .app {
    grid-template-columns: 1fr;   /* una sola columna: el menú ya no empuja el contenido */
  }

  .sidebar {
    position: static;             /* ya no ocupa toda la altura de la pantalla */
    height: auto;
    width: auto;
    flex-direction: row;
    align-items: center;
    flex-wrap: nowrap;
    gap: var(--s-4);
    padding: var(--s-3) var(--s-4);
    overflow-x: auto;             /* si no entra todo, se desliza con el dedo */
    -webkit-overflow-scrolling: touch;
    border-right: none;
    border-bottom: 1px solid var(--line);
  }
  .sidebar__brand {
    padding-bottom: 0;
    border-bottom: none;
    flex-shrink: 0;
  }
  .sidebar__brand-sub { display: none; }  /* ahorra espacio; el nombre solo ya identifica la app */

  /* En el telefono el menu es una FILA horizontal, no una columna: el
     contenedor que hace scroll vertical en escritorio tiene que deshacerse
     aqui, o las secciones se apilarian dentro de la barra. El deslizamiento
     lateral lo sigue haciendo .sidebar (overflow-x arriba). */
  .sidebar__nav {
    flex-direction: row;
    align-items: center;
    gap: var(--s-4);
    overflow-y: visible;
    min-height: auto;
    flex: 0 0 auto;
  }

  /* Las secciones (Inicio / Plataformas / Datos / Configuración) pasan de
     columnas apiladas a una sola fila continua, sin su título de grupo
     (no hay alto para mostrarlo) — los íconos + nombres cortos ya orientan. */
  .nav-section {
    flex-direction: row;
    flex-shrink: 0;
    gap: var(--s-1);
  }
  .nav-section__label { display: none; }
  .nav-item {
    padding: 8px 10px;
    white-space: nowrap;
  }
  .nav-item.is-active::before { display: none; }  /* la barrita vertical no aplica en fila */

  /* (Antes había aquí una regla para .nav-item__long, que escondía la
     coletilla " · Casos" de "V3 · Casos" en el teléfono. El ítem del menú pasó
     a llamarse solo "Casos" en ta-shell.js — ya no existe ese sufijo que
     esconder. Andres, 2026-08-10: "el botón debe tener solo eso, no texto de
     más" sigue cumplido, ahora en el nombre mismo. */

  /* El pie del menú (avatar + nombre + rol) se repite en la barra superior de
     cada pantalla (topbar-avatar) — se oculta aquí para no duplicar y ahorrar
     espacio vertical, que en un teléfono es lo más valioso. */
  .sidebar__footer { display: none; }

  /* --- Barra superior de cada pantalla --- */
  .topbar {
    height: auto;
    min-height: var(--topbar-h);
    flex-wrap: wrap;
    padding: var(--s-3) var(--s-4);
    gap: var(--s-3);
  }
  .topbar__actions {
    width: 100%;
    margin-left: 0;
    flex-wrap: wrap;
  }
  /* Los buscadores tienen un ancho fijo en píxeles puesto en cada página
     (340/320/280px) — en un teléfono angosto eso se sale de la pantalla.
     Se fuerza a ocupar el ancho disponible en su lugar. */
  .topbar .input-group { width: 100% !important; }

  .page {
    padding: var(--s-5) var(--s-4) var(--s-10);
  }

  /* Filas de estadísticas / tarjetas: una sola columna en vez de varias,
     para que ningún número quede apretado o cortado.
     📌 `.quicknav` (las 3 tarjetas grandes de Resumen — V3/Perfiles/
     Consultas) se sumó el 2026-08-29: en 390px de ancho cada tarjeta
     quedaba en ~110px y el título serif se partía letra por letra. */
  .cases-stats, .class-stats, .grid-2, .grid-3, .quicknav {
    grid-template-columns: 1fr;
  }
  .grid-sidebar { grid-template-columns: 1fr; }

  /* Banner "Conectar Google Sheets" (v3/registro/equipo lo definen con la
     clase .connect-banner; dashboard/perfiles lo escriben con estilos en
     línea) — en las 5 pantallas el id es el mismo, así que un solo arreglo
     por id alcanza para todas. Sin esto, el botón queda cortado fuera de la
     pantalla en un teléfono en vez de acomodarse debajo del texto. */
  #connect-banner {
    flex-wrap: wrap !important;
  }
  #btn-connect {
    margin-left: 0 !important;
    width: 100%;
  }
}

/* ═══════════════════════════════════════════════════════════════════════
   GUARDADO EN VIVO — confirmación minimalista (2026-08-10)
   ═══════════════════════════════════════════════════════════════════════
   📌 Por qué se rehízo. Antes cada guardado sacaba un cartel grande abajo a
      la derecha. Dos problemas reales, los dos vistos en la revisión manual:

      1. NO SE VEÍA. El cartel tenía z-index:200 y el panel del caso (drawer)
         tiene 901 — y encima el cartel salía justo DEBAJO del panel, en la
         misma esquina. O sea: se dibujaba detrás. Como editar un campo solo
         se puede hacer con el panel abierto, el aviso de "Guardado" era
         literalmente invisible siempre. Ese era el fallo del paso 3.2.

      2. AUNQUE SE VIERA, SOBRA. Se guarda al salir de CADA campo: un cartel
         por campo es ruido, no información. Andres lo pidió explícito:
         "que no sea disruptivo".

   Qué hace ahora, en dos capas que no interrumpen a nadie:

      • EN EL CAMPO — el propio campo se ilumina un instante en verde y le
        aparece un ✓ diminuto. Es donde ya están los ojos de quien escribe.
      • EN EL LOGO — mientras la escritura viaja a la hoja, el logo de la
        barra late suave; al terminar, un ✓ dorado. Es el "se está guardando
        en vivo" que pidió Andres, y sirve de confirmación global sin tapar
        nada de la pantalla.

   Vive en admin.css (no en v3.html) a propósito: TODAS las pantallas que
   guarden algo usan la misma señal, sin copiar y pegar estilos. */

/* ── Capa 1 · el campo que se acaba de guardar ── */
.is-saving-field {
  border-color: rgba(208,184,132,.55) !important;
  transition: border-color .2s ease, box-shadow .2s ease;
}
.is-saved-field {
  animation: fieldSaved 1.5s ease forwards;
}
@keyframes fieldSaved {
  0%   { border-color: rgba(90,190,140,.85); box-shadow: 0 0 0 3px rgba(90,190,140,.18); }
  60%  { border-color: rgba(90,190,140,.85); box-shadow: 0 0 0 3px rgba(90,190,140,.10); }
  100% { border-color: var(--line);          box-shadow: 0 0 0 0 rgba(90,190,140,0); }
}
/* El ✓ va en el contenedor del campo, no dentro del <input> (un input no
   admite hijos). Quien llame pone .field-ok-wrap en el padre. */
.field-ok-wrap { position: relative; }
.field-ok {
  position: absolute; top: 50%; right: 10px; transform: translateY(-50%);
  width: 15px; height: 15px; pointer-events: none; opacity: 0;
  animation: fieldOk 1.5s ease forwards;
}
.field-ok path { stroke: #8fe0b6; stroke-width: 3; fill: none; stroke-linecap: round; stroke-linejoin: round;
  stroke-dasharray: 24; stroke-dashoffset: 24; animation: fieldOkDraw .4s .05s ease forwards; }
@keyframes fieldOkDraw { to { stroke-dashoffset: 0; } }
@keyframes fieldOk { 0% { opacity: 0; } 15% { opacity: 1; } 75% { opacity: 1; } 100% { opacity: 0; } }
/* En un textarea (Notas) el centro vertical queda mal: se ancla arriba. */
.field-ok--top { top: 12px; transform: none; }

/* ── Capa 2 · el logo de la barra lateral como indicador global ──
   ⚠️ El dibujo del logo NO se toca: es la marca de Andres. Lo único que se
      anima es un halo por DETRÁS (::after sobre el contenedor) y la opacidad.
      Nada de reescalar, recortar ni redibujar la imagen. */
.sidebar__brand { position: relative; }
.sidebar__brand img { transition: opacity .25s ease, filter .25s ease; }

.sidebar__brand.is-saving img {
  animation: brandPulse 1.15s ease-in-out infinite;
}
@keyframes brandPulse {
  0%, 100% { opacity: .55; filter: drop-shadow(0 0 0 rgba(208,184,132,0)); }
  50%      { opacity: 1;   filter: drop-shadow(0 0 7px rgba(208,184,132,.75)); }
}
/* Anillo que gira mientras guarda — detrás del logo, nunca encima. */
.sidebar__brand.is-saving::after {
  content: '';
  position: absolute; left: -5px; top: 50%; margin-top: -21px;
  width: 42px; height: 42px; border-radius: 50%;
  border: 1.5px solid transparent;
  border-top-color: rgba(208,184,132,.85);
  border-right-color: rgba(208,184,132,.35);
  animation: brandSpin .9s linear infinite;
  pointer-events: none;
}
@keyframes brandSpin { to { transform: rotate(360deg); } }

/* Al terminar: destello dorado corto y se apaga solo. */
.sidebar__brand.is-saved img { animation: brandSaved 1.4s ease forwards; }
@keyframes brandSaved {
  0%   { filter: drop-shadow(0 0 10px rgba(143,224,182,.9)); }
  100% { filter: drop-shadow(0 0 0 rgba(143,224,182,0)); }
}

/* La línea "Consola" del logo cuenta qué está pasando, en pequeño y en el
   mismo dorado de la marca. Sustituye al cartel grande. */
.sidebar__brand-sub { transition: color .2s ease, opacity .2s ease; }
.brand-state { display: block; }
.brand-state.is-busy  { color: var(--accent); }
.brand-state.is-ok    { color: #8fe0b6; }
.brand-state.is-error { color: #d97a7a; }

@media (prefers-reduced-motion: reduce) {
  .sidebar__brand.is-saving img,
  .sidebar__brand.is-saving::after,
  .sidebar__brand.is-saved img,
  .is-saved-field, .field-ok { animation: none; }
  .sidebar__brand.is-saving img { opacity: .6; }
}

/* ── Aviso de cambios sin guardar / revertir (panel del caso) ── */
.drawer__unsaved {
  display: flex; align-items: center; gap: 10px; flex-wrap: wrap;
  margin: 0 0 14px; padding: 10px 12px;
  background: rgba(208,184,132,.08);
  border: 1px solid rgba(208,184,132,.35);
  border-radius: var(--r-sm, 8px);
  font-size: 12px; color: var(--fg-muted);
}
.drawer__unsaved b { color: var(--fg); font-weight: 600; }
.drawer__unsaved .grow { flex: 1 1 auto; }
.btn-revert {
  height: 28px; padding: 0 12px; border-radius: var(--r-sm, 8px); cursor: pointer;
  background: transparent; border: 1px solid rgba(208,184,132,.45); color: var(--accent);
  font-family: var(--font-sans); font-size: 12px; font-weight: 500;
}
.btn-revert:hover { background: rgba(208,184,132,.14); border-color: var(--accent); }
.btn-revert[disabled] { opacity: .5; cursor: default; }

/* ═══════════════════════════════════════════════════════════════════════
   DIÁLOGO DE CONFIRMACIÓN — con los colores de la casa
   ═══════════════════════════════════════════════════════════════════════
   📌 Reemplaza a confirm() del navegador. Andres lo pidió el 2026-08-10 al
      ver el de "Revertir cambios": "se ve muy no profesional". Y tiene razón
      — el cuadro gris del navegador dice "team-abogados-admin.vercel.app
      says", rompe el tema oscuro y no se puede tocar.

   Sigue siendo BLOQUEANTE (hay que contestar para seguir): el fondo tapa la
   pantalla y Escape cuenta como cancelar. Se usa solo donde la respuesta
   importa de verdad — revertir, mover de clínica, borrar — no para avisos. */
.ta-dialog-overlay {
  position: fixed; inset: 0; background: rgba(8,8,8,.62); backdrop-filter: blur(3px);
  z-index: 1000; display: flex; align-items: center; justify-content: center; padding: 20px;
  opacity: 0; animation: taDlgFadeIn .16s ease forwards;
}
@keyframes taDlgFadeIn { to { opacity: 1; } }
.ta-dialog {
  width: min(460px, 100%); background: var(--bg-paper);
  border: 1px solid var(--line); border-radius: var(--r-md, 12px);
  box-shadow: 0 30px 70px rgba(0,0,0,.55);
  transform: translateY(10px) scale(.98); opacity: 0;
  animation: taDlgIn .2s cubic-bezier(.2,.8,.3,1) .02s forwards;
  overflow: hidden;
}
@keyframes taDlgIn { to { transform: translateY(0) scale(1); opacity: 1; } }
.ta-dialog__head { padding: 20px 24px 0; display: flex; align-items: flex-start; gap: 12px; }
.ta-dialog__icon {
  flex: 0 0 auto; width: 34px; height: 34px; border-radius: 50%;
  display: flex; align-items: center; justify-content: center;
  background: rgba(208,184,132,.13); border: 1px solid rgba(208,184,132,.32);
}
.ta-dialog__icon svg { width: 17px; height: 17px; stroke: var(--accent); fill: none; stroke-width: 2; stroke-linecap: round; stroke-linejoin: round; }
.ta-dialog__title {
  font-family: var(--font-serif, Georgia, serif); font-size: 18px; color: var(--fg); margin: 4px 0 0;
}
.ta-dialog__body { padding: 12px 24px 0 70px; font-size: 13px; color: var(--fg-muted); line-height: 1.55; }
.ta-dialog__body b { color: var(--fg); font-weight: 600; }
.ta-dialog__list {
  margin: 10px 0 0; padding: 10px 12px; border-radius: var(--r-sm, 8px);
  background: rgba(255,255,255,.03); border: 1px solid var(--line);
  font-size: 12px; color: var(--fg); max-height: 160px; overflow: auto;
}
.ta-dialog__foot {
  display: flex; justify-content: flex-end; gap: 10px;
  padding: 20px 24px; margin-top: 18px; border-top: 1px solid var(--line);
}
.ta-dialog__btn {
  height: 36px; padding: 0 18px; border-radius: var(--r-sm, 8px); cursor: pointer;
  font-family: var(--font-sans); font-size: 13px; font-weight: 600;
  transition: background .15s ease, border-color .15s ease, transform .12s ease;
}
.ta-dialog__btn:active { transform: translateY(1px); }
.ta-dialog__btn--ghost { background: transparent; border: 1px solid var(--line); color: var(--fg-muted); }
.ta-dialog__btn--ghost:hover { border-color: rgba(244,238,223,.3); color: var(--fg); background: rgba(244,238,223,.04); }
.ta-dialog__btn--go { background: var(--accent); border: 1px solid var(--accent); color: #1a1410; }
.ta-dialog__btn--go:hover { background: var(--ta-gold-400); }
.ta-dialog__btn--danger { background: rgba(192,69,63,.14); border: 1px solid rgba(192,69,63,.5); color: #e08b86; }
.ta-dialog__btn--danger:hover { background: rgba(192,69,63,.24); border-color: #c0453f; }

@media (max-width: 520px) {
  .ta-dialog__body { padding-left: 24px; }
  .ta-dialog__foot { flex-direction: column-reverse; }
  .ta-dialog__btn { width: 100%; }
}

/* Campo de nivel Admin que la cuenta actual no puede tocar. */
.is-admin-locked,
[data-locked="1"] { opacity: .62; cursor: not-allowed !important; }
.tier-badge {
  display: inline-flex; align-items: center; gap: 4px; height: 16px; padding: 0 6px;
  margin-left: 6px; border-radius: 999px; font-size: 9px; font-weight: 700;
  letter-spacing: .06em; text-transform: uppercase; vertical-align: middle;
  background: rgba(208,184,132,.13); border: 1px solid rgba(208,184,132,.3); color: var(--accent-ink, #c8ad78);
}

/* ═══════════════════════════════════════════════════════════════════════
   ta-shell.js — menú, chip de usuario y buscador global (2026-08-11)
   ═══════════════════════════════════════════════════════════════════════
   📌 Antes el menú y el bloque "usuario + Salir" estaban copiados a mano en
      cada una de las 11 pantallas — un arreglo (como el hover de Salir) había
      que aplicarlo 11 veces y se desincronizaba solo. Ahora los dibuja
      ta-shell.js desde un solo sitio; este bloque de CSS es el que usan. */

/* Separa "Ayuda" del resto del menú — vive al pie, no dentro de un grupo de
   trabajo, así que necesita su propia línea divisoria arriba. */
.nav-section--help {
  margin-top: auto;
  padding-top: var(--s-3);
  border-top: 1px solid var(--line);
}

/* Botón "Salir" — antes cada pantalla traía su propio onmouseover/onmouseout
   pegado a mano, y solo 3 de 11 lo tenían (por eso en el resto no reaccionaba
   al pasar el mouse). Ahora es una clase real, en todas partes por igual. */
.btn--logout {
  display: flex; align-items: center; gap: 6px; height: 36px; padding: 0 12px;
  background: rgba(220,50,50,0.07); border: 1px solid rgba(220,50,50,0.3);
  border-radius: var(--r-sm); color: #c94040;
  font-family: var(--font-sans); font-size: 12px; font-weight: 500; cursor: pointer;
  transition: background .15s ease, border-color .15s ease, color .15s ease;
}
.btn--logout:hover { background: rgba(220,50,50,0.15); border-color: rgba(220,50,50,0.6); color: #e03030; }
.btn--logout:focus-visible { outline: none; box-shadow: var(--focus-ring); }

/* ── Buscador global (⌘K / Ctrl+K) ── */
.ta-palette-overlay { align-items: flex-start; padding-top: 12vh; }
.ta-palette {
  width: min(560px, 100%); background: var(--bg-paper);
  border: 1px solid var(--line); border-radius: var(--r-md, 12px);
  box-shadow: 0 30px 70px rgba(0,0,0,.55);
  transform: translateY(6px) scale(.99); opacity: 0;
  animation: taDlgIn .16s cubic-bezier(.2,.8,.3,1) .01s forwards;
  overflow: hidden;
}
.ta-palette__input-wrap {
  display: flex; align-items: center; gap: 10px; padding: 14px 18px;
  border-bottom: 1px solid var(--line);
}
.ta-palette__input-wrap .icon { width: 17px; height: 17px; color: var(--fg-subtle); flex-shrink: 0; }
.ta-palette__input {
  flex: 1; border: none; background: none; outline: none; color: var(--fg);
  font-family: var(--font-sans); font-size: 15px;
}
.ta-palette__input::placeholder { color: var(--fg-subtle); }
.ta-palette__input-wrap kbd {
  font-family: var(--font-mono); font-size: 10px; color: var(--fg-subtle);
  padding: 2px 6px; border: 1px solid var(--line); border-radius: 3px; background: var(--bg);
}
.ta-palette__results { max-height: 360px; overflow-y: auto; padding: 6px; }
.ta-palette__empty { padding: 22px 16px; text-align: center; font-size: 13px; color: var(--fg-subtle); }
.ta-palette__row {
  display: flex; flex-direction: column; gap: 2px; padding: 10px 12px;
  border-radius: var(--r-sm); cursor: pointer;
}
.ta-palette__row.is-active,
.ta-palette__row:hover { background: rgba(208,184,132,0.10); }
.ta-palette__row-main { display: flex; align-items: baseline; justify-content: space-between; gap: 10px; }
.ta-palette__name { font-size: 13px; font-weight: 600; color: var(--fg); }
.ta-palette__id { font-family: var(--font-mono); font-size: 11px; color: var(--accent); flex-shrink: 0; }
.ta-palette__row-sub { font-size: 11px; color: var(--fg-subtle); }

/* ── Foco de teclado visible — filas de tabla, filtros, menú ──
   Todas usan el mismo anillo dorado ya definido en tokens.css (--focus-ring),
   nunca el contorno azul por defecto del navegador (rompería el tema). */
.nav-item:focus-visible,
.chip:focus-visible,
table.cases tbody tr:focus-visible,
.crow:focus-visible {
  outline: none;
  box-shadow: var(--focus-ring);
}
table.cases tbody tr:focus-visible,
.crow:focus-visible { position: relative; z-index: 1; }

/* ═══════════════════════════════════════════════════════════════════════
   ESTADOS DE CARGA — skeleton (2026-08-11)
   ═══════════════════════════════════════════════════════════════════════
   📌 Por qué. `init()` en v3.html es asíncrono (lee la hoja compartida) y,
      hasta que termina, `#stats` y `#tbody` quedan LITERALMENTE vacíos en
      el HTML — nada les pone contenido hasta que renderStats()/renderTable()
      corren. En una conexión lenta (o el primer load real contra Sheets,
      que puede tardar más que el cache local con el que se prueba siempre)
      eso se ve como una pantalla rota: el menú y los filtros ya están,
      pero ni un número ni una fila. Encontrado recorriendo la consola con
      el ojo puesto en "¿esto se sentiría profesional si tardara 2 segundos
      más de lo normal?" — no, se sentía como que algo se había colgado.

   Estas filas/tarjetas van escritas DIRECTO en el HTML de cada pantalla
   (no las crea JS) — así aparecen en el primer pintado, antes de que
   cargue ni una línea de JavaScript. renderTable()/renderStats() las
   REEMPLAZAN por el contenido real apenas terminan — no hace falta
   "esconder" nada a mano, el propio innerHTML las borra. */
@keyframes taShimmer {
  0%   { background-position: -120% 0; }
  100% { background-position: 220% 0; }
}
.skel {
  display: inline-block;
  border-radius: 4px;
  background: linear-gradient(90deg, rgba(244,238,223,0.05) 25%, rgba(244,238,223,0.12) 50%, rgba(244,238,223,0.05) 75%);
  background-size: 200% 100%;
  animation: taShimmer 1.6s ease-in-out infinite;
  color: transparent !important; /* por si el elemento real trae texto de respaldo */
}
/* Fila de tabla (V3 · Casos): mismas 11 columnas que .crow, en el mismo
   ancho relativo, para que la tabla real "aterrice" en el mismo sitio y
   no haya un salto de layout cuando llegan los datos. */
tr.skel-row td { padding: var(--s-4); border-bottom: 1px solid var(--line); }
tr.skel-row .skel { height: 13px; width: 100%; }
tr.skel-row .skel--avatar { width: 26px; height: 26px; border-radius: 50%; }
tr.skel-row .skel--wide { width: 82%; }
tr.skel-row .skel--mid { width: 60%; }
tr.skel-row .skel--narrow { width: 40%; }
/* Cada fila late un poco después de la anterior — se lee como una lista
   "viva" en vez de 5 copias idénticas parpadeando al unísono. */
tr.skel-row:nth-child(2) .skel { animation-delay: .08s; }
tr.skel-row:nth-child(3) .skel { animation-delay: .16s; }
tr.skel-row:nth-child(4) .skel { animation-delay: .24s; }
tr.skel-row:nth-child(5) .skel { animation-delay: .32s; }

/* Tarjeta de estadística (.cstat / .stat): la etiqueta queda real y fija
   (ya se sabe qué número va a aparecer ahí — "Casos totales", etc.) y solo
   el VALOR es el bloque que late, en vez de vaciar la tarjeta entera. */
.skel-stat-value { display: inline-block; width: 44px; height: 24px; margin-top: 3px; }

@media (prefers-reduced-motion: reduce) {
  .skel { animation: none; background: rgba(244,238,223,0.08); }
}

/* =============================================================
   TEMA CLARO  —  :root[data-tema="claro"]
   =============================================================
   Andres, 2026-08-26: "opcion de mantener el tema negro y opcion de
   cambiarlo a blanco".

   Como funciona: admin.css re-ata los tokens semanticos (--bg, --fg, --line…)
   a los valores OSCUROS. Aqui se vuelven a atar a los CLAROS, que ya existen
   en tokens.css. Nada de esto toca los componentes: cada tarjeta, tabla y
   boton sigue leyendo los mismos tokens, asi que el tema cambia entero sin
   reescribir una sola regla de componente.

   El oro tambien cambia de tono: --ta-gold-500 (#D0B884) esta pensado para
   brillar sobre negro; sobre papel claro se lava y no se lee. En claro se usa
   --ta-gold-700 / -900, que es como se ve el oro en un membrete impreso.
   ============================================================= */
:root[data-tema="claro"] {
  --bg:             var(--ta-cream);
  --bg-soft:        var(--ta-cream-soft);
  --bg-paper:       var(--ta-paper);
  --bg-pressed:     var(--ta-bone);
  --surface:        var(--ta-paper);
  --surface-ink:    var(--ta-black);
  --surface-ink-fg: var(--ta-cream);

  --fg:             var(--ta-black);
  --fg-muted:       var(--ta-black-60);
  --fg-subtle:      var(--ta-black-40);
  --fg-inverse:     var(--ta-cream);

  --accent:         var(--ta-gold-700);
  --accent-strong:  var(--ta-gold-900);
  --accent-soft:    var(--ta-gold-100);
  --accent-ink:     var(--ta-gold-900);

  --line:           var(--ta-black-10);
  --line-strong:    var(--ta-black-20);
  --line-gold:      var(--ta-gold-500);

  --focus-ring:     0 0 0 2px var(--ta-cream), 0 0 0 4px var(--ta-gold-700);
}

/* ── Los pocos sitios con un color escrito a mano ──────────────────────────
   Casi todo el sistema usa tokens y cambia solo. Estas reglas son las
   excepciones: nacieron con un blanco o un negro literal dentro, y sobre el
   tema contrario se verian mal. Se corrigen una por una, a proposito, en vez
   de con un filtro global que degradaria la nitidez de todo. */

/* La barra lateral era translucida sobre negro. En claro se vuelve papel
   solido: un translucido claro sobre fondo claro no separa nada. */
:root[data-tema="claro"] .sidebar {
  background: var(--ta-paper);
  backdrop-filter: none;
  -webkit-backdrop-filter: none;
  border-right: 1px solid var(--line);
}
:root[data-tema="claro"] .nav-item:hover { background: rgba(11,11,12,0.05); }
:root[data-tema="claro"] .nav-item.is-active { background: rgba(154,122,46,0.10); }

/* Filas de tabla: el separador era blanco al 4 %, invisible sobre papel. */
:root[data-tema="claro"] table tbody tr { border-bottom-color: var(--line); }

/* Barra de scroll. */
:root[data-tema="claro"] ::-webkit-scrollbar-thumb { background: rgba(11,11,12,0.16); }
:root[data-tema="claro"] ::-webkit-scrollbar-thumb:hover { background: rgba(11,11,12,0.28); }

/* Seleccion de texto: dorado sobre negro se lee; sobre papel, no. */
:root[data-tema="claro"] ::selection { background: var(--ta-gold-200); color: var(--ta-black); }

/* El codigo en linea de la Ayuda tenia el fondo en negro puro. */
:root[data-tema="claro"] .doc code { background: var(--ta-bone); }
