/* ============================================================
   BLACK DIAMOND — sistema visual
   Dark luxury: negro void, superficies grafito, acento platino.
   El diamante no es un adorno: es luz sobre negro. Por eso casi
   todo el color se gasta en el fondo (negro) y el brillo se
   reserva para el dato. Hairlines de 1px, cero sombras suaves.

   1. El negro manda. Fondo void, tinta casi blanca, aire.
   2. El acento es platino, no un color. El unico color con
      significado obligatorio es el rojo = caida; nunca va solo
      (siempre signo, icono o texto).
   3. La firma es el filo de faceta: una linea de luz platino en el
      masthead y en el KPI principal, y en ningun otro lugar.

   Inter (UI + display, tracking cerrado) · Playfair Display 700
   (solo el logotipo de la intro) · JetBrains Mono (cifras, tabular)
   ============================================================ */

/* --------------------------------------------------------------
   Tokens. Los nombres semanticos son los de arriba; abajo quedan
   los alias historicos (--void, --platinum, ...) apuntando a los
   nuevos, para no reescribir 1200 lineas de selectores. Un token
   nuevo se agrega arriba, nunca un hex crudo en un componente.
   -------------------------------------------------------------- */
:root {
  color-scheme: dark;

  /* --- primitivas de color. En dark ya no son los cuatro cuadros
     del logo: son los tonos de la categorica, todos >=3:1 sobre el
     fondo void y separados tambien en luminancia (deuteranopia). --- */
  --mp-red:   #e2685a;
  --mp-green: #6fcfaf;
  --mp-amber: #d8b25f;
  --mp-blue:  #7fb2e5;

  /* En claro las variantes -ink existian porque el color puro no
     alcanzaba 4.5:1 sobre papel. Sobre negro el puro ya contrasta,
     asi que -ink es el mismo tono: los alias siguen vivos para no
     tocar los selectores que los usan. */
  --mp-red-ink:   var(--mp-red);
  --mp-green-ink: var(--mp-green);
  --mp-amber-ink: var(--mp-amber);
  --mp-blue-ink:  var(--mp-blue);

  /* Firma de marca. Solo masthead y KPI total: el filo de luz que
     corta la pieza, como la arista iluminada de una faceta. */
  --band: linear-gradient(90deg,
    transparent, rgba(201,205,212,.35), transparent);

  /* --- superficies --- */
  --canvas:    #0a0a0b;   /* fondo de pagina (void) */
  --paper:     #141416;   /* paneles, cards, tablas */
  --surface-2: #1b1b1e;   /* hover / zebra */
  --surface-3: #232327;   /* activo / presionado, menus, popovers */
  --line:      #2a2a2e;   /* hairline visible */
  --line-soft: #202024;   /* hairline interno */
  --line-hard: #3a3a40;   /* borde de enfasis */

  /* --- tinta (contraste medido sobre --canvas) --- */
  --text:      #f2f2f3;   /* primario   ~17:1 */
  --text-2:    #9a9aa0;   /* secundario  ~7:1 */
  --text-3:    #7e7e86;   /* terciario   ~4.6:1 (minimo AA) */

  /* --- acento primario: platino --- */
  --brand:     #c9cdd4;   /* enlaces, relleno de boton */
  --brand-hi:  #e8f1ff;   /* destello frio: foco, activo, hover */
  --brand-lo:  #8f949c;   /* etiquetas y bordes tenues */
  --brand-tint: color-mix(in srgb, var(--brand) 9%, var(--paper));
  /* Tinta sobre relleno de acento: el platino es claro, asi que el
     texto encima va en negro void, no en blanco. */
  --on-brand:  var(--canvas);

  /* --- semanticos --- */
  --danger:     var(--mp-red);       /* relleno: barras, badges */
  --danger-ink: var(--mp-red);       /* texto sobre fondo o tinte */
  --danger-bg:  color-mix(in srgb, var(--mp-red) 14%, transparent);
  --warn:       var(--mp-amber);
  --warn-fill:  var(--mp-amber);
  --warn-bg:    color-mix(in srgb, var(--mp-amber) 12%, transparent);
  --ok:         var(--mp-green);

  /* --- alias heredados (no romper selectores existentes) --- */
  --void:       var(--canvas);
  --surface:    var(--paper);
  --ink:        var(--text);
  --ink-2:      var(--text-2);
  --ink-3:      var(--text-3);
  --rule:       var(--line);
  --rule-soft:  var(--line-soft);
  --platinum:    var(--brand);
  --platinum-hi: var(--brand-hi);
  --platinum-lo: var(--brand-lo);
  --green:      var(--ok);
  --green-deep: var(--ok);
  --vermillion: var(--danger-ink);
  --vermillion-d: var(--danger-ink);
  --gold:       var(--warn);
  --rojo:       var(--danger-ink);
  --rojo-suave: var(--danger-bg);

  /* En dark, "sombra" es luz: un halo tenue hacia abajo y un borde
     superior claro que simula la arista iluminada de una faceta. */
  --shadow:    inset 0 1px 0 rgba(255,255,255,.045), 0 18px 50px -28px rgba(0,0,0,.9);
  --shadow-sm: inset 0 1px 0 rgba(255,255,255,.04), 0 8px 22px -16px rgba(0,0,0,.85);
  --facet: linear-gradient(140deg,
    rgba(255,255,255,.055) 0%, rgba(255,255,255,0) 38%,
    rgba(255,255,255,0) 62%, rgba(255,255,255,.028) 100%);

  --font-display: "Inter", system-ui, -apple-system, sans-serif;
  --font-body:    "Inter", system-ui, -apple-system, sans-serif;
  --font-brand:   "Inter", system-ui, -apple-system, sans-serif;
  --font-mono:    "JetBrains Mono", ui-monospace, SFMono-Regular, monospace;

  /* --- escalas (responsive) ---
     Breakpoints (mobile-first, no se pueden usar como var en @media):
       sm 640px · md 900px · lg 1200px.  "Movil" = max-width 639.98px. */
  --sp-1: 4px;  --sp-2: 8px;  --sp-3: 12px; --sp-4: 16px;
  --sp-5: 20px; --sp-6: 24px; --sp-7: 28px; --sp-8: 32px;
  --gutter: clamp(16px, 4vw, 44px);
  --r-sm: 6px; --r-md: 8px; --r-lg: 10px; --r-xl: 14px;
  --fs-xs: 11px; --fs-sm: 13px; --fs-md: 15px;
  --fs-lg: clamp(16px, 1.2vw + 11px, 20px);
  --fs-xl: clamp(24px, 2.5vw + 14px, 40px);
  /* celdas de tablas cruzadas: por ancho de viewport, nunca por alto */
  --fs-cell: clamp(11px, 0.3vw + 9.5px, 12.5px);
  --fs-cell-h: clamp(9.5px, 0.25vw + 8px, 10.5px);
  --z-sticky: 10; --z-popover: 50; --z-masthead: 60; --z-scrim: 90;
  --z-drawer: 100; --z-toast: 200;
  --tap: 44px;
}

/* ============================================================
   Modo claro
   La marca es negra, así que el claro no es "otra identidad": es la
   misma pieza impresa en papel. Mismo grafito para la tinta, mismo
   acento sin color (aquí el acento es la tinta, no el brillo), y el
   dato manda igual. Solo se redefinen TOKENS: ni un selector de
   componente cambia de tema.

   El interruptor vive en el masthead y guarda la elección en
   localStorage; un script en <head> pone el atributo antes del primer
   pintado (ver base.html) para que no haya destello.
   ============================================================ */
:root[data-tema="claro"] {
  color-scheme: light;

  /* Categórica de gráficas para papel: todas >=3:1 sobre blanco y
     separadas también en luminancia (deuteranopia). */
  --mp-red:   #b3261e;
  --mp-green: #2f6b46;
  --mp-amber: #8a5a00;
  --mp-blue:  #1f5f8b;

  --band: linear-gradient(90deg, transparent, rgba(20,22,26,.30), transparent);

  --canvas:    #f2f3f5;   /* fondo de pagina */
  --paper:     #ffffff;   /* paneles, cards, tablas */
  --surface-2: #f1f2f4;   /* hover / zebra */
  --surface-3: #e6e8ec;   /* activo / presionado, menus, popovers */
  --line:      #d8dbe0;
  --line-soft: #e8eaee;
  --line-hard: #b9bec6;

  /* contraste medido sobre --paper */
  --text:      #14161a;   /* 16.4:1 */
  --text-2:    #4a5058;   /* 8.1:1  */
  --text-3:    #6b7178;   /* 4.9:1 (minimo AA) */

  /* El acento en papel es tinta grafito, no un color: el platino sobre
     blanco no se ve. El texto sobre relleno de acento va en blanco. */
  --brand:     #2b3440;
  --brand-hi:  #0f1319;
  --brand-lo:  #6b7178;
  --brand-tint: color-mix(in srgb, var(--brand) 6%, var(--paper));
  --on-brand:  #ffffff;

  --danger:     #b3261e;
  --danger-ink: #96201a;
  --danger-bg:  color-mix(in srgb, var(--mp-red) 10%, transparent);
  --warn:       #8a5a00;
  --warn-fill:  #d8a200;
  --warn-bg:    color-mix(in srgb, var(--warn-fill) 18%, transparent);
  --ok:         #2f6b46;

  /* En claro la elevacion vuelve a ser sombra: difusa, corta y gris,
     para que la card se despegue del canvas sin ensuciarlo. */
  --shadow:    0 1px 2px rgba(20,22,26,.05), 0 14px 30px -18px rgba(20,22,26,.22);
  --shadow-sm: 0 1px 2px rgba(20,22,26,.05), 0 6px 14px -10px rgba(20,22,26,.16);
  /* El filo de faceta es un destello: sobre papel no existe. */
  --facet: none;
}
/* El grano rompia el banding del negro plano. Sobre papel no hay banding
   y el ruido se lee como suciedad. */
:root[data-tema="claro"] .grain { display: none; }
/* Los dos destellos de faceta del fondo se apagan; queda un lavado
   grisaceo, apenas por debajo del umbral de lectura. */
:root[data-tema="claro"] body {
  background-image:
    radial-gradient(70% 50% at 100% -8%, rgba(43,52,64,.055), transparent 62%),
    radial-gradient(55% 45% at -8% 108%, rgba(43,52,64,.04), transparent 58%);
}

* { box-sizing: border-box; }
[hidden] { display: none !important; }

html { -webkit-text-size-adjust: 100%; }

body {
  margin: 0;
  font-family: var(--font-body);
  font-size: 15px;
  line-height: 1.55;
  letter-spacing: -.005em;
  color: var(--text);
  background-color: var(--canvas);
  /* Dos destellos de faceta, arriba-derecha y abajo-izquierda. Muy por
     debajo del umbral de lectura: dan volumen al negro, no compiten
     con el dato. */
  background-image:
    radial-gradient(110% 70% at 100% -10%, rgba(201,205,212,.075), transparent 58%),
    radial-gradient(90% 60% at -10% 110%, rgba(143,148,156,.055), transparent 55%);
  background-attachment: fixed;
  min-height: 100vh; min-height: 100dvh;
  display: flex; flex-direction: column;
  -webkit-font-smoothing: antialiased;
  text-rendering: optimizeLegibility;
}

/* Grano: en negro plano se ve banding, el ruido lo rompe. */
.grain {
  position: fixed; inset: 0; z-index: 9999; pointer-events: none;
  opacity: .30; mix-blend-mode: soft-light;
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='160' height='160'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='0.85' numOctaves='2' stitchTiles='stitch'/%3E%3C/filter%3E%3Crect width='100%25' height='100%25' filter='url(%23n)' opacity='0.55'/%3E%3C/svg%3E");
}

a { color: var(--platinum); text-decoration: none; }
a:hover { color: var(--platinum-hi); }

.muted { color: var(--text-2); }
.spacer { flex: 1; }

::selection { background: var(--platinum); color: var(--void); }

::-webkit-scrollbar { width: 11px; height: 11px; }
::-webkit-scrollbar-track { background: var(--canvas); }
::-webkit-scrollbar-thumb { background: var(--line-hard); border-radius: 100px; border: 3px solid var(--canvas); }
::-webkit-scrollbar-thumb:hover { background: var(--text-3); }

.num, .mono { font-family: var(--font-mono); font-variant-numeric: tabular-nums; }

/* ============================================================
   Masthead
   ============================================================ */
.masthead {
  display: flex; align-items: center; gap: 16px;
  padding: 13px 26px;
  background: color-mix(in srgb, var(--surface) 88%, transparent);
  backdrop-filter: saturate(140%) blur(14px);
  -webkit-backdrop-filter: saturate(140%) blur(14px);
  border-bottom: 1px solid var(--line);
  position: sticky; top: 0; z-index: 50;
}
/* La firma: el filo de faceta, la linea de luz que corta el header.
   Es el unico lugar de la app (con el KPI total) donde el brillo
   aparece sin significar dato. */
.masthead::after {
  content: ""; position: absolute; left: 0; right: 0; bottom: -1px; height: 1px;
  background: var(--band);
}
.brand { display: flex; align-items: center; gap: 11px; color: var(--text); }
/* El isotipo es el diamante de la marca en trazo, no un relleno: sobre
   negro la silueta se lee mejor como aristas de luz. */
.brand-mark {
  display: inline-flex; align-items: center; justify-content: center;
  width: 26px; height: 26px; flex-shrink: 0;
  color: var(--platinum);
  transition: color .18s, transform .18s;
}
.brand-mark svg { width: 100%; height: 100%; display: block; }
.brand:hover .brand-mark { color: var(--platinum-hi); transform: rotate(-8deg); }
/* Logotipo: Inter 600 con tracking cerrado. "Black" en tinta plena y
   "Diamond" en platino: la palabra que pesa es la primera. */
.brand-name {
  font-family: var(--font-display); font-weight: 600; font-size: 15px;
  letter-spacing: .01em; line-height: 1; color: var(--text);
  white-space: nowrap;
}
.brand-name .thin { font-weight: 300; color: var(--platinum); }
.masthead-rule { width: 1px; height: 22px; background: var(--line); }
.masthead-tag {
  font-family: var(--font-mono); font-size: 10.5px; letter-spacing: .12em;
  text-transform: uppercase; color: var(--text-3);
}
.masthead-user {
  font-family: var(--font-mono); font-size: 12px; color: var(--text-2);
  padding: 3px 11px; border: 1px solid var(--line); border-radius: 100px;
  background: var(--surface-2);
}
/* ----- Interruptor de tema -----
   Los dos iconos van en el DOM y el CSS ensena el que toca: en oscuro se
   ofrece el sol (lo que vas a obtener), en claro la luna. */
.tema-btn {
  display: inline-flex; align-items: center; gap: 7px;
  font-family: var(--font-mono); font-size: 12px; letter-spacing: .02em;
  padding: 6px 10px; min-height: 32px; cursor: pointer;
  background: none; color: var(--text-2);
  border: 1px solid var(--line); border-radius: 100px;
  transition: color .14s, border-color .14s, background .14s;
}
.tema-btn:hover { color: var(--text); border-color: var(--line-hard); background: var(--surface-2); }
.tema-btn .ico { width: 15px; height: 15px; }
.tema-btn.solo-icono { padding: 6px; width: 32px; justify-content: center; }
.tema-btn.solo-icono .tema-txt { display: none; }
.tema-ico { display: none; line-height: 0; }
:root[data-tema="oscuro"] .tema-ico-sol,
:root[data-tema="claro"] .tema-ico-luna { display: inline-flex; }
/* Sin JS no hay atributo data-tema: el portal se queda en oscuro y el boton
   no serviria de nada, asi que no se pinta. */
:root:not([data-tema]) .tema-btn { display: none; }

.link-quiet {
  font-family: var(--font-mono); font-size: 12px; letter-spacing: .02em;
  color: var(--text-2);
}
.link-quiet:hover { color: var(--platinum-hi); }
/* "Salir" es un POST (GET permitia cerrar la sesion con un <img src>); el
   boton se ve como el enlace de siempre. */
.salir { display: inline; margin: 0; }
.salir button { background: none; border: 0; padding: 0; font: inherit; cursor: pointer; }

@media (max-width: 639.98px) {
  .masthead-tag, .masthead-rule { display: none; }
  .masthead { padding: 10px 16px; gap: 10px; }
}

/* ============================================================
   Layout
   ============================================================ */
.layout { display: flex; align-items: stretch; flex: 1; min-height: 0; }

/* ----- Sidebar ----- */
.sidebar {
  width: 252px; flex-shrink: 0; padding: 26px 20px 40px;
  border-right: 1px solid var(--line);
  background: color-mix(in srgb, var(--paper) 45%, transparent);
}
/* En movil el sidebar de 252px fijos le dejaba ~120px al contenido y
   todo salia en columnas de una palabra. Se apila: navegacion arriba,
   contenido abajo, cada uno con el ancho completo. */
@media (max-width: 639.98px) {
  .layout { flex-direction: column; }
  .sidebar {
    width: auto; padding: 12px 16px 14px;
    border-right: 0; border-bottom: 1px solid var(--line);
  }
}
.sidebar h2 {
  font-family: var(--font-mono); font-size: 10.5px; font-weight: 500;
  text-transform: uppercase; letter-spacing: .2em; color: var(--text-3);
  margin: 0 0 8px;
}
.anio {
  font-family: var(--font-display); font-weight: 600; font-size: 15px;
  letter-spacing: .06em; color: var(--platinum); margin: 22px 0 6px;
  display: flex; align-items: center; gap: 10px;
}
.anio::after { content: ""; flex: 1; height: 1px; background: var(--line); }
.meses { list-style: none; padding: 0; margin: 0; }
.meses li { animation: fade-up .5s both; }
.meses a {
  display: flex; align-items: baseline; justify-content: space-between; gap: 8px;
  padding: 7px 12px; margin: 1px 0; border-radius: 7px;
  color: var(--text-2); position: relative;
  transition: background .15s, color .15s;
}
/* Marca de posición: un rombo de platino, la faceta del diamante. */
.meses a::before {
  content: ""; position: absolute; left: 3px; top: 50%;
  width: 5px; height: 5px; background: var(--platinum);
  transform: translateY(-50%) rotate(45deg) scale(0); transform-origin: center;
  transition: transform .18s;
}
.meses a:hover { background: var(--surface-2); color: var(--text); text-decoration: none; }
.meses a.activo { background: var(--surface-3); color: var(--text); font-weight: 500; }
.meses a.activo::before { transform: translateY(-50%) rotate(45deg) scale(1); }
.meses a .badge {
  font-family: var(--font-mono); font-size: 11px; font-variant-numeric: tabular-nums;
  color: var(--text-3);
}
.meses a.activo .badge { color: var(--platinum); }

/* dias dentro del mes activo */
.dias { list-style: none; padding: 0; margin: 2px 0 6px; }
.dias li { animation: none; }
.dias a {
  display: flex; align-items: baseline; justify-content: space-between; gap: 8px;
  padding: 5px 12px 5px 24px; margin: 1px 0; border-radius: 6px;
  color: var(--text-3); font-family: var(--font-mono); font-size: 12px;
  position: relative; transition: background .15s, color .15s;
}
.dias a:hover { background: var(--surface-2); color: var(--text); text-decoration: none; }
.dias a.activo { background: var(--platinum); color: var(--void); font-weight: 600; }
.dias a .badge {
  font-family: var(--font-mono); font-size: 10px; color: var(--text-3);
  font-variant-numeric: tabular-nums;
}
.dias a.activo .badge { color: var(--void); opacity: .7; }
.dias a.dia-todo { letter-spacing: .02em; }
.dias a.dia-todo.activo { background: var(--surface-3); color: var(--text); }

.ver-mes {
  font-family: var(--font-mono); font-size: 11px; font-weight: 400;
  color: var(--platinum); margin-left: 12px; vertical-align: middle;
}

/* ----- Contenido ----- */
.content { flex: 1; min-width: 0; padding: 36px var(--gutter) 64px; }
.content.full { padding: 32px var(--gutter) 64px; }
@media (max-width: 639.98px) { .content, .content.full { padding: 20px var(--gutter) 48px; } }

.content > h1, .rep-head h1 {
  font-family: var(--font-display); font-weight: 600;
  font-size: clamp(28px, 3.6vw, 40px); line-height: 1.06; letter-spacing: -.035em;
  margin: 0 0 4px; color: var(--text);
}
.content > h1 .yr { color: var(--text-3); font-weight: 300; }
.eyebrow {
  font-family: var(--font-mono); font-size: 10.5px; letter-spacing: .24em;
  text-transform: uppercase; color: var(--platinum-lo); margin: 0 0 14px;
}

/* ============================================================
   Tabla (índice de reportes)
   ============================================================ */
.lista { width: 100%; border-collapse: collapse; margin-top: 26px; }
.lista thead th {
  font-family: var(--font-mono); font-size: 10px; font-weight: 500;
  text-transform: uppercase; letter-spacing: .16em; color: var(--text-3);
  text-align: left; padding: 0 14px 10px; border-bottom: 1px solid var(--line-hard);
}
.lista thead th.num { text-align: right; }
.lista tbody tr {
  border-bottom: 1px solid var(--line-soft);
  animation: fade-up .45s both;
  transition: background .14s;
}
.lista tbody tr:hover { background: var(--surface-2); }
.lista td { padding: 13px 14px; vertical-align: baseline; }

.rep-link {
  font-family: var(--font-display); font-weight: 500; font-size: 15.5px;
  color: var(--text); letter-spacing: -.015em;
  display: inline-flex; align-items: baseline; gap: 11px;
}
.rep-link:hover { color: var(--platinum-hi); text-decoration: none; }
.rep-link .seq {
  font-family: var(--font-mono); font-size: 11.5px; font-weight: 400;
  color: var(--text-3); font-variant-numeric: tabular-nums;
}

/* punto por tienda */
.dot {
  width: 8px; height: 8px; display: inline-block; border-radius: 2px;
  background: currentColor; flex-shrink: 0;
  transform: translateY(-1px);
  box-shadow: 0 0 0 3px color-mix(in srgb, currentColor 16%, transparent);
}
.tienda-cell { font-weight: 600; font-size: 14px; letter-spacing: -.01em; }
[data-tienda] { color: var(--platinum); }

.grupo-tienda td {
  padding-top: 20px; padding-bottom: 8px;
  border-bottom: 1px solid var(--line);
}
.grupo-tienda .tienda-cell {
  font-size: 12px; letter-spacing: .14em; text-transform: uppercase;
}
.grupo-tienda .grupo-conteo {
  font-family: var(--font-mono); font-size: 11px; color: var(--text-3);
  margin-left: 8px; font-variant-numeric: tabular-nums;
}
.rep-name { font-size: 14px; color: var(--text-2); }

.tag-tipo {
  font-family: var(--font-mono); font-size: 10.5px; letter-spacing: .06em;
  text-transform: uppercase; color: var(--text-2);
  border: 1px solid var(--line); border-radius: 4px; padding: 2px 8px;
  background: var(--surface-2);
}
.lista td.num {
  text-align: right; color: var(--text); font-size: 14px;
  font-family: var(--font-mono); font-variant-numeric: tabular-nums;
}

/* Tabla cruzada compacta (Consolidado): mes completo en 100vh. */
.lista.xtab thead th { padding: 0 10px 4px; font-size: var(--fs-cell-h); }
.lista.xtab td { padding: 3px 10px; font-size: var(--fs-cell); line-height: 1.25; }
.lista.xtab td.num { font-size: var(--fs-cell); }
.lista.xtab tbody tr { animation: none; }

/* ============================================================
   Botones
   ============================================================ */
.btn, .btn-sm {
  display: inline-flex; align-items: center; gap: 7px;
  font-family: var(--font-mono); font-weight: 500; letter-spacing: .04em;
  text-transform: uppercase;
  border: 1px solid var(--platinum); background: var(--platinum); color: var(--void);
  border-radius: 7px; cursor: pointer;
  transition: background .14s, border-color .14s, color .14s, box-shadow .14s;
}
.btn { padding: 11px 18px; font-size: 12px; }
.btn-sm { padding: 6px 12px; font-size: 11px; }
.btn:hover, .btn-sm:hover {
  text-decoration: none; background: var(--platinum-hi); border-color: var(--platinum-hi);
  color: var(--void); box-shadow: 0 0 0 3px color-mix(in srgb, var(--platinum) 18%, transparent);
}
.btn-ghost {
  background: transparent; color: var(--text-2); border-color: var(--line);
}
.btn-ghost:hover {
  background: var(--surface-2); border-color: var(--platinum-lo); color: var(--text);
  box-shadow: none;
}
.btn:disabled, .btn-sm:disabled {
  opacity: .4; cursor: not-allowed; box-shadow: none;
  background: var(--surface-3); border-color: var(--line); color: var(--text-3);
}

/* Selector de periodo: gemelo "fantasma" del .btn, etiqueta flotando
   sobre el borde. */
.field-periodo { position: relative; display: inline-flex; }
.field-tag {
  position: absolute; top: -7px; left: 11px; padding: 0 5px;
  font-family: var(--font-mono); font-size: 9.5px; font-weight: 500;
  letter-spacing: .16em; text-transform: uppercase;
  color: var(--text-3); background: var(--canvas);
  pointer-events: none; z-index: 1;
}
.select-ctrl {
  appearance: none; -webkit-appearance: none;
  font-family: var(--font-mono); font-weight: 500; font-size: 12.5px;
  letter-spacing: .02em; color: var(--text);
  border: 1px solid var(--line); border-radius: 7px;
  padding: 11px 36px 11px 14px; cursor: pointer;
  background: var(--surface)
    url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='10' height='6' viewBox='0 0 10 6'%3E%3Cpath d='M1 1l4 4 4-4' fill='none' stroke='%236b7684' stroke-width='1.5'/%3E%3C/svg%3E")
    no-repeat right 13px center;
  transition: background-color .12s, border-color .12s;
}
.select-ctrl:hover { background-color: var(--surface-2); border-color: var(--platinum-lo); }
.select-ctrl:focus-visible { outline: 2px solid var(--platinum-hi); outline-offset: 2px; }
.select-ctrl option { background: var(--surface-3); color: var(--text); }
@media (prefers-reduced-motion: reduce) {
  .select-ctrl { transition: none; }
}

/* ============================================================
   Login — vitrina de marca
   ============================================================ */
.login-wrap {
  flex: 1; display: grid; place-items: center; padding: 40px 20px;
  position: relative; overflow: hidden;
}
/* Logotipo gigante de fondo, en contorno y apenas visible. */
.login-wrap::before {
  content: "DIAMOND"; position: absolute; inset: 0;
  font-family: var(--font-display); font-weight: 700;
  font-size: 24vw; line-height: 1; letter-spacing: -.05em;
  color: transparent;
  /* Por token: en papel, un contorno de platino al 10% no se ve. */
  -webkit-text-stroke: 1px color-mix(in srgb, var(--text) 12%, transparent);
  display: grid; place-items: center;
  pointer-events: none; overflow: hidden;
}
.card.login {
  position: relative; background: var(--surface);
  background-image: var(--facet);
  padding: 40px 38px 34px; width: 380px; max-width: 100%;
  border: 1px solid var(--line); border-radius: 14px; box-shadow: var(--shadow);
  animation: fade-up .6s both;
}
/* El diamante a 34px, sin logotipo: en la portada del portal la marca
   entra por el simbolo y el nombre queda en el eyebrow. */
.card.login .login-mark {
  display: block; width: 34px; height: 34px; color: var(--platinum);
  margin: 0 0 20px;
}
.card.login .login-eyebrow {
  font-family: var(--font-mono); font-size: 10px; letter-spacing: .28em;
  text-transform: uppercase; color: var(--platinum-lo); margin: 0 0 10px;
}
.card.login h1 {
  font-family: var(--font-display); font-weight: 600; font-size: 26px;
  letter-spacing: -.03em; margin: 0 0 6px; line-height: 1.1; color: var(--text);
}
.card.login .sub { color: var(--text-2); font-size: 13.5px; margin: 0 0 26px; }
.card.login label {
  display: block; margin-bottom: 16px;
  font-family: var(--font-mono); font-size: 10px; letter-spacing: .16em;
  text-transform: uppercase; color: var(--text-3);
}
.card.login input {
  width: 100%; margin-top: 8px; padding: 12px 13px; min-height: 44px;
  font-family: var(--font-body); font-size: 16px; color: var(--text);
  background: var(--canvas); border: 1px solid var(--line); border-radius: 8px;
  transition: border-color .15s, box-shadow .15s;
}
.card.login input::placeholder { color: var(--text-3); }
.card.login input:focus {
  outline: none; border-color: var(--platinum);
  box-shadow: 0 0 0 3px color-mix(in srgb, var(--platinum) 16%, transparent);
}
.card.login button {
  width: 100%; margin-top: 10px; padding: 13px; font-size: 12px; min-height: 44px;
  justify-content: center;
}
.error {
  font-family: var(--font-mono); font-size: 12px; color: var(--danger-ink);
  background: var(--danger-bg);
  border-left: 2px solid var(--danger); padding: 9px 12px; border-radius: 4px;
  margin: 0 0 18px;
}

/* ============================================================
   Detalle de reporte
   ============================================================ */
.rep-head {
  display: flex; justify-content: space-between; align-items: flex-end;
  gap: 24px; flex-wrap: wrap; padding-bottom: 22px;
  border-bottom: 1px solid var(--line); margin-bottom: 26px;
}
.rep-back {
  font-family: var(--font-mono); font-size: 11.5px; letter-spacing: .06em;
  color: var(--text-2);
}
.rep-back:hover { color: var(--platinum-hi); }
.rep-meta {
  font-family: var(--font-mono); font-size: 12px; color: var(--text-2);
  margin: 8px 0 0; display: flex; gap: 10px; flex-wrap: wrap; align-items: center;
  font-variant-numeric: tabular-nums;
}
.rep-meta .pin { color: var(--text); font-weight: 500; }
.rep-meta .sep { color: var(--line); }

.chart-controls {
  display: flex; gap: 16px; align-items: flex-end; flex-wrap: wrap;
  margin: 4px 0 14px; padding: 16px 18px;
  background: var(--surface); border: 1px solid var(--line); border-radius: 12px;
}
.chart-controls label {
  display: grid; gap: 6px;
  font-family: var(--font-mono); font-size: 10px; letter-spacing: .14em;
  text-transform: uppercase; color: var(--text-3);
}
.chart-controls select {
  font-family: var(--font-body); font-size: 14px; color: var(--text);
  padding: 9px 10px; min-width: min(160px, 100%);
  background: var(--canvas); border: 1px solid var(--line); border-radius: 7px;
}
.chart-controls select:focus { outline: none; border-color: var(--platinum); }
.chart-wrap {
  background: var(--surface); background-image: var(--facet);
  border: 1px solid var(--line); border-radius: 12px;
  padding: 16px 18px; margin-bottom: 24px;
}
#chart { max-height: 230px; }

/* ============================================================
   Tabulator → tema Miniprecios
   ============================================================ */
#tabla { margin-top: 6px; }
.tabulator {
  background: var(--surface); border: 1px solid var(--line);
  border-radius: 12px; font-family: var(--font-body); font-size: 13.5px;
  color: var(--text); overflow: hidden;
}
.tabulator .tabulator-header {
  background: var(--surface-2); border-bottom: 1px solid var(--line-hard);
  font-family: var(--font-mono); color: var(--text-2);
}
.tabulator .tabulator-header .tabulator-col {
  background: transparent; border-right: 1px solid var(--line-soft);
}
.tabulator .tabulator-header .tabulator-col .tabulator-col-title {
  font-size: 10px; font-weight: 500; text-transform: uppercase;
  letter-spacing: .12em; color: var(--text-3); padding: 11px 10px;
}
.tabulator .tabulator-header .tabulator-col.tabulator-sortable[aria-sort="ascending"] .tabulator-col-title,
.tabulator .tabulator-header .tabulator-col.tabulator-sortable[aria-sort="descending"] .tabulator-col-title {
  color: var(--platinum);
}
.tabulator .tabulator-row {
  background: transparent; border-bottom: 1px solid var(--line-soft);
  color: var(--text);
}
.tabulator .tabulator-row.tabulator-row-even { background: color-mix(in srgb, var(--surface-2) 55%, transparent); }
.tabulator .tabulator-row:hover { background: var(--surface-3) !important; }
.tabulator .tabulator-row .tabulator-cell {
  border-right: 1px solid var(--line-soft); padding: 9px 10px;
  font-variant-numeric: tabular-nums;
}
.tabulator .tabulator-footer {
  background: var(--surface-2); border-top: 1px solid var(--line);
  font-family: var(--font-mono); font-size: 11.5px; color: var(--text-2);
}
.tabulator .tabulator-footer .tabulator-page {
  background: var(--surface-3); border: 1px solid var(--line); border-radius: 5px;
  color: var(--text-2); font-family: var(--font-mono);
}
.tabulator .tabulator-footer .tabulator-page.active {
  background: var(--platinum); color: var(--void); border-color: var(--platinum);
}
/* Fila de totales (columnCalcs). Tabulator la pinta #f3f3f3 con
   !important, asi que aqui no basta con ser mas especifico: es el unico
   punto del tema donde hay que responder con !important. Se cubren las
   dos posiciones (arriba y abajo) y las tres capas del bloque, porque
   el calcs-holder trae su propia tabla, fuera del tableholder. */
.tabulator .tabulator-calcs-holder,
.tabulator .tabulator-footer .tabulator-calcs-holder,
.tabulator .tabulator-header .tabulator-calcs-holder,
.tabulator .tabulator-calcs-holder .tabulator-table,
.tabulator .tabulator-calcs-holder .tabulator-row,
.tabulator .tabulator-row.tabulator-calcs,
.tabulator .tabulator-row.tabulator-calcs.tabulator-calcs-bottom,
.tabulator .tabulator-row.tabulator-calcs.tabulator-calcs-top {
  background-color: var(--surface-2) !important;
  color: var(--text) !important;
  font-weight: 600;
}
.tabulator .tabulator-row.tabulator-calcs .tabulator-cell {
  background-color: transparent !important;
  color: var(--text) !important;
  border-right-color: var(--line-soft);
}

.tabulator .tabulator-placeholder,
.tabulator .tabulator-placeholder .tabulator-placeholder-contents {
  color: var(--text-3); background: transparent;
}

/* Piezas que Tabulator pinta de blanco por su cuenta.
   OJO con la especificidad: Tabulator declara el fondo en selectores
   anidados como `.tabulator .tabulator-tableholder .tabulator-table`
   (0,3,0). Un `.tabulator .tabulator-table` (0,2,0) pierde aunque
   cargue despues, y la tabla queda blanca con texto blanco encima.
   Estos selectores igualan la anidacion de su hoja a proposito. */
.tabulator .tabulator-tableholder,
.tabulator .tabulator-tableholder .tabulator-table,
.tabulator .tabulator-header .tabulator-headers,
.tabulator .tabulator-header-filter,
.tabulator .tabulator-frozen {
  background-color: transparent; color: var(--text);
}
.tabulator .tabulator-tableholder .tabulator-table .tabulator-row {
  background-color: transparent; color: var(--text);
}
/* La zebra y el hover se re-declaran con la misma anidacion, si no la
   regla de arriba (mas especifica) las borra. */
.tabulator .tabulator-tableholder .tabulator-table .tabulator-row.tabulator-row-even {
  background-color: var(--surface-2);
}
.tabulator .tabulator-tableholder .tabulator-table .tabulator-row:hover {
  background-color: var(--surface-3);
}
.tabulator .tabulator-row.tabulator-selectable:hover { background: var(--surface-3); }
.tabulator .tabulator-row.tabulator-selected { background: var(--surface-3) !important; }
.tabulator .tabulator-col-resize-handle { background: transparent; }
.tabulator .tabulator-header .tabulator-col.tabulator-sortable:hover {
  background-color: var(--surface-3);
}
/* Controles internos: filtros de columna, editores y menus emergentes */
.tabulator input, .tabulator select, .tabulator textarea {
  background: var(--canvas); color: var(--text);
  border: 1px solid var(--line); border-radius: 5px;
}
.tabulator-menu, .tabulator-popup-container, .tabulator-edit-list {
  background: var(--paper); color: var(--text);
  border: 1px solid var(--line); border-radius: 10px; box-shadow: var(--shadow);
}
.tabulator-menu .tabulator-menu-item:hover,
.tabulator-edit-list .tabulator-edit-list-item:hover,
.tabulator-edit-list .tabulator-edit-list-item.active {
  background: var(--surface-2); color: var(--text);
}
/* Las flechas de orden vienen en gris oscuro: invisibles sobre negro */
.tabulator .tabulator-col-sorter .tabulator-arrow {
  border-bottom-color: var(--text-3) !important;
}
.tabulator .tabulator-col[aria-sort="ascending"] .tabulator-arrow,
.tabulator .tabulator-col[aria-sort="descending"] .tabulator-arrow {
  border-bottom-color: var(--platinum) !important;
  border-top-color: var(--platinum) !important;
}

/* ============================================================
   Estado vacío
   ============================================================ */
.empty {
  margin-top: 60px; text-align: center; color: var(--text-2);
  border: 1px dashed var(--line); border-radius: 12px; padding: 40px 24px;
}
.empty .glyph {
  font-family: var(--font-display); font-size: 44px; color: var(--line);
  display: block; margin-bottom: 10px; font-weight: 300;
}
/* Estado de error: el color no va solo, siempre lleva icono y texto. */
.empty.alerta {
  border-style: solid; border-color: color-mix(in srgb, var(--mp-red) 50%, transparent);
  background: var(--danger-bg); color: var(--danger-ink);
  font-family: var(--font-mono); font-size: 12.5px; padding: 26px 24px;
}
.empty .glyph-svg {
  display: block; width: 30px; height: 30px; margin: 0 auto 12px;
  stroke: currentColor;
}
.aviso-ok {
  display: flex; align-items: center; gap: 9px;
  font-family: var(--font-mono); font-size: 12.5px; color: var(--text-2);
}
.aviso-ok svg { width: 16px; height: 16px; flex-shrink: 0; color: var(--ok); }

/* ============================================================
   Índice por empresa
   ============================================================ */
.empresa {
  display: flex; align-items: baseline; gap: 10px;
  padding: 9px 12px; margin: 3px 0; border-radius: 8px;
  color: var(--text-2); transition: background .15s, color .15s;
}
.empresa:hover { background: var(--surface-2); color: var(--text); text-decoration: none; }
.empresa.activa { background: var(--surface-3); color: var(--text); }
.empresa-nom {
  font-family: var(--font-display); font-weight: 500; font-size: 14px;
  letter-spacing: -.01em; white-space: nowrap;
}
.empresa.activa .empresa-nom { color: var(--platinum-hi); }
.empresa .leader {
  flex: 1; align-self: stretch; min-width: 14px;
  border-bottom: 1px dotted var(--line); transform: translateY(-4px);
}
.empresa.activa .leader { border-bottom-color: var(--platinum-lo); }
.empresa .badge {
  font-family: var(--font-mono); font-size: 11px; color: var(--text-3);
  font-variant-numeric: tabular-nums;
}
.empresa.activa .badge { color: var(--platinum); }

/* ============================================================
   Navegación masthead
   ============================================================ */
.masthead-nav { display: flex; gap: 2px; align-items: center; }
.nav-link {
  font-family: var(--font-mono); font-size: 11.5px; letter-spacing: .06em;
  color: var(--text-2); padding: 6px 12px; border-radius: 7px;
  transition: background .14s, color .14s;
  position: relative;
}
.nav-link:hover { background: var(--surface-2); color: var(--text); }
/* Indicador de posición: pastilla de platino. Va rellena y no como filo
   de luz en el borde inferior, porque ese filo ya es la firma del
   header — se tapaban entre si. */
.nav-link.activo {
  background: var(--platinum); color: var(--on-brand); font-weight: 600;
}
@media (max-width: 899.98px) { .masthead-nav { display: none; } }

/* ============================================================
   Dashboard
   ============================================================ */
.dash-head {
  display: flex; justify-content: space-between; align-items: flex-end;
  gap: 20px; flex-wrap: wrap; padding-bottom: 18px;
  border-bottom: 1px solid var(--line); margin-bottom: 26px;
}
.dash-section-title {
  font-family: var(--font-mono); font-size: 10px; font-weight: 500;
  text-transform: uppercase; letter-spacing: .2em; color: var(--text-3);
  margin: 36px 0 14px; padding-bottom: 8px; border-bottom: 1px solid var(--line-soft);
}
.kpi-grid {
  display: grid; gap: 14px;
  grid-template-columns: repeat(auto-fill, minmax(212px, 1fr));
}
.kpi-card {
  background: var(--surface); background-image: var(--facet);
  border: 1px solid var(--line);
  border-radius: 12px; padding: 16px 18px; animation: fade-up .45s both;
  transition: border-color .16s;
}
.kpi-card:hover { border-color: var(--line-hard); box-shadow: var(--shadow-sm); }
/* El total lleva la firma de marca en el filo superior: es la unica
   card que la usa, y por eso se lee como "la cifra" sin necesidad de
   ser mas grande que las demas. */
.kpi-card.kpi-total {
  position: relative; overflow: hidden;
  background: var(--paper);
  background-image: linear-gradient(160deg, var(--brand-tint), transparent 62%);
  border-color: var(--line-hard);
  box-shadow: var(--shadow-sm);
}
.kpi-card.kpi-total::before {
  content: ""; position: absolute; left: 0; right: 0; top: 0; height: 3px;
  background: var(--band);
}
.kpi-card .kpi-label {
  font-family: var(--font-mono); font-size: 9.5px; letter-spacing: .18em;
  text-transform: uppercase; color: var(--text-3); margin: 0 0 9px;
  display: flex; align-items: center; gap: 7px;
}
.kpi-card.kpi-total .kpi-label { color: var(--text-3); }
.kpi-card .kpi-value {
  font-family: var(--font-mono); font-variant-numeric: tabular-nums;
  font-size: 21px; font-weight: 500; color: var(--text); line-height: 1.1;
  letter-spacing: -.02em;
  font-size: clamp(18px, 1.2vw + 14px, 22px);
  overflow-wrap: anywhere;
}
.kpi-card.kpi-total .kpi-value { color: var(--brand-hi); }
.kpi-card .kpi-row {
  display: flex; justify-content: space-between; gap: 4px 8px; flex-wrap: wrap;
  font-family: var(--font-mono); font-size: 11.5px; color: var(--text-2);
  margin-top: 6px; font-variant-numeric: tabular-nums;
}
.kpi-card .kpi-row span:first-child { color: var(--text-3); white-space: nowrap; }
.kpi-card .kpi-row span:last-child { white-space: nowrap; }
.kpi-card .kpi-sub {
  font-family: var(--font-mono); font-size: 10.5px; color: var(--text-3);
  margin-top: 10px; padding-top: 9px; border-top: 1px solid var(--line-soft);
  font-variant-numeric: tabular-nums;
}
.dash-charts {
  display: grid; gap: 18px; grid-template-columns: repeat(auto-fit, minmax(min(340px, 100%), 1fr));
}
.dash-charts .chart-wrap { margin-bottom: 0; }
.dash-charts h3 {
  font-family: var(--font-mono); font-size: 10px; font-weight: 500;
  text-transform: uppercase; letter-spacing: .16em; color: var(--text-3);
  margin: 0 0 14px;
}
.dash-charts canvas { max-height: 240px; }
.chip {
  font-family: var(--font-mono); font-size: 10px; letter-spacing: .05em;
  color: var(--text-2); border: 1px solid var(--line); border-radius: 4px;
  padding: 2px 7px; white-space: nowrap; background: var(--surface-2);
}
.chip.warn { color: var(--warn); border-color: color-mix(in srgb, var(--warn-fill) 60%, transparent);
  background: var(--warn-bg); }
.chip.run { color: var(--brand); border-color: color-mix(in srgb, var(--mp-blue) 45%, transparent);
  background: color-mix(in srgb, var(--mp-blue) 10%, transparent); }
.cob-tipos { display: flex; gap: 5px; flex-wrap: wrap; }

/* Barra de progreso de corridas en curso */
.run-cell { display: flex; align-items: center; gap: 8px; }
.pbar {
  position: relative; width: min(120px, 30vw); height: 5px; overflow: hidden;
  background: var(--surface-3); border-radius: 100px;
}
.pbar-fill {
  display: block; height: 100%; width: 0; border-radius: 100px;
  background: var(--brand); transition: width .3s linear;
  background-image: linear-gradient(90deg,
    transparent, rgba(255,255,255,.85), transparent);
  background-size: 40px 100%; background-repeat: no-repeat;
  animation: pbar-sweep 1.1s linear infinite;
}
@keyframes pbar-sweep {
  from { background-position: -40px 0; }
  to   { background-position: 160px 0; }
}
.pbar-txt { font-size: 10px; color: var(--text-3); white-space: nowrap;
  font-family: var(--font-mono); font-variant-numeric: tabular-nums; }

/* Badge de fallos en el nav */
.notif-badge {
  display: inline-block; min-width: 16px; margin-left: 5px; padding: 0 4px;
  font-family: var(--font-mono); font-size: 10px; line-height: 16px;
  text-align: center; color: var(--void); background: var(--danger);
  border-radius: 999px; vertical-align: middle; font-weight: 600;
}

/* ----- Controles del dashboard ----- */
.dash-actions { display: flex; gap: 8px; flex-wrap: wrap; }
.dash-controls {
  display: flex; flex-wrap: wrap; align-items: center; gap: 14px 22px;
  margin: 6px 0 24px; padding-bottom: 16px; border-bottom: 1px solid var(--line-soft);
}
.ctrl-group { display: flex; align-items: center; gap: 10px; flex-wrap: wrap; }
.ctrl-label {
  font-family: var(--font-mono); font-size: 9.5px; letter-spacing: .2em;
  text-transform: uppercase; color: var(--text-3);
}
.seg {
  display: inline-flex; flex-wrap: wrap; border: 1px solid var(--line); border-radius: 8px;
  background: var(--surface); max-width: 100%;
}
.seg-btn:first-child { border-radius: 7px 0 0 7px; }
.seg-btn:last-child { border-radius: 0 7px 7px 0; }
.seg-btn {
  font-family: var(--font-mono); font-size: 11.5px; letter-spacing: .04em;
  padding: 7px 13px; border: 0; border-right: 1px solid var(--line);
  background: transparent; color: var(--text-2); cursor: pointer;
  transition: background .14s, color .14s;
}
.seg-btn:last-child { border-right: 0; }
.seg-btn:hover { background: var(--surface-2); color: var(--text); }
.seg-btn[aria-pressed="true"] { background: var(--platinum); color: var(--void); font-weight: 600; }
.pills { display: flex; gap: 6px; flex-wrap: wrap; }
.pill {
  font-family: var(--font-mono); font-size: 11px; letter-spacing: .04em;
  padding: 6px 13px; border: 1px solid var(--line); border-radius: 100px;
  background: var(--surface); color: var(--text-2); cursor: pointer;
  transition: background .14s, color .14s, border-color .14s;
}
.pill:hover { background: var(--surface-2); color: var(--text); border-color: var(--platinum-lo); }
.pill.activa {
  background: var(--platinum); color: var(--void);
  border-color: var(--platinum); font-weight: 600;
}
.seg-btn:focus-visible, .pill:focus-visible,
a:focus-visible, .btn:focus-visible, .btn-sm:focus-visible, .nav-link:focus-visible,
input:focus-visible, select:focus-visible, button:focus-visible {
  outline: 2px solid var(--platinum-hi); outline-offset: 2px;
}
/* Áreas táctiles: ver seccion "Responsive / componentes compartidos" al final. */

/* Skeleton de carga */
.dash-skel { display: grid; gap: 14px; margin-top: 8px; }
.skel-row {
  height: 130px; border-radius: 12px; border: 1px solid var(--line-soft);
  background: linear-gradient(90deg, var(--surface), var(--surface-3), var(--surface));
  background-size: 200% 100%; animation: shimmer 1.3s linear infinite;
}
@keyframes shimmer { from { background-position: 200% 0; } to { background-position: -200% 0; } }

/* ============================================================
   Vista Ejecutivo
   Lo que crece va en tinta clara; lo que cae, en rojo ("estar en
   rojo"). Es la única concesión de color de la paleta, y significa
   algo. Nunca va sola: siempre lleva signo +/− en el texto.
   ============================================================ */
.delta { font-family: var(--font-mono); font-variant-numeric: tabular-nums; }
.delta.up   { color: var(--ok); }
.delta.down { color: var(--danger-ink); }
.delta.nulo { color: var(--text-3); }
.kpi-card.kpi-total .delta.up { color: var(--ok); }
.kpi-card.kpi-total .delta.down { color: var(--danger-ink); }

/* Banda de confiabilidad del dato: condiciona la lectura de cada
   número de la pantalla, por eso va arriba de todo. */
.salud-band {
  display: flex; flex-wrap: wrap; align-items: baseline; gap: 8px 14px;
  border: 1px solid color-mix(in srgb, var(--mp-red) 45%, transparent);
  border-left-width: 2px; border-radius: 10px;
  background: var(--danger-bg); padding: 12px 15px; margin: 0 0 22px;
  font-family: var(--font-mono); font-size: 11.5px; color: var(--text);
}
.salud-band.aviso {
  border-color: color-mix(in srgb, var(--warn-fill) 60%, transparent);
  background: var(--warn-bg);
}
.salud-band .salud-tit {
  letter-spacing: .16em; text-transform: uppercase; font-size: 9.5px;
  color: var(--text-3);
}
.salud-band .salud-item { white-space: nowrap; }
.salud-band .salud-item b { font-weight: 600; color: var(--text); }

/* Nota de alcance: "YoY sobre 4 de 7 cadenas". Sin esto un director
   lee una caída del 40% que no existe. */
.nota-alcance {
  font-family: var(--font-mono); font-size: 10.5px; color: var(--text-3);
  margin: -12px 0 18px;
}
.dash-section-title + .nota-alcance { margin-top: -8px; }

.kpi-card .kpi-foot {
  font-family: var(--font-mono); font-size: 10px; color: var(--text-3);
  margin-top: 4px;
}
.kpi-card.kpi-total .kpi-foot { color: var(--text-3); }

/* Dos tablas cortas lado a lado */
.par-tablas { display: grid; grid-template-columns: 1fr 1fr; gap: 22px; }
.par-tablas h3 {
  font-family: var(--font-mono); font-size: 10px; letter-spacing: .16em;
  text-transform: uppercase; color: var(--text-3); margin: 0 0 8px; font-weight: 500;
}
@media (max-width: 900px) { .par-tablas { grid-template-columns: 1fr; } }

.lista td .sub {
  display: block; font-size: 10.5px; color: var(--text-3);
  font-family: var(--font-mono);
}

/* ============================================================
   Impresión / PDF — la marca es negra en pantalla, no en papel: un
   dashboard exportado no debe gastar un cartucho por hoja. Aqui se
   invierten los tokens a claro, se quitan sombras, faceta y grano, y
   se esconde el cromo de navegacion.
   ============================================================ */
@media print {
  :root {
    color-scheme: light;
    --canvas: #ffffff; --paper: #ffffff;
    --surface-2: #f3f3f4; --surface-3: #e9e9eb;
    --line: #bcbcc2; --line-soft: #dcdce0; --line-hard: #8e8e96;
    --text: #101012; --text-2: #3c3c42; --text-3: #58585f;
    --brand: #101012; --brand-hi: #000000; --brand-lo: #58585f;
    --brand-tint: #ffffff;
    --on-brand: #ffffff;
    --danger: #a13224; --danger-ink: #a13224;
    --shadow: none; --shadow-sm: none; --facet: none;
    --band: #101012;
  }
  .masthead, .sidebar, .dash-controls, .dash-actions, .grain,
  .filtros-side { display: none !important; }
  /* Sin panel, el reporte ocupa la hoja completa. */
  .filtros-layout { display: block; }
  .content.full { padding: 0; }
  .chart-wrap, .kpi-card, .lista tr { break-inside: avoid; }
  body { background: #fff !important; background-image: none; }
  .kpi-card.kpi-total { box-shadow: none; border-color: #101012; }
}

/* ============================================================
   Animación de entrada (stagger)
   ============================================================ */
@keyframes fade-up {
  from { opacity: 0; transform: translateY(8px); }
  to   { opacity: 1; transform: translateY(0); }
}
.meses li:nth-child(1){animation-delay:.03s}.meses li:nth-child(2){animation-delay:.06s}
.meses li:nth-child(3){animation-delay:.09s}.meses li:nth-child(4){animation-delay:.12s}
.meses li:nth-child(5){animation-delay:.15s}.meses li:nth-child(6){animation-delay:.18s}
.meses li:nth-child(7){animation-delay:.21s}.meses li:nth-child(8){animation-delay:.24s}
.meses li:nth-child(9){animation-delay:.27s}.meses li:nth-child(10){animation-delay:.30s}
.meses li:nth-child(11){animation-delay:.33s}.meses li:nth-child(12){animation-delay:.36s}
.lista tbody tr:nth-child(1){animation-delay:.04s}.lista tbody tr:nth-child(2){animation-delay:.08s}
.lista tbody tr:nth-child(3){animation-delay:.12s}.lista tbody tr:nth-child(4){animation-delay:.16s}
.lista tbody tr:nth-child(5){animation-delay:.20s}.lista tbody tr:nth-child(6){animation-delay:.24s}
.lista tbody tr:nth-child(7){animation-delay:.28s}.lista tbody tr:nth-child(8){animation-delay:.32s}
.lista tbody tr:nth-child(9){animation-delay:.36s}.lista tbody tr:nth-child(10){animation-delay:.40s}

@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after { animation: none !important; transition: none !important; }
}

/* Controles nativos sueltos (subida de archivos, selects fuera de los
   paneles ya tematizados). Sin esto el navegador los pinta con su tema
   claro y quedan como parches blancos sobre el negro. */
input[type="file"] {
  font-family: var(--font-mono); font-size: 12px; color: var(--text-2);
  background: var(--surface); border: 1px solid var(--line);
  border-radius: 7px; padding: 6px 8px; max-width: 100%;
}
input[type="file"]::file-selector-button {
  font-family: var(--font-mono); font-size: 11px; letter-spacing: .06em;
  text-transform: uppercase; cursor: pointer;
  color: var(--text); background: var(--surface-2);
  border: 1px solid var(--line); border-radius: 5px;
  padding: 5px 11px; margin-right: 10px;
  transition: background .14s, border-color .14s;
}
input[type="file"]::file-selector-button:hover {
  background: var(--surface-2); border-color: var(--line-hard);
}
select { color-scheme: light; }

/* ============================================================
   Intro de marca (overlay Three.js + GSAP)
   El canvas hace el diamante y las esquirlas; el logotipo es DOM
   con gradiente CSS para que la tipografia quede nitida en
   cualquier densidad de pantalla.
   ============================================================ */

/* Mientras la intro esta viva se congela el scroll del documento:
   la clase la pone un script sincrono en <head>, antes del primer
   pintado, para que no se alcance a ver el portal por debajo. */
html.bd-intro-activa, html.bd-intro-activa body { overflow: hidden; }

/* Oculto por defecto: solo existe si el script de <head> activo la
   clase. Sin JS (o con reduced-motion) el overlay nunca se pinta. */
#bd-intro { display: none; }
html.bd-intro-activa #bd-intro {
  position: fixed; inset: 0; z-index: 10000;
  background: var(--void);
  display: grid; place-items: center;
  cursor: pointer;
  /* Vineta: el video no tiene el negro plano, tiene caida a los bordes */
  background-image: radial-gradient(62% 62% at 50% 46%,
    rgba(201,205,212,.055), transparent 70%);
  transition: opacity .4s ease, transform .4s ease;
}
#bd-intro.bd-fuera { opacity: 0; transform: scale(1.04); pointer-events: none; }

#bd-canvas { position: absolute; inset: 0; width: 100%; height: 100%; display: block; }

.bd-logo {
  position: relative; z-index: 1; text-align: center;
  opacity: 0; will-change: transform, opacity, filter;
  padding: 0 24px;
}
.bd-nombre {
  margin: 0; font-family: "Playfair Display", Georgia, serif;
  font-weight: 700; font-size: clamp(30px, 7.2vw, 74px);
  letter-spacing: .04em; line-height: 1; white-space: nowrap;
  /* Gradiente metalico vertical: claro en el centro optico, gris en
     los extremos. Es lo que hace que se lea como plata y no como
     texto gris. */
  background: linear-gradient(180deg,
    #7c828c 0%, #ffffff 34%, #e6eaf0 50%, #9aa0aa 72%, #5e646d 100%);
  -webkit-background-clip: text; background-clip: text;
  color: transparent; -webkit-text-fill-color: transparent;
  filter: drop-shadow(0 2px 18px rgba(201,205,212,.28));
}
.bd-tagline {
  display: block; margin-top: 14px;
  font-family: var(--font-body); font-weight: 500;
  font-size: clamp(8px, 1.5vw, 13px);
  letter-spacing: .42em; text-transform: uppercase;
  color: var(--text-2); white-space: nowrap;
  /* el tracking se anima, asi que el texto no debe reflowear la caja */
  text-indent: .42em;
}
/* Reflejo especular en el piso, como el video. Se apoya en un mask
   para que se desvanezca en vez de cortarse en seco. */
.bd-reflejo {
  margin-top: 4px; transform: scaleY(-1); opacity: .10;
  filter: blur(4px);
  -webkit-mask-image: linear-gradient(180deg, transparent 4%, #000 92%);
  mask-image: linear-gradient(180deg, transparent 4%, #000 92%);
  pointer-events: none; user-select: none;
}
.bd-saltar {
  position: absolute; z-index: 2; bottom: 26px; left: 50%;
  transform: translateX(-50%);
  font-family: var(--font-mono); font-size: 10px; letter-spacing: .22em;
  text-transform: uppercase; color: var(--text-3);
  opacity: 0; animation: bd-saltar-in .5s .9s forwards;
}
@keyframes bd-saltar-in { to { opacity: .75; } }

@media (max-width: 720px) {
  .bd-reflejo { display: none; }        /* en movil no cabe y roba altura */
  .bd-tagline { letter-spacing: .3em; text-indent: .3em; }
}

/* La intro es decorativa: si el usuario pidio menos movimiento, no
   existe. El script de <head> ni siquiera la activa, pero por si el
   ajuste cambia a media carga, aqui queda muerta. */
@media (prefers-reduced-motion: reduce) {
  #bd-intro { display: none !important; }
  html.bd-intro-activa, html.bd-intro-activa body { overflow: auto; }
}

/* ============================================================
   Responsive / componentes compartidos
   Reglas mobile-first que todas las paginas comparten. Los patrones
   nacieron en tablero (.tb-scroll/.tb-tabs), promotor (.pr-in) y el
   login (inputs de 16px); aqui quedan con nombre generico. Los nombres
   viejos siguen como alias mientras las plantillas migran.
   ============================================================ */

/* ============================================================
   Filtros en panel lateral (cubo, tablero, dashboard)
   Los filtros viven en una columna fija a la izquierda y el reporte a la
   derecha, como los slicers del tablero de Excel del cliente: cada
   dimensión se ve completa, sin abrir un menú por filtro.
   ============================================================ */
.filtros-layout {
  display: grid; grid-template-columns: 15.5rem minmax(0, 1fr);
  gap: 20px; align-items: start; margin-top: 4px;
}
.filtros-main { min-width: 0; }
/* .tabs sangra a los lados con margen negativo para pegarse al filo de la
   página. Dentro de la columna del reporte eso la mete debajo del panel de
   filtros: aquí la tira de pestañas empieza donde empieza su columna. */
.filtros-main > .tabs { margin-left: 0; margin-right: 0; padding-left: 0; padding-right: 0; }
/* Pegajoso: el reporte se lee scrolleando y los filtros no se van con él. */
.filtros-side {
  position: sticky; top: 76px;               /* alto del masthead + aire */
  max-height: calc(100dvh - 92px); overflow-y: auto;
  display: grid; gap: 12px; padding: 14px;
  background: var(--surface); border: 1px solid var(--line); border-radius: 12px;
  background-image: var(--facet);
}
/* En teléfono la columna pasa arriba del reporte. Seis slicers abiertos
   serían metro y medio de scroll antes de ver la tabla, así que el panel
   entero se vuelve una caja con su propio scroll. */
@media (max-width: 899.98px) {
  .filtros-layout { grid-template-columns: 1fr; }
  .filtros-side { position: static; max-height: 60dvh; }
  .sl-l { max-height: 9rem; }
}

/* ----- Controles sueltos del panel (rango, unidad, acciones) ----- */
.filtros-side-top { display: grid; gap: 12px; }
.filtros-side .campo {
  display: grid; gap: 6px;
  font-family: var(--font-mono); font-size: 10px; letter-spacing: .14em;
  text-transform: uppercase; color: var(--text-3);
}
.filtros-side select,
.filtros-side input[type="number"],
.filtros-side input[type="text"] {
  font-family: var(--font-body); font-size: 14px; color: var(--text);
  padding: 9px 10px; width: 100%; max-width: 100%;
  background: var(--canvas); border: 1px solid var(--line); border-radius: 7px;
}
.filtros-side input[type="number"] {
  font-family: var(--font-mono); font-variant-numeric: tabular-nums;
}
.filtros-side select:focus, .filtros-side input:focus {
  outline: none; border-color: var(--platinum);
  box-shadow: 0 0 0 3px color-mix(in srgb, var(--platinum) 14%, transparent);
}
.filtros-side select option { background: var(--surface-3); color: var(--text); }
.filtros-side .seg { width: 100%; flex-wrap: wrap; }
.filtros-side .seg-btn { flex: 1 1 0; justify-content: center; }
.filtros-side .acciones { display: grid; gap: 8px; }
.filtros-side .acciones .btn { justify-content: center; }
.filtros-side .pills { display: flex; flex-wrap: wrap; gap: 5px; }

/* ----- Slicer: una dimensión con todos sus valores a la vista ----- */
.filtros-dims { display: grid; gap: 10px; }
/* En el dashboard los slicers van dentro del sidebar del portal, arriba del
   índice de periodos: sin este aire el «Índice / Periodos» queda pegado. */
.sidebar .filtros-dims + h2 { margin-top: 22px; }
.sl {
  border: 1px solid var(--line); border-radius: 8px;
  background: var(--canvas); overflow: hidden;
}
.sl.filtrado { border-color: var(--platinum-lo); }
.sl-h {
  display: flex; align-items: center; justify-content: space-between; gap: 6px;
  padding: 7px 9px; background: var(--surface-2);
  border-bottom: 1px solid var(--line);
}
.sl.filtrado .sl-h { background: var(--surface-3); }
.sl-t {
  display: flex; align-items: center; gap: 7px;
  font-family: var(--font-mono); font-size: 10.5px; letter-spacing: .1em;
  text-transform: uppercase; color: var(--text-2);
}
.sl.filtrado .sl-t { color: var(--text); }
.sl-n {
  font-size: 10px; min-width: 16px; padding: 0 5px; line-height: 16px;
  text-align: center; border-radius: 999px;
  background: var(--platinum); color: var(--on-brand); font-weight: 600;
  font-variant-numeric: tabular-nums;
}
/* Soltar el filtro de esa dimensión. Es <button> en el cubo (filtra en el
   navegador) y <a> en tablero (filtra por URL): mismo aspecto. */
.sl-x {
  background: none; border: 0; padding: 0 2px; cursor: pointer;
  font-size: 16px; line-height: 1; color: var(--text-3); text-decoration: none;
}
.sl-x:hover { color: var(--text); text-decoration: none; }
.sl-q {
  display: block; width: calc(100% - 16px); margin: 8px 8px 2px; padding: 6px 8px;
  font-family: var(--font-body); font-size: 13px; color: var(--text);
  background: var(--paper); border: 1px solid var(--line); border-radius: 6px;
}
.sl-q::placeholder { color: var(--text-3); }
.sl-q:focus { outline: none; border-color: var(--platinum); }
/* Alto fijo: media docena de dimensiones abiertas a la vez tienen que caber
   en la columna sin empujar el resto fuera de la pantalla. */
.sl-l { max-height: 11.5rem; overflow-y: auto; padding: 5px; }
.sl-i {
  display: block; width: 100%; text-align: left; cursor: pointer;
  font: inherit; font-size: 12.5px; line-height: 1.35;
  padding: 5px 7px; margin: 1px 0; border-radius: 5px;
  background: transparent; border: 1px solid transparent; color: var(--text-2);
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
.sl-i:hover { background: var(--surface-2); color: var(--text); text-decoration: none; }
/* El valor puesto. Se marca por clase (cubo y tablero, que repintan la lista)
   y por aria-pressed (dashboard, donde el script solo mueve el atributo): un
   solo aspecto, se llegue por donde se llegue. */
.sl-i.on, .sl-i[aria-pressed="true"] {
  background: color-mix(in srgb, var(--platinum) 18%, transparent);
  border-color: var(--platinum-lo); color: var(--text); font-weight: 500;
}
.sl-vacio {
  padding: 10px; font-family: var(--font-mono); font-size: 11px;
  color: var(--text-3); text-align: center;
}

/* ----- Iconos SVG inline (macro icon() en _icons.html) ----- */
.ico { width: 1.15em; height: 1.15em; flex-shrink: 0; vertical-align: -.2em; }
.btn .ico, .btn-sm .ico { width: 1.25em; height: 1.25em; }

/* ----- Areas tactiles ≥44px e inputs ≥16px (iOS no hace zoom) ----- */
@media (pointer: coarse), (max-width: 639.98px) {
  .btn, .btn-sm, .btn-ghost, .nav-link, .seg-btn, .pill, .cubo-tab, .tabs a, .tabs button,
  .sl-x, .pr-btn-mini, .sidebar .meses a, .sidebar .dias a,
  .rep-back, .ver-mes, button.chip, .tabulator-responsive-collapse-toggle,
  .tabulator-page, .tabulator-header-filter input {
    min-height: var(--tap); display: inline-flex; align-items: center;
  }
  .btn-sm { padding-top: 6px; padding-bottom: 6px; }
  select, input:not([type="checkbox"]):not([type="radio"]):not([type="file"]), textarea, .select-ctrl {
    min-height: var(--tap);
  }
  .sidebar .meses a, .sidebar .dias a { display: flex; }
}
@media (max-width: 639.98px) {
  /* !important a proposito: gana a cualquier tamano por pagina; en iOS un
     campo menor a 16px hace zoom al enfocar. */
  input, select, textarea, .select-ctrl, .sl-q, .chart-controls select,
  .cubo-side select, .cubo-side input, input[type="file"] { font-size: 16px !important; }
  .ctrl-group { gap: 8px; }
  .ctrl-group > input, .ctrl-group > select { flex: 1 1 140px; min-width: 0; }
  .dash-head { gap: 12px; padding-bottom: 14px; margin-bottom: 18px; }
  .dash-head > form, .dash-head > .dash-actions { width: 100%; }
  .dash-controls { gap: 10px 14px; margin-bottom: 18px; }
  .dash-controls > .spacer { display: none; }
  .kpi-grid { gap: 10px; grid-template-columns: repeat(auto-fill, minmax(min(212px, 100%), 1fr)); }
  .kpi-card { padding: 14px 15px; }
  .chart-controls { padding: 12px; gap: 10px; }
  .chart-controls label { flex: 1 1 140px; }
  .chart-wrap { padding: 12px; }
  .salud-band .salud-item { white-space: normal; }
  .par-tablas { gap: 14px; }
  .lista td { padding: 10px 10px; }
  .lista thead th { padding: 0 10px 8px; }
  .lista { margin-top: 14px; }
}

/* ----- Formularios: un solo estilo de input (copiado del login) ----- */
:where(.form-field, .pr-in, .pr-alta input, .pr-in-meta,
.form-row input, .form-row select,
input[type="date"], input[type="time"], input[type="number"],
input[type="search"], input[type="text"]):not(.tabulator input):not(.sl-q):not(.card.login input) {
  font-family: var(--font-body); font-size: 15px; color: var(--text);
  background: var(--canvas); border: 1px solid var(--line); border-radius: var(--r-md);
  padding: 9px 12px; min-height: 40px; max-width: 100%;
  transition: border-color .12s, background .12s;
}
:where(input[type="number"], input[type="time"], input[type="date"]):not(.tabulator input) {
  font-family: var(--font-mono); font-variant-numeric: tabular-nums;
}
.form-row select {
  appearance: none; -webkit-appearance: none; padding-right: 32px; cursor: pointer;
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='10' height='6' viewBox='0 0 10 6'%3E%3Cpath d='M1 1l4 4 4-4' fill='none' stroke='%236b7684' stroke-width='1.5'/%3E%3C/svg%3E");
  background-repeat: no-repeat; background-position: right 11px center;
}
.form-field:focus, input:focus-visible, textarea:focus-visible {
  outline: 2px solid var(--platinum-hi); outline-offset: 1px; border-color: var(--platinum);
}
.form-field--num { text-align: right; font-family: var(--font-mono); }
.form-field--full { width: 100%; }
.form-row { display: flex; flex-wrap: wrap; gap: 8px 12px; align-items: flex-end; }
.form-row label { display: flex; flex-wrap: wrap; align-items: center; gap: 4px;
  font-family: var(--font-mono); font-size: 10px; letter-spacing: .14em; text-transform: uppercase;
  color: var(--text-3); flex: 1 1 140px; min-width: 0; }
.form-row label > span { font: inherit; color: var(--danger-ink); }
.form-row label > input, .form-row label > select, .form-row label > textarea {
  flex: 1 1 100%; width: 100%; font-size: 15px; letter-spacing: 0; text-transform: none; }
.form-row .form-actions { flex: 0 0 auto; display: flex; gap: 8px; align-items: center; }
/* Tags flotantes (.field-periodo) necesitan aire arriba cuando la fila envuelve */
.field-periodo { margin-top: 6px; }

/* ----- Titulos de seccion: uno para todas las paginas ----- */
.section-title, .pr-h2, .tb-h2 {
  font-family: var(--font-display); font-weight: 600; font-size: var(--fs-lg);
  letter-spacing: -.015em; margin: 28px 0 8px; color: var(--text);
}
.section-title .muted, .pr-h2 .muted, .tb-h2 .muted, .section-sub {
  font-weight: 400; font-size: 12.5px; color: var(--text-2);
}
.section-head { display: flex; align-items: baseline; gap: 12px; flex-wrap: wrap; margin: 28px 0 8px; }
.section-head .section-title { margin: 0; }
.hint, .tb-nota, .pr-nota {
  max-width: 90ch; margin: 8px 0 0; font-size: 12px; color: var(--text-2);
}
/* Ayuda plegable: reemplaza los title= (invisibles en tactil) */
details.ayuda { margin: 8px 0 0; font-size: 12.5px; color: var(--text-2); max-width: 90ch; }
details.ayuda summary {
  cursor: pointer; display: inline-flex; align-items: center; gap: 6px;
  font-family: var(--font-mono); font-size: 11px; letter-spacing: .06em; text-transform: uppercase;
  color: var(--brand); min-height: 32px; list-style: none;
}
details.ayuda summary::-webkit-details-marker { display: none; }
details.ayuda summary .ico { transition: transform .15s; }
details.ayuda[open] summary .ico { transform: rotate(180deg); }
details.ayuda dl { display: grid; grid-template-columns: max-content 1fr; gap: 4px 14px; margin: 6px 0 0; }
details.ayuda dt { font-weight: 600; color: var(--text); }
details.ayuda dd { margin: 0; }
@media (max-width: 639.98px) { details.ayuda dl { grid-template-columns: 1fr; gap: 2px; } details.ayuda dd { margin-bottom: 6px; } }

/* ----- Tablas: wrapper de scroll horizontal con primera columna fija ----- */
.tabla-scroll, .tb-scroll {
  position: relative; overflow-x: auto; overflow-y: hidden;
  -webkit-overflow-scrolling: touch; overscroll-behavior-x: contain;
  border: 1px solid var(--line); border-radius: var(--r-lg); background: var(--surface);
  /* sombra en el borde derecho mientras haya mas contenido */
  background-image:
    linear-gradient(to right, var(--surface) 30%, transparent),
    linear-gradient(to left, var(--surface) 30%, transparent),
    linear-gradient(to right, rgba(17,19,24,.10), transparent),
    linear-gradient(to left, rgba(17,19,24,.10), transparent);
  background-position: left center, right center, left center, right center;
  background-repeat: no-repeat; background-size: 40px 100%, 40px 100%, 14px 100%, 14px 100%;
  background-attachment: local, local, scroll, scroll;
}
.tabla-scroll > .lista, .tb-scroll > .lista { margin-top: 0; min-width: max-content; width: 100%; }
.tabla-scroll, .tb-scroll { max-width: 100%; min-width: 0; }
/* hijos de grids/flex: sin esto el min-width:auto deja pasar la tabla ancha */
.par-tablas > *, .dash-charts > *, .kpi-grid > *, .content > * { min-width: 0; }
.tabla-scroll .lista td, .tabla-scroll .lista th { white-space: nowrap; }
.tabla-scroll .lista td.wrap, .tabla-scroll .lista .celda-larga { white-space: normal; }
.tabla-scroll--fija1 .lista td:first-child, .tabla-scroll--fija1 .lista th:first-child {
  position: sticky; left: 0; z-index: var(--z-sticky); background: var(--surface);
  box-shadow: 1px 0 0 var(--line);
}
.tabla-scroll--fija1 .lista tbody tr:hover td:first-child,
.tabla-scroll--fija1 .lista tr.tb-total td:first-child,
.tabla-scroll--fija1 .lista tr.pr-total td:first-child { background: var(--surface-2); }
.tabla-scroll .lista tbody tr { animation: none; }
.celda-larga { max-width: min(52ch, 60vw); white-space: normal; overflow-wrap: anywhere; }

/* ----- Tabs: tira horizontal con scroll (unifica .cubo-tab y .tb-tab) ----- */
.tabs {
  display: flex; align-items: stretch; gap: 2px; flex-wrap: nowrap;
  overflow-x: auto; scrollbar-width: none; -webkit-overflow-scrolling: touch;
  scroll-snap-type: x proximity; border-bottom: 1px solid var(--line);
  margin: 18px calc(-1 * var(--gutter)) 14px; padding: 0 var(--gutter);
}
.tabs::-webkit-scrollbar { display: none; }
.tabs a, .tabs button {
  position: relative; display: inline-flex; align-items: center; gap: 6px; flex: 0 0 auto;
  min-height: 40px; padding: 0 14px 8px; margin-bottom: -1px; scroll-snap-align: start;
  color: var(--text-2); font: 500 13px/1 var(--font-body); text-decoration: none;
  background: none; border: 0; border-bottom: 2px solid transparent; border-radius: 6px 6px 0 0;
  cursor: pointer; white-space: nowrap; transition: color .15s, border-color .15s, background .15s;
}
.tabs a:hover, .tabs button:hover { color: var(--text); background: var(--surface-2); }
.tabs a[aria-current="page"], .tabs button[aria-pressed="true"] {
  color: var(--brand-hi); border-bottom-color: var(--brand-hi); font-weight: 600;
}
.tabs a:focus-visible, .tabs button:focus-visible { outline: 2px solid var(--platinum-hi); outline-offset: -2px; }
.tabs .tabs-grp {
  align-self: center; font-family: var(--font-mono); font-size: 10px; letter-spacing: .14em;
  text-transform: uppercase; color: var(--text-3); padding: 0 10px 8px 0; flex: 0 0 auto;
}
.tabs .tabs-sep { margin-left: 14px; padding-left: 14px; border-left: 1px solid var(--line); }
@media (max-width: 639.98px) {
  .tabs .tabs-grp { display: none; }
  .tabs .tabs-sep { margin-left: 6px; padding-left: 6px; }
  .tabs a, .tabs button { min-height: var(--tap); padding: 0 12px 6px; }
}

/* ----- Dataviz en celda ----- */
.heat, .tb-heat { position: relative;
  background-image: linear-gradient(to left, var(--brand-tint) var(--w, 0%), transparent var(--w, 0%));
  background-repeat: no-repeat; }
.bar, .tb-bar { display: inline-flex; align-items: center; gap: 6px; }
.bar i, .tb-bar i { display: inline-block; width: 56px; height: 6px; border-radius: 3px;
  background: var(--surface-2); position: relative; overflow: hidden; }
.bar i::after, .tb-bar i::after { content: ''; position: absolute; inset: 0; width: var(--w, 0%);
  background: var(--brand); border-radius: 3px; }
.dual, .tb-dual { display: flex; flex-direction: column; gap: 2px; width: 100%; }
.dual i, .tb-dual i { display: block; height: 5px; border-radius: 2px; width: var(--w, 0%); min-width: 1px; }
.dual i.act, .tb-dual i.act, .leg.act, .tb-leg.act { background: var(--brand); }
.dual i.ant, .tb-dual i.ant, .leg.ant, .tb-leg.ant { background: var(--text-3); opacity: .55; }
.leg, .tb-leg { display: inline-block; width: 12px; height: 5px; border-radius: 2px; vertical-align: middle; }
.pill-val, .tb-pill { display: inline-block; padding: 1px 7px; border-radius: 99px; border: 1px solid var(--line); font-family: var(--font-mono); }
.pill-val.ok, .tb-pill.ok { color: var(--ok); border-color: color-mix(in srgb, var(--ok) 45%, transparent); }
.pill-val.warn, .tb-pill.warn { color: var(--warn); border-color: color-mix(in srgb, var(--warn) 45%, transparent); }
.vacio, .tb-vacio, .pr-vacio { color: var(--text-3); }
.pos, .tb-pos, .pr-ok { color: var(--ok); }
.neg, .tb-neg, .pr-bajo { color: var(--danger-ink); }
.delta .ico { width: 1em; height: 1em; }

/* ----- Toast (reemplaza alert()) ----- */
.toast-zona { position: fixed; left: 50%; bottom: max(16px, env(safe-area-inset-bottom)); transform: translateX(-50%);
  z-index: var(--z-toast); display: flex; flex-direction: column; gap: 8px; width: min(520px, calc(100vw - 32px)); pointer-events: none; }
.toast { pointer-events: auto; display: flex; align-items: flex-start; gap: 10px;
  background: var(--text); color: var(--paper); padding: 12px 14px; border-radius: var(--r-lg);
  font-size: 13.5px; line-height: 1.4; box-shadow: var(--shadow); animation: fade-up .25s both; }
.toast .ico { margin-top: 2px; }
.toast--error { background: var(--danger-ink); }
.toast--ok { background: var(--ok); }
.toast button { margin-left: auto; background: none; border: 0; color: inherit; cursor: pointer; font: inherit; opacity: .8; min-width: 32px; min-height: 32px; }

/* ----- Masthead movil: hamburguesa + drawer ----- */
.nav-toggle {
  display: none; align-items: center; justify-content: center;
  width: var(--tap); height: var(--tap); margin-left: -8px;
  background: none; border: 0; border-radius: var(--r-md); color: var(--text); cursor: pointer;
}
.nav-toggle .ico { width: 24px; height: 24px; }
.nav-toggle:hover { background: var(--surface-2); }
.masthead-user { max-width: 30vw; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
@media (max-width: 899.98px) {
  .nav-toggle { display: inline-flex; }
  .masthead .masthead-user, .masthead .link-quiet { display: none; }
  .masthead { z-index: var(--z-masthead); }
}
.scrim {
  position: fixed; inset: 0; z-index: var(--z-scrim); background: rgba(17,19,24,.45);
  opacity: 0; transition: opacity .2s; pointer-events: none;
}
.scrim.abierto { opacity: 1; pointer-events: auto; }
.drawer {
  position: fixed; top: 0; bottom: 0; left: 0; z-index: var(--z-drawer);
  width: min(320px, 86vw); background: var(--paper); border-right: 1px solid var(--line);
  box-shadow: var(--shadow); transform: translateX(-102%); transition: transform .22s ease-out;
  display: flex; flex-direction: column; overflow-y: auto; overscroll-behavior: contain;
  padding-bottom: env(safe-area-inset-bottom);
}
.drawer.abierto { transform: none; }
.drawer-head { display: flex; align-items: center; gap: 10px; padding: 10px 12px 10px 16px; border-bottom: 1px solid var(--line); }
.drawer-head .brand-name { font-size: 19px; }
.drawer-cerrar { margin-left: auto; width: var(--tap); height: var(--tap); display: inline-flex; align-items: center;
  justify-content: center; background: none; border: 0; border-radius: var(--r-md); color: var(--text); cursor: pointer; }
.drawer-cerrar .ico { width: 22px; height: 22px; }
.drawer-nav { display: flex; flex-direction: column; padding: 8px; }
.drawer-nav a {
  display: flex; align-items: center; gap: 10px; min-height: 46px; padding: 0 12px;
  border-radius: var(--r-md); color: var(--text-2); font-size: 15px; font-weight: 500;
}
.drawer-nav a:hover { background: var(--surface-2); color: var(--text); }
.drawer-nav a.activo { background: var(--brand-tint); color: var(--brand-hi); font-weight: 600; }
.drawer-nav a .notif-badge { margin-left: auto; }
.drawer-pie { margin-top: auto; padding: 12px 16px 16px; border-top: 1px solid var(--line);
  display: flex; align-items: center; gap: 10px; flex-wrap: wrap; }
.drawer-pie .masthead-user { display: inline-block; max-width: 60%; }
.drawer-pie .link-quiet { display: inline-flex; min-height: var(--tap); align-items: center; margin-left: auto; }
body.scroll-lock { overflow: hidden; }
@media (prefers-reduced-motion: reduce) { .drawer, .scrim { transition: none; } }

/* ----- Sidebar de periodos como <details> en movil ----- */
.sidebar > summary { display: none; }
@media (max-width: 639.98px) {
  details.sidebar > summary {
    display: flex; align-items: center; gap: 8px; min-height: var(--tap); cursor: pointer;
    list-style: none; font-family: var(--font-mono); font-size: 12px; letter-spacing: .04em;
    color: var(--text); padding: 0 2px;
  }
  details.sidebar > summary::-webkit-details-marker { display: none; }
  details.sidebar > summary .ico { margin-left: auto; transition: transform .15s; }
  details.sidebar[open] > summary .ico { transform: rotate(180deg); }
  details.sidebar > summary .muted { font-family: var(--font-body); }
  details.sidebar > h2 { margin-top: 10px; }
  details.sidebar:not([open]) > *:not(summary) { display: none; }
}

/* ----- Tabulator en movil ----- */
.tabulator .tabulator-frozen { background: var(--surface); }
.tabulator .tabulator-frozen-left { border-right: 1px solid var(--line) !important; }
.tabulator-responsive-collapse-toggle {
  background: var(--surface-2) !important; color: var(--text) !important;
  border: 1px solid var(--line) !important; border-radius: 6px !important; width: 28px !important; height: 28px !important;
}
.tabulator-responsive-collapse { background: var(--surface); border-top: 1px solid var(--line-soft) !important; }
.tabulator-responsive-collapse table td { padding: 4px 8px; font-size: 12.5px; }
.tabulator-responsive-collapse table td:first-child { font-family: var(--font-mono); font-size: 10.5px; color: var(--text-3); text-transform: uppercase; letter-spacing: .06em; }
.tabla-alta { max-height: 70dvh; }

/* ----- Cubo cards: afordancia visible (no solo hover) ----- */
.cubo-card-abrir { display: inline-flex; align-items: center; gap: 4px; margin-top: 8px;
  font-family: var(--font-mono); font-size: 11px; letter-spacing: .06em; text-transform: uppercase; color: var(--brand); }

/* Tabulator: el layout fitDataTable ensancha el contenedor; se limita al
   ancho disponible y el scroll horizontal queda dentro de la tabla. */
.tabulator { max-width: 100%; }
.tabulator .tabulator-tableholder { overflow-x: auto; }
/* Inputs de archivo y grupos de control: que encojan en telefono */
.ctrl-group input[type="file"] { flex: 1 1 200px; min-width: 0; width: auto; max-width: 100%; }
input[type="file"] { max-width: 100%; }
@media (max-width: 639.98px) {
  .ctrl-group { row-gap: 10px; }
  .ctrl-group > label, .ctrl-group > .ctrl-label { flex-basis: 100%; }
  .ctrl-group > .btn, .ctrl-group > .btn-sm { flex: 0 0 auto; }
  input[type="file"] { width: 100%; }
}
/* El input de archivo tiene un ancho intrinseco enorme: se le quita el
   minimo y el grupo se limita al ancho del contenido. */
.ctrl-group, .dash-controls, .form-row { max-width: 100%; min-width: 0; }
.ctrl-group > *, .form-row > * { min-width: 0; max-width: 100%; }
input[type="file"] { min-width: 0; width: min(100%, 320px); box-sizing: border-box; }
@media (max-width: 639.98px) {
  .dash-controls > .ctrl-group { flex: 1 1 100%; }
  input[type="file"] { width: 100%; flex: 1 1 100%; }
}

/* ============================================================
   Navegacion de dos niveles y mapa del sistema
   ============================================================
   El nav de arriba lleva los grupos (5 destinos) y el detalle de cada grupo
   baja al subnav, que reusa .tabs. Antes eran 10 enlaces planos compitiendo
   entre si en el masthead. La estructura sale de app/mapa.py. */
.subnav {
  margin: 0; padding: 0 var(--gutter); background: var(--surface);
  border-bottom: 1px solid var(--line);
}
.subnav .tabs-grp { padding-bottom: 0; }
@media (max-width: 899.98px) { .subnav { display: none; } }

/* En telefono el segundo nivel vive dentro del drawer. */
.drawer-sub { display: grid; margin-top: 6px; padding-top: 10px; border-top: 1px solid var(--line); }
.drawer-sub-tit {
  font-family: var(--font-mono); font-size: 10px; letter-spacing: .14em;
  text-transform: uppercase; color: var(--text-3); margin: 0 0 4px;
}
.drawer-sub a {
  min-height: var(--tap); display: flex; align-items: center; padding-left: 12px;
  color: var(--text-2); text-decoration: none; font-size: 14px;
  border-left: 2px solid var(--line);
}
.drawer-sub a.activo { color: var(--brand-hi); border-left-color: var(--brand-hi); font-weight: 600; }

/* ----- Chips de estado: color + icono + texto, nunca color solo ----- */
.chip--listo, .chip--parcial, .chip--planeado {
  display: inline-flex; align-items: center; gap: 4px;
}
.chip--listo .ico, .chip--parcial .ico, .chip--planeado .ico { width: 12px; height: 12px; }
.chip--listo {
  color: var(--ok); background: color-mix(in srgb, var(--mp-green) 12%, transparent);
  border-color: color-mix(in srgb, var(--mp-green) 45%, transparent);
}
.chip--parcial { color: var(--warn); background: var(--warn-bg);
  border-color: color-mix(in srgb, var(--warn-fill) 60%, transparent); }
/* --text-3 da 4.6:1 sobre papel, pero la tarjeta planeada tiene fondo
   --canvas y ahi cae a 4.26:1. Con --text-2 son 6.9:1 sobre ese fondo. */
.chip--planeado { color: var(--text-2); background: var(--paper); }

/* ----- Mapa del sistema ----- */
.mapa-conteo { margin-bottom: 26px; }
.mapa-grupo { margin: 26px 0 10px; }
.mapa-rejilla { display: grid; gap: 10px; grid-template-columns: repeat(auto-fill, minmax(280px, 1fr)); }
.mapa-card {
  display: block; padding: 14px 16px; background: var(--surface);
  border: 1px solid var(--line); border-radius: var(--r-lg);
  color: var(--text); text-decoration: none;
}
a.mapa-card:hover { border-color: var(--brand); box-shadow: var(--shadow-sm); }
/* Lo planeado se lee como pendiente, no como deshabilitado por error. */
.mapa-card--planeado { background: var(--canvas); border-style: dashed; }
.mapa-card-top { display: flex; align-items: center; justify-content: space-between; gap: 10px; margin-bottom: 4px; }
.mapa-card-nombre { font-weight: 700; font-size: 15px; }
.mapa-card-txt { margin: 0; font-size: 13px; color: var(--text-2); }
.mapa-card-falta {
  display: flex; gap: 6px; margin: 8px 0 0; padding-top: 8px;
  border-top: 1px dashed var(--line); font-size: 12.5px; color: var(--text-3);
}
.mapa-card-falta .ico { flex: 0 0 auto; width: 14px; height: 14px; margin-top: 2px; }
.mapa-pie { margin-top: 24px; }

/* ----- Estado vacio unificado (macro `vacio` de _nav.html) -----
   Tres razones distintas que hasta hoy se veian igual: no hay dato para el
   filtro, no hay fuente todavia, o algo fallo. El error nunca se disfraza de
   vacio. */
.vacio {
  display: flex; gap: 10px; align-items: flex-start; margin: 14px 0;
  padding: 14px 16px; border: 1px dashed var(--line-hard);
  border-radius: var(--r-lg); font-size: 13.5px; color: var(--text-2);
}
.vacio p { margin: 0; }
.vacio .ico { flex: 0 0 auto; margin-top: 2px; color: var(--text-3); }
.vacio .btn { margin-top: 8px; }
.vacio--fuente { border-color: color-mix(in srgb, var(--warn-fill) 45%, transparent); background: var(--warn-bg); }
.vacio--fuente .ico { color: var(--warn); }
.vacio--error {
  border-style: solid; border-color: color-mix(in srgb, var(--mp-red) 50%, transparent);
  background: var(--danger-bg); color: var(--danger-ink);
}
.vacio--error .ico { color: var(--danger); }
/* Celda sin valor: "·" no hay dato, "—" no hay fuente. */
.celda-vacia { color: var(--text-3); }

/* ----- Iconos de seccion en nav, subnav y mapa -----
   Van con la etiqueta, nunca solos (regla nav-label-icon: un nav de puros
   iconos no se descubre). El .tabs y el .nav-link ya traen su propio gap. */
.masthead-nav .nav-link, .drawer-nav a, .drawer-sub a {
  display: inline-flex; align-items: center; gap: 7px;
}
.masthead-nav .nav-link .ico, .drawer-nav a .ico,
.drawer-sub a .ico, .tabs a .ico { width: 15px; height: 15px; flex: 0 0 auto; }
/* En pantallas justas el icono se va antes que el texto: la palabra es la
   que orienta, el icono solo ayuda a reconocerla. */
@media (min-width: 900px) and (max-width: 1160px) {
  .masthead-nav .nav-link .ico { display: none; }
}
.mapa-grupo { display: flex; align-items: center; gap: 8px; }
.mapa-grupo .ico { width: 17px; height: 17px; color: var(--text-3); }
.mapa-card-nombre { display: inline-flex; align-items: center; gap: 8px; }
.mapa-card-ico { width: 16px; height: 16px; flex: 0 0 auto; color: var(--brand); }
.mapa-card--planeado .mapa-card-ico { color: var(--text-3); }

/* Chip rojo: lo que no se surtió o no se facturó. Completa la escala de
   .chip--listo / .chip--parcial / .chip--planeado del mapa. */
.chip--rojo {
  display: inline-flex; align-items: center; gap: 4px;
  color: var(--danger-ink); background: var(--danger-bg);
  border-color: color-mix(in srgb, var(--danger) 45%, transparent);
}
.chip--rojo .ico { width: 12px; height: 12px; }
