/* =========================================================================
   The Show — componentes
   =========================================================================
   Todo valor sale de tokens.css. Si aquí aparece un literal de color, tamaño,
   espacio o radio, es un error: el token que falta se añade allí.

   El material va en el CHROME —sidebar, toolbar, contenedor de tarjeta— para
   que la interfaz retroceda y el contenido avance. Las cifras van sobre la hoja
   más sólida. Nunca cristal sobre cristal.
   ========================================================================= */

*, *::before, *::after { box-sizing: border-box; }

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

body {
  margin: 0;
  color: var(--color-text);
  /* El campo de luces es lo que el material refracta. Sobre gris plano, la
     translucidez no se distingue de una opacidad cualquiera. Fijo: un fondo que
     se mueve detrás de una tabla de cifras distrae, no ambienta. */
  background: var(--fondo-luces), var(--fondo-base);
  background-attachment: fixed;
  background-repeat: no-repeat;
  min-block-size: 100vh;
  font-family: var(--font-sans);
  font-size: var(--text-body);
  font-weight: var(--weight-regular);
  line-height: var(--leading-normal);
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
  font-feature-settings: "cv02", "cv03", "cv04", "cv11";
}

:focus-visible {
  outline: var(--focus-width) solid var(--color-focus);
  outline-offset: var(--focus-offset);
  border-radius: var(--radius-xs);
}

/* -------------------------------------------------------------------------
   Tipografía
   ------------------------------------------------------------------------- */

h1, h2, h3 {
  margin: 0;
  font-weight: var(--weight-medium);
  line-height: var(--leading-tight);
  letter-spacing: var(--tracking-tight);
}

h1 { font-size: var(--text-title); margin-bottom: var(--space-1); }
h2 { font-size: var(--text-subtitle); }
h3 { font-size: var(--text-section); }

p { margin: 0 0 var(--space-4); }

.sub {
  color: var(--color-text-secondary);
  margin: 0 0 var(--space-6);
}

.tenue { color: var(--color-text-tertiary); }

.caption {
  display: block;
  font-size: var(--text-caption);
  line-height: var(--leading-snug);
  color: var(--color-text-tertiary);
}

.nota {
  font-size: var(--text-label);
  color: var(--color-text-secondary);
  margin-top: var(--space-3);
  margin-bottom: 0;
}

/* La cifra grande de una métrica: peso 400, tracking negativo y cifras de
   ancho fijo, para que al refrescar no bailen las columnas. */
.metrica {
  display: block;
  font-size: var(--text-metric);
  font-weight: var(--weight-regular);
  line-height: var(--leading-tight);
  letter-spacing: var(--tracking-tight);
  font-variant-numeric: tabular-nums;
  font-feature-settings: "tnum";
  margin: var(--space-2) 0;
}

.metrica-lg { font-size: var(--text-metric-lg); }

/* Cualquier cifra dentro de una tabla o una línea de texto. */
.num {
  font-variant-numeric: tabular-nums;
  font-feature-settings: "tnum";
  letter-spacing: var(--tracking-tight);
}

code {
  font-family: var(--font-mono);
  font-size: var(--text-sm);
  background: var(--color-surface-sunken);
  border-radius: var(--radius-xs);
  padding: 0 var(--space-1);
}

/* -------------------------------------------------------------------------
   Capas de cristal
   Tres piezas que se repiten: el material, el anillo de refracción y el
   reflejo. Se declaran una vez y se aplican por composición.
   ------------------------------------------------------------------------- */

/* El anillo de refracción. ESTO es lo que separa Liquid Glass de un
   glassmorphism: no es una sombra que imita un borde, es un backdrop-filter
   propio recortado a un anillo. El fondo que pasa por el canto se aclara y se
   distorsiona de verdad. */
.lens {
  position: absolute;
  inset: 0;
  border-radius: inherit;
  padding: var(--lens-grosor);
  pointer-events: none;
  backdrop-filter: var(--lens-filter);
  -webkit-backdrop-filter: var(--lens-filter);
  -webkit-mask: linear-gradient(#fff 0 0) content-box, linear-gradient(#fff 0 0);
  -webkit-mask-composite: xor;
  mask: linear-gradient(#fff 0 0) content-box, linear-gradient(#fff 0 0);
  mask-composite: exclude;
}

/* El reflejo especular que sigue al puntero. Sutil a propósito: si se nota, ya
   es demasiado. --mx y --my las escribe glass.js sobre el contenedor raíz. */
.spec {
  position: absolute;
  inset: 0;
  border-radius: inherit;
  pointer-events: none;
  opacity: var(--spec-opacidad);
  background: radial-gradient(
    420px 220px at var(--mx, 50%) var(--my, 0%),
    rgba(255, 255, 255, 0.55),
    rgba(255, 255, 255, 0.10) 42%,
    transparent 68%
  );
}

/* -------------------------------------------------------------------------
   Estructura: sidebar, toolbar y lienzo
   ------------------------------------------------------------------------- */

.app {
  display: grid;
  grid-template-columns: var(--sidebar-ancho) minmax(0, 1fr);
  min-block-size: 100vh;
}

/* --- Sidebar ----------------------------------------------------------
   Sustituye a la barra superior porque resuelve algo que la barra no podía:
   agrupar secciones. «Shows» del panel y «Shows» de administración se llaman
   igual y hacen cosas distintas; en una barra plana quedaban uno al lado del
   otro sin nada que los separara. */
.sidebar {
  position: sticky;
  top: 0;
  block-size: 100vh;
  display: flex;
  flex-direction: column;
  gap: var(--space-6);
  padding: var(--space-5) var(--space-4);
  background: var(--glass-sidebar-bg);
  backdrop-filter: var(--glass-sidebar-filter);
  -webkit-backdrop-filter: var(--glass-sidebar-filter);
  border-inline-end: var(--border-width-hairline) solid rgba(255, 255, 255, 0.5);
  overflow-y: auto;
}

.marca {
  font-size: var(--text-label);
  font-weight: var(--weight-medium);
  letter-spacing: var(--tracking-tight);
  color: var(--color-text);
  padding-inline: var(--space-2);
}

.nav-grupo { display: flex; flex-direction: column; gap: var(--space-1); }

.nav-titulo {
  font-size: var(--text-2xs);
  font-weight: var(--weight-medium);
  letter-spacing: var(--tracking-wide);
  text-transform: uppercase;
  color: var(--color-text-tertiary);
  padding: 0 var(--space-2) var(--space-1);
}

.nav-item {
  display: flex;
  align-items: center;
  gap: var(--space-3);
  padding: var(--space-2) var(--space-2);
  border-radius: var(--radius-control);
  color: var(--color-text-secondary);
  font-size: var(--text-label);
  font-weight: var(--weight-regular);
  text-decoration: none;
  transition: background-color var(--duration-fast) var(--ease-standard),
              color var(--duration-fast) var(--ease-standard);
}

.nav-item:hover { background: rgba(255, 255, 255, 0.5); color: var(--color-text); }

/* Seleccionado: inequívoco. Fondo tintado del acento, texto e ícono en el
   acento, peso 500 y un inset que lo hunde un punto. */
.nav-item[aria-current="page"] {
  background: var(--color-acento-tinte);
  color: var(--color-acento);
  font-weight: var(--weight-medium);
  box-shadow: inset 0 1px 2px rgba(0, 113, 227, 0.12);
}

/* Cada sección con su tinte. Ayuda a separar de un vistazo dos entradas que se
   llaman igual y llevan a sitios distintos. */
.nav-icono {
  inline-size: var(--space-4);
  block-size: var(--space-4);
  flex: 0 0 auto;
  color: var(--nav-tinte, var(--color-text-tertiary));
}

.nav-item[aria-current="page"] .nav-icono { color: var(--color-acento); }

/* El tinte por sección. Es lo que separa de un vistazo el «Shows» del panel del
   «Shows» de administración: se llaman igual y llevan a sitios distintos. */
.nav-item[data-tinte="panel"]     { --nav-tinte: var(--tinte-panel); }
.nav-item[data-tinte="historico"] { --nav-tinte: var(--tinte-historico); }
.nav-item[data-tinte="admin"]     { --nav-tinte: var(--tinte-admin); }
.nav-item[data-tinte="campanas"]  { --nav-tinte: var(--tinte-campanas); }
.nav-item[data-tinte="usuarios"]  { --nav-tinte: var(--tinte-usuarios); }

.nav-item .nav-icono svg { display: block; inline-size: 100%; block-size: 100%; }

.nav-pie { margin-block-start: auto; }

/* --- Toolbar ----------------------------------------------------------- */

.lienzo { display: flex; flex-direction: column; min-inline-size: 0; }

.toolbar {
  position: sticky;
  top: 0;
  z-index: 30;
  min-block-size: var(--toolbar-alto);
  display: flex;
  align-items: center;
  gap: var(--space-3);
  padding: 0 var(--layout-gutter);
  background: var(--glass-toolbar-bg);
  backdrop-filter: var(--glass-toolbar-filter);
  -webkit-backdrop-filter: var(--glass-toolbar-filter);
}

.toolbar .spacer { margin-inline-start: auto; }

.toolbar-titulo {
  font-size: var(--text-label);
  font-weight: var(--weight-medium);
  color: var(--color-text);
}

/* --- Scroll edge effect ------------------------------------------------
   El contenido se disuelve bajo la toolbar sin una línea dura de blur. CSS no
   tiene desenfoque progresivo nativo —linear-blur() sigue siendo propuesta del
   CSSWG—, así que se fabrica apilando cuatro capas de backdrop-filter con
   máscaras escalonadas. La opacidad la mueve glass.js según el scroll. */
.scroll-edge {
  position: sticky;
  top: var(--toolbar-alto);
  z-index: 20;
  block-size: var(--scroll-edge-alto);
  margin-block-end: calc(var(--scroll-edge-alto) * -1);
  pointer-events: none;
  opacity: var(--edge-opacidad, 0.2);
  transition: opacity var(--duration-base) var(--ease-standard);
}

.scroll-edge > i {
  position: absolute;
  inset: 0;
  display: block;
}

.scroll-edge .e1 {
  backdrop-filter: blur(16px);
  -webkit-backdrop-filter: blur(16px);
  -webkit-mask: linear-gradient(#000 0%, #000 12%, transparent 40%);
  mask: linear-gradient(#000 0%, #000 12%, transparent 40%);
}

.scroll-edge .e2 {
  backdrop-filter: blur(8px);
  -webkit-backdrop-filter: blur(8px);
  -webkit-mask: linear-gradient(#000 0%, #000 32%, transparent 64%);
  mask: linear-gradient(#000 0%, #000 32%, transparent 64%);
}

.scroll-edge .e3 {
  backdrop-filter: blur(3px);
  -webkit-backdrop-filter: blur(3px);
  -webkit-mask: linear-gradient(#000 0%, #000 56%, transparent 92%);
  mask: linear-gradient(#000 0%, #000 56%, transparent 92%);
}

.scroll-edge .e4 {
  background: linear-gradient(rgba(255, 255, 255, 0.4), transparent 90%);
}

/* En opaco el borde no se difumina: se acabó el cristal. */
[data-material="opaco"] .scroll-edge { display: none; }

@media (prefers-reduced-transparency: reduce) {
  .scroll-edge { display: none; }
}

/* --- Lienzo ------------------------------------------------------------ */

main {
  max-inline-size: var(--layout-max-width);
  inline-size: 100%;
  margin: 0 auto;
  padding: var(--space-8) var(--layout-gutter) var(--space-20);
}

main.estrecha { max-inline-size: var(--layout-narrow); }

main.centrada {
  max-inline-size: var(--layout-form);
  padding-block-start: var(--space-16);
  text-align: center;
}

main.centrada .card { text-align: start; }

/* Las pantallas sin sesión —login, error— no tienen sidebar. */
.app.sin-sidebar { grid-template-columns: minmax(0, 1fr); }

/* -------------------------------------------------------------------------
   Tarjetas
   El contenedor es cristal; lo de dentro, casi sólido. Una hoja por nivel.
   ------------------------------------------------------------------------- */

.card {
  position: relative;
  isolation: isolate;
  background: var(--glass-card-bg);
  backdrop-filter: var(--glass-card-filter);
  -webkit-backdrop-filter: var(--glass-card-filter);
  border-radius: var(--radius-card);
  box-shadow: var(--sombra-card);
  /* El padding es el que separa el radio exterior del interior. */
  padding: var(--space-5);
  margin-block-end: var(--space-4);
}

.card > :first-child { margin-block-start: 0; }
.card > :last-child { margin-block-end: 0; }

/* El anillo y el reflejo van como pseudo-elementos de la tarjeta, no como divs
   en la plantilla: así ninguna tarjeta se queda sin ellos porque alguien
   olvidara añadirlos, y las plantillas no cargan con marcado decorativo.
   `.lens` y `.spec` siguen existiendo como clases para casos sueltos. */
.card::before,
.card::after {
  content: "";
  position: absolute;
  inset: 0;
  border-radius: inherit;
  pointer-events: none;
}

/* El anillo de refracción: su propio backdrop-filter recortado a un marco. */
.card::before {
  padding: var(--lens-grosor);
  backdrop-filter: var(--lens-filter);
  -webkit-backdrop-filter: var(--lens-filter);
  -webkit-mask: linear-gradient(#fff 0 0) content-box, linear-gradient(#fff 0 0);
  -webkit-mask-composite: xor;
  mask: linear-gradient(#fff 0 0) content-box, linear-gradient(#fff 0 0);
  mask-composite: exclude;
}

/* El reflejo especular, que sigue al puntero. */
.card::after {
  opacity: var(--spec-opacidad);
  background: radial-gradient(
    420px 220px at var(--mx, 50%) var(--my, 0%),
    rgba(255, 255, 255, 0.55),
    rgba(255, 255, 255, 0.10) 42%,
    transparent 68%
  );
}

/* El contenido va por encima de las dos capas. Sin esto, el reflejo lavaría el
   texto que debería estar iluminando por detrás. */
.card > * { position: relative; z-index: 1; }

/* En opaco no hay ni anillo ni reflejo: no son adornos que se atenúan, se
   apagan. */
[data-material="opaco"] .card::before,
[data-material="opaco"] .card::after { display: none; }

@media (prefers-reduced-transparency: reduce) {
  .card::before,
  .card::after { display: none; }
}

/* Todo lo que va dentro de una tarjeta usa el radio DERIVADO, nunca el mismo.
   Dos radios iguales anidados se leen como cajas dentro de cajas. */
.card .tabla-scroll,
.card .password-unica,
.card .hito,
.card .plegable { border-radius: var(--radius-interior); }

.card-titulo {
  font-size: var(--text-section);
  font-weight: var(--weight-medium);
  letter-spacing: var(--tracking-tight);
  margin: 0 0 var(--space-4);
}

.card.acotada { max-inline-size: var(--layout-narrow); }

/* -------------------------------------------------------------------------
   Tablas
   ------------------------------------------------------------------------- */

/* La hoja más sólida de todas. Las cifras no se leen a través de nada.
   NO lleva backdrop-filter, y por dos razones que apuntan al mismo sitio:

   1. Vive DENTRO de una tarjeta que ya es cristal. Otro desenfoque encima sería
      cristal sobre cristal: lo que se vería a través no es el fondo, es la
      tarjeta, y el efecto se ensucia en vez de dar profundidad.
   2. Cada capa que pide desenfoque de fondo se recalcula en cada frame del
      scroll. Con las tablas dentro, la página pasaba de 16 a 94 ms de p95. */
.tabla-scroll {
  overflow-x: auto;
  min-inline-size: 0;
  background: var(--glass-table-bg);
}

table {
  width: 100%;
  border-collapse: collapse;
  font-size: var(--text-body);
}

th, td {
  text-align: start;
  padding: var(--cell-padding-y) var(--cell-padding-x);
  border-bottom: var(--border-hairline);
  vertical-align: middle;
}

th {
  font-size: var(--text-caption);
  font-weight: var(--weight-medium);
  color: var(--color-text-secondary);
  letter-spacing: var(--tracking-normal);
  border-bottom: var(--border-hairline-strong);
  white-space: nowrap;
}

tr:last-child td { border-bottom: none; }

td.num, th.num { text-align: end; font-variant-numeric: tabular-nums; }
td.acciones, th.acciones { text-align: end; white-space: nowrap; }

/* Anchos mínimos de las celdas que llevan un control dentro. Se miden en
   múltiplos de --space-20 para que sigan la misma escala que todo lo demás. */
td.col-xs { min-width: var(--space-16); }
td.col-sm { min-width: var(--space-20); }
td.col-md { min-width: calc(var(--space-20) * 1.6); }
td.col-lg { min-width: calc(var(--space-20) * 2); }
td.col-xl { min-width: calc(var(--space-20) * 2.9); }

/* La celda de estado apila la pastilla y su pie sin estirar la columna. */
td .pila {
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  gap: var(--space-1);
}

/* -------------------------------------------------------------------------
   Formularios
   ------------------------------------------------------------------------- */

label {
  display: block;
  font-size: var(--text-label);
  font-weight: var(--weight-regular);
  color: var(--color-text-secondary);
  margin: var(--space-4) 0 var(--space-1);
}

label:first-child { margin-top: 0; }

input, select, textarea {
  width: 100%;
  min-height: var(--control-height);
  padding: 0 var(--control-padding-x);
  border: var(--border-hairline-strong);
  border-radius: var(--radius-control);
  background: var(--color-surface);
  color: var(--color-text);
  font-family: var(--font-sans);
  font-size: var(--text-body);
  font-weight: var(--weight-regular);
  transition: border-color var(--duration-fast) var(--ease-standard);
}

textarea {
  padding: var(--space-2) var(--control-padding-x);
  line-height: var(--leading-snug);
  resize: vertical;
}

input:hover, select:hover, textarea:hover { border-color: var(--color-text-tertiary); }

input::placeholder, textarea::placeholder { color: var(--color-text-tertiary); }

input.auto, select.auto { width: auto; }

.fila {
  display: flex;
  gap: var(--space-3);
  flex-wrap: wrap;
  align-items: flex-end;
}

.fila > * { flex: 1 1 calc(var(--space-20) * 2.25); }
.fila .estrecho { flex: 0 0 auto; }

.acciones-form {
  display: flex;
  gap: var(--space-2);
  align-items: center;
  margin-top: var(--space-5);
}

form.inline { display: inline; }

/* -------------------------------------------------------------------------
   Botones
   ------------------------------------------------------------------------- */

button, .btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  height: var(--control-height);
  padding: 0 var(--space-4);
  border: var(--border-width-hairline) solid var(--color-surface-inverse);
  border-radius: var(--radius-control);
  background: var(--color-surface-inverse);
  color: var(--color-text-inverse);
  font-family: var(--font-sans);
  font-size: var(--text-label);
  font-weight: var(--weight-medium);
  line-height: var(--leading-none);
  letter-spacing: var(--tracking-normal);
  cursor: pointer;
  text-decoration: none;
  white-space: nowrap;
  transition: background-color var(--duration-fast) var(--ease-standard),
              border-color var(--duration-fast) var(--ease-standard),
              color var(--duration-fast) var(--ease-standard);
}

button:hover, .btn:hover { background: var(--color-text); border-color: var(--color-text); }

button.sec, .btn.sec {
  background: var(--color-surface);
  color: var(--color-text);
  border-color: var(--color-border-strong);
}

button.sec:hover, .btn.sec:hover {
  background: var(--color-surface-hover);
  border-color: var(--color-text-tertiary);
  color: var(--color-text);
}

button.mini, .btn.mini {
  height: var(--control-height-sm);
  padding: 0 var(--control-padding-x-sm);
  font-size: var(--text-caption);
}

button.ancho, .btn.ancho { inline-size: 100%; }

/* Botón de cristal. El sólido en medio del panel translúcido se leía como una
   pieza de otro sistema; este habla el mismo idioma que los chips de contador:
   fondo translúcido y el mismo canto especular de las tarjetas. */
.btn.cristal, button.cristal {
  position: relative;
  isolation: isolate;
  background: var(--glass-toolbar-bg);
  backdrop-filter: var(--glass-toolbar-filter);
  -webkit-backdrop-filter: var(--glass-toolbar-filter);
  border: none;
  color: var(--color-text);
  box-shadow:
    inset 0 1px 0 rgba(255, 255, 255, 0.9),
    inset 0 -1px 0 rgba(255, 255, 255, 0.35),
    inset 1px 0 0 rgba(255, 255, 255, 0.5),
    inset -1px 0 0 rgba(255, 255, 255, 0.5),
    0 1px 3px rgba(70, 55, 110, 0.10);
  transition: background-color var(--duracion-resorte) var(--resorte),
              transform var(--duracion-resorte) var(--resorte);
}

.btn.cristal:hover, button.cristal:hover {
  background: var(--color-surface-solida);
  color: var(--color-text);
  transform: translateY(-1px);
}

[data-material="opaco"] .btn.cristal,
[data-material="opaco"] button.cristal {
  background: var(--color-surface);
  box-shadow: 0 0 0 var(--border-width-hairline) var(--color-border-strong);
}

@media (prefers-reduced-transparency: reduce) {
  .btn.cristal, button.cristal {
    background: var(--color-surface);
    box-shadow: 0 0 0 var(--border-width-hairline) var(--color-border-strong);
  }
}

@media (prefers-reduced-motion: reduce) {
  .btn.cristal:hover, button.cristal:hover { transform: none; }
}

/* -------------------------------------------------------------------------
   Avisos y pastillas
   ------------------------------------------------------------------------- */

.aviso {
  padding: var(--space-3) var(--space-4);
  border: var(--border-width-hairline) solid var(--color-border);
  border-radius: var(--radius-control);
  margin-bottom: var(--space-4);
  font-size: var(--text-label);
}

.aviso.ok {
  background: var(--color-positive-surface);
  border-color: var(--color-positive-border);
  color: var(--color-positive-text);
}

.aviso.error {
  background: var(--color-negative-surface);
  border-color: var(--color-negative-border);
  color: var(--color-negative-text);
}

.pill {
  display: inline-flex;
  align-items: center;
  font-size: var(--text-caption);
  font-weight: var(--weight-regular);
  padding: var(--space-1) var(--space-2);
  border-radius: var(--radius-pill);
  background: var(--color-neutral-surface);
  color: var(--color-neutral-text);
  white-space: nowrap;
}

.pill.on { background: var(--color-positive-surface); color: var(--color-positive-text); }
.pill.off { background: var(--color-neutral-surface); color: var(--color-neutral-text); }

/* -------------------------------------------------------------------------
   Menú de la cuenta
   Un <details> nativo: se abre y se cierra sin una línea de JavaScript.
   ------------------------------------------------------------------------- */

.menu { position: relative; }

.menu summary {
  list-style: none;
  cursor: pointer;
  /* Vive en el sidebar claro, no en la barra oscura de antes: con el color
     heredado se quedaba casi invisible. */
  color: var(--color-text-secondary);
  font-size: var(--text-label);
  padding: var(--space-2);
  border-radius: var(--radius-control);
  transition: color var(--duration-fast) var(--ease-standard),
              background-color var(--duration-fast) var(--ease-standard);
}

.menu summary::-webkit-details-marker { display: none; }
.menu summary:hover,
.menu[open] summary {
  color: var(--color-text);
  background: rgba(255, 255, 255, 0.5);
}

.menu-panel {
  position: absolute;
  z-index: 40;
  inset-inline-start: 0;
  /* Cuelga hacia ARRIBA: el menú vive en el pie del sidebar y hacia abajo se
     saldría de la ventana. */
  bottom: calc(100% + var(--space-2));
  z-index: 10;
  min-width: var(--menu-ancho);
  display: flex;
  flex-direction: column;
  background: var(--color-surface);
  border: var(--border-hairline-strong);
  border-radius: var(--radius-card);
  padding: var(--space-2);
}

.menu-cabecera {
  display: block;
  padding: var(--space-2);
  color: var(--color-text-secondary);
  font-size: var(--text-caption);
  border-bottom: var(--border-hairline);
  margin-bottom: var(--space-1);
}

.menu-panel a {
  color: var(--color-text);
  font-size: var(--text-label);
  text-decoration: none;
  padding: var(--space-2);
  border-radius: var(--radius-sm);
}

.menu-panel a:hover { background: var(--color-surface-hover); color: var(--color-text); }

/* Botón que vive sobre la barra oscura: sin relleno, solo contorno. */
/* Ya no hay barra oscura sobre la que vivir: se comporta como secundario. */
button.fantasma, .btn.fantasma {
  background: var(--color-surface-solida);
  color: var(--color-text);
  border-color: var(--color-border-strong);
}

/* -------------------------------------------------------------------------
   Modo vista
   ------------------------------------------------------------------------- */

.barra-vista {
  position: sticky;
  top: 0;
  z-index: 20;
  min-height: var(--altura-barra-vista);
  display: flex;
  align-items: center;
  justify-content: center;
  gap: var(--space-3);
  padding: var(--space-1) var(--layout-gutter);
  background: var(--color-vista-surface);
  color: var(--color-vista-text);
  /* Franja invertida respecto a la barra de arriba, que es casi negra. En un
     sistema sin color, la inversión es la señal más fuerte que hay: se ve que
     es otra cosa antes de leerla. */
  border-block: var(--border-width-regular) solid var(--color-vista-borde);
  font-size: var(--text-label);
  font-weight: var(--weight-medium);
}

.barra-vista button { height: var(--control-height-sm); }

/* La contraseña temporal, enseñada una sola vez. */
.password-unica {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--space-3);
  padding: var(--space-4);
  border: var(--border-hairline-strong);
  border-radius: var(--radius-control);
  background: var(--color-surface-sunken);
  margin-bottom: var(--space-4);
}

.password-unica code {
  font-size: var(--text-xl);
  letter-spacing: var(--tracking-wide);
  background: var(--color-surface);
  border: var(--border-hairline);
  padding: var(--space-2) var(--space-3);
  border-radius: var(--radius-sm);
  user-select: all;
}

/* -------------------------------------------------------------------------
   Dashboard: lista agrupada de shows
   Patrón inset grouped list. Cada show es un <details>: tres zonas en reposo
   —identidad, dinero, chevron— y al abrirse la fila y su panel se convierten
   en una sola tarjeta que flota sobre la lista.
   ------------------------------------------------------------------------- */

.filas { display: flex; flex-direction: column; }

/* --- Separadores insertados ---------------------------------------------
   Media línea que empieza donde empieza el texto. De borde a borde, la lista
   se lee como una hoja rayada; insertados, cada fila se lee como una unidad. */
.fila-show + .fila-show::before {
  content: "";
  display: block;
  block-size: var(--separador-alto);
  margin-inline-start: var(--separador-inset);
  background: var(--color-separador-inset);
}

/* La tarjeta elevada no lleva línea ni arriba ni abajo: ya está en otro plano,
   y una línea entre planos distintos se lee como suciedad. */
.fila-show[open] + .fila-show::before,
.fila-show[open]::before { display: none; }

/* --- Fila en reposo ------------------------------------------------------ */
.fila-show > summary {
  list-style: none;
  cursor: pointer;
  display: grid;
  grid-template-columns: minmax(0, 1fr) auto auto;
  align-items: center;
  gap: var(--space-4);
  padding: var(--fila-pad-y) var(--fila-pad-x);
  border-radius: var(--lift-radio);
  transition: background-color var(--duration-fast) var(--ease-standard);
}

.fila-show > summary::-webkit-details-marker { display: none; }
.fila-show > summary:hover { background: var(--color-surface-hover); }

/* Identidad: nombre y una sola línea de metadata. Ninguno de los dos parte en
   dos líneas — partidos, la lista deja de escanearse de un vistazo. */
.fila-txt {
  display: flex;
  flex-direction: column;
  gap: var(--space-1);
  min-inline-size: 0;
}

/* Nombre e ingreso son el mismo nivel, uno a cada lado de la fila. No compiten
   entre ellos: compiten juntos contra la metadata y los boletos. */
.fila-titulo {
  font-size: var(--text-fila-titulo);
  font-weight: var(--peso-dato-primario);
  letter-spacing: var(--tracking-fila-titulo);
  color: var(--color-text);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

.fila-meta {
  font-size: var(--text-fila-meta);
  color: var(--color-text-tertiary);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

/* Dinero: el acumulado arriba, y debajo boletos y la venta de hoy. */
.fila-valor {
  display: flex;
  flex-direction: column;
  align-items: flex-end;
  gap: var(--space-1);
  text-align: end;
  font-variant-numeric: tabular-nums;
}

.fila-monto {
  font-size: var(--text-fila-monto);
  font-weight: var(--peso-dato-primario);
  letter-spacing: var(--tracking-monto);
  color: var(--color-text);
}

.fila-sub {
  font-size: var(--text-fila-meta);
  color: var(--color-text-tertiary);
  white-space: nowrap;
}

/* En la fila colapsada la venta de hoy NO lleva color. Salía verde en las siete
   filas a la vez, y el color le gana al peso siempre: se llevaba la mirada antes
   que el nombre y el ingreso, que es justo lo que la fila tiene que anclar. Un
   acento que aparece en todas partes deja de ser un acento.
   El verde se conserva donde sí es el foco y aparece una sola vez: el tile de
   «Hoy» del panel abierto. */
.mueve { color: var(--color-text-tertiary); }

/* --- Chevron ------------------------------------------------------------- */
.chevron {
  display: inline-flex;
  color: var(--color-chevron);
  transition: transform var(--duracion-resorte) var(--resorte),
              color var(--duration-fast) var(--ease-standard);
}

.chevron svg {
  inline-size: var(--chevron-tamano);
  block-size: var(--chevron-tamano);
}

.fila-show[open] > summary .chevron {
  transform: rotate(90deg);
  color: var(--color-acento);
}

/* Un show pasado ya no admite acción: el chevron se retira sin desaparecer. */
.pasado > summary .chevron { color: var(--color-chevron-tenue); }
.pasado > summary .fila-titulo { color: var(--color-text-secondary); }

@media (prefers-reduced-motion: reduce) {
  .chevron { transition: none; }
}

/* --- La fila abierta se despega ------------------------------------------
   Fila y panel son una sola tarjeta con su propio plano. El anillo azul de
   1px es la selección; las filas de arriba y abajo retroceden solas sin que
   haya que tocarlas. */
.fila-show[open] {
  margin: var(--lift-margen) 0;
  border-radius: var(--lift-radio);
  background: var(--lift-fondo);
  box-shadow: var(--lift-sombra);
}

.fila-show[open] > summary {
  border-end-start-radius: 0;
  border-end-end-radius: 0;
}

.fila-show[open] > summary:hover { background: transparent; }

/* --- Orden de la lista ---------------------------------------------------
   Sin columnas no hay encabezados donde colgar el orden. Se queda como lo que
   siempre fue: tres enlaces. */
.orden-lista {
  display: flex;
  align-items: baseline;
  gap: var(--space-3);
  padding: var(--space-3) var(--fila-pad-x);
  font-size: var(--text-caption);
  color: var(--color-text-tertiary);
}

.orden-lista a {
  color: var(--color-text-secondary);
  text-decoration: none;
}

.orden-lista a:hover { color: var(--color-text); }
.orden-lista a.activo { color: var(--color-text); }

/* --- Panel abierto ------------------------------------------------------- */
.panel-show {
  padding: 0 var(--fila-pad-x) var(--fila-pad-x);
}

/* Tres tiles: hoy, ayer y el ticket promedio. Hoy va en verde porque es el
   número que se mueve. */
.tiles {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(calc(var(--space-20) * 1.4), 1fr));
  gap: var(--space-2);
  margin-block-end: var(--space-3);
}

.tile {
  border-radius: var(--tile-radio);
  padding: var(--tile-pad-y) var(--tile-pad-x);
  background: var(--tile-fondo);
}

.tile label {
  display: block;
  font-size: var(--text-tile-label);
  color: var(--color-text-secondary);
  letter-spacing: var(--tracking-wide);
  text-transform: uppercase;
  margin: 0;
}

.tile .cifra {
  display: block;
  font-size: var(--text-tile-cifra);
  letter-spacing: var(--tracking-cifra);
  color: var(--color-text);
  font-variant-numeric: tabular-nums;
  margin-block-start: var(--space-1);
}

.tile.verde { background: var(--tile-fondo-verde); }
.tile.verde label,
.tile.verde .cifra { color: var(--color-verde); }

/* Pares etiqueta/valor. Lo que no es una cifra comparable no merece un tile:
   merece un renglón. */
.pares {
  border-radius: var(--pares-radio);
  background: var(--pares-fondo);
  overflow: hidden;
  margin-block-end: var(--space-3);
}

.par {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: var(--space-4);
  padding: var(--pares-pad-y) var(--pares-pad-x);
  font-size: var(--text-label);
}

.par { position: relative; }

/* El separador interno también va insertado, como los de la lista. */
.par + .par::before {
  content: "";
  position: absolute;
  inset-block-start: 0;
  inset-inline: var(--pares-inset) 0;
  block-size: var(--separador-alto);
  background: var(--color-separador-inset);
}

.par > dt {
  color: var(--color-text-secondary);
  white-space: nowrap;
}

.par > dd {
  margin: 0;
  color: var(--color-text);
  text-align: end;
  font-variant-numeric: tabular-nums;
}

.pares > .tabla-scroll { border-radius: 0; }

/* «Ver detalle completo» no es un botón: es el enlace de iOS al final de una
   sección. Un botón sólido en medio del cristal se lee como una pieza de otro
   sistema. */
.enlace-detalle {
  display: inline-flex;
  align-items: center;
  gap: var(--space-1);
  font-size: var(--text-enlace-detalle);
  font-weight: var(--weight-medium);
  color: var(--color-acento-texto);
  text-decoration: none;
}

.enlace-detalle:hover { text-decoration: underline; }
.enlace-detalle svg {
  inline-size: var(--chevron-tamano);
  block-size: var(--chevron-tamano);
}

/* La tabla de funciones no se estruja por debajo de lo legible: cuando no cabe,
   se desplaza dentro de su caja. Una fecha partida en cinco líneas no es una
   tabla más compacta, es una tabla que no se puede leer. */
.panel-show table { min-inline-size: calc(var(--space-20) * 7); }
.panel-show td:first-child { white-space: nowrap; }

/* Un dato que falta se dice con un guion, no con una frase. Repetida en cada
   fila, la frase pesa más que el dato que acompaña. */
.vacio { color: var(--color-text-tertiary); }

.titulo-bloque {
  font-size: var(--text-section);
  font-weight: var(--weight-medium);
  color: var(--color-text-secondary);
  letter-spacing: var(--tracking-normal);
  margin: var(--space-8) 0 var(--space-3);
}

.titulo-bloque:first-of-type { margin-top: var(--space-6); }

/* -------------------------------------------------------------------------
   Barra de aforo
   ------------------------------------------------------------------------- */

.aforo {
  display: flex;
  flex-direction: column;
  align-items: flex-end;
  gap: var(--space-1);
}

/* <progress> nativo. Cada motor lo pinta con sus propias pseudoclases, así que
   hay que declarar las tres; todas beben de los mismos tokens. */
progress.barra {
  appearance: none;
  -webkit-appearance: none;
  display: block;
  inline-size: 100%;
  block-size: var(--barra-alto);
  border: none;
  border-radius: var(--radius-full);
  background: var(--barra-fondo);
  overflow: hidden;
}

progress.barra::-webkit-progress-bar {
  background: var(--barra-fondo);
  border-radius: var(--radius-full);
}

progress.barra::-webkit-progress-value {
  background: var(--barra-relleno);
  border-radius: var(--radius-full);
}

progress.barra::-moz-progress-bar {
  background: var(--barra-relleno);
  border-radius: var(--radius-full);
}

/* Sin capacidad no hay barra. Se dice por qué, en lugar de dejar el hueco. */
.sin-aforo { color: var(--color-text-tertiary); font-size: var(--text-caption); }

/* -------------------------------------------------------------------------
   Barra de refresco del catálogo
   ------------------------------------------------------------------------- */

.refrescar {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--space-3);
  margin-bottom: var(--space-5);
}

/* -------------------------------------------------------------------------
   Bloque plegable
   Para listas largas que tienen que estar pero no delante: las campañas
   históricas del account, que son 69 de 85.
   ------------------------------------------------------------------------- */

.plegable > summary {
  list-style: none;
  cursor: pointer;
  display: inline-flex;
  align-items: center;
  gap: var(--space-2);
  padding: var(--space-2) var(--space-3);
  border: var(--border-hairline-strong);
  border-radius: var(--radius-control);
  color: var(--color-text);
  font-size: var(--text-label);
  transition: background-color var(--duration-fast) var(--ease-standard);
}

.plegable > summary::-webkit-details-marker { display: none; }
.plegable > summary::before { content: "▸"; color: var(--color-text-tertiary); }
.plegable[open] > summary::before { content: "▾"; }
.plegable > summary:hover { background: var(--color-surface-hover); }
.plegable[open] > summary { margin-bottom: var(--space-4); }

/* -------------------------------------------------------------------------
   Selector de campañas
   ------------------------------------------------------------------------- */

.selector-campanas {
  block-size: auto;
  padding: var(--space-2);
  font-family: var(--font-sans);
  font-size: var(--text-label);
}

.selector-campanas option { padding: var(--space-1) var(--space-2); }

/* Las tablas de campañas no se estrujan por debajo de lo legible: cuando no
   caben, se desplazan dentro de su caja. Un nombre partido en cinco líneas no
   es una tabla más compacta, es una tabla que no se puede leer. */
.tabla-campanas { min-inline-size: calc(var(--space-20) * 9); }
.tabla-campanas td:first-child { min-inline-size: calc(var(--space-20) * 2.5); }

.selector-campanas optgroup {
  font-weight: var(--weight-medium);
  font-style: normal;
  color: var(--color-text-secondary);
  padding-block: var(--space-2);
}

input.buscador { margin-bottom: var(--space-2); }

/* -------------------------------------------------------------------------
   Frescura del dato
   ------------------------------------------------------------------------- */

.frescura {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--space-2);
  font-size: var(--text-label);
  color: var(--color-text-secondary);
  margin-bottom: var(--space-5);
}

.frescura.obsoleto {
  padding: var(--space-3) var(--space-4);
  border-radius: var(--radius-control);
  background: var(--color-obsoleto-surface);
  color: var(--color-obsoleto-text);
  font-weight: var(--weight-medium);
}

.frescura.obsoleto .detalle { color: var(--color-text-tertiary); font-weight: var(--weight-regular); }
.frescura .separador { color: var(--color-text-tertiary); }

/* El parcial de hoy: el número y, debajo, a qué hora se leyó. */
.parcial {
  display: flex;
  flex-direction: column;
  align-items: flex-end;
  gap: var(--space-1);
}

.parcial .caption { white-space: nowrap; }

/* -------------------------------------------------------------------------
   Dashboard: KPIs y notas
   ------------------------------------------------------------------------- */

.kpis {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(calc(var(--space-20) * 2), 1fr));
  gap: var(--space-5) var(--space-4);
}

/* Encabezado del dashboard: venta a la izquierda, contexto a la derecha.
   Agrupados por naturaleza, no por caber. */
.kpis-fila {
  display: grid;
  grid-template-columns: 2fr 1fr;
  gap: var(--space-4);
  /* Las dos tarjetas miden lo mismo. Con align-items:start, el párrafo largo de
     una empujaba su altura y la otra quedaba corta. */
  align-items: stretch;
}

.kpis-fila > .card { display: flex; flex-direction: column; }
.kpis-fila > .card > .kpi-grupo:last-child { margin-block-start: auto; }

.kpis-fila .card { margin-bottom: var(--space-4); }

/* El número hero. La jerarquía sale del tamaño, nunca del peso: sigue en 400. */
.kpi-hero { margin-bottom: var(--space-6); }

.metrica.hero {
  font-size: var(--text-metric-hero);
  font-weight: var(--weight-regular);
  letter-spacing: var(--tracking-hero);
  display: flex;
  align-items: baseline;
  gap: 0;
}

/* Los centavos, a media escala y en gris. El ojo lee la magnitud primero y el
   detalle después; a tamaño completo compiten con ella. */
.centavos {
  font-size: var(--text-centavos);
  color: var(--color-text-tertiary);
  letter-spacing: var(--tracking-normal);
}

/* Rejillas de columnas FIJAS. Con auto-fit, cinco tarjetas se repartían solas y
   dejaban una huérfana en su propia fila. */
.kpi-grupo {
  display: grid;
  gap: var(--space-5) var(--space-4);
}

.grupo-venta { grid-template-columns: repeat(var(--kpi-cols-venta), minmax(0, 1fr)); }
.grupo-contexto { grid-template-columns: repeat(var(--kpi-cols-contexto), minmax(0, 1fr)); }

.kpi-grupo .metrica { font-size: var(--text-metric-kpi); }

/* Cuando una nota precede a la rejilla, el texto no puede quedar pegado a las
   cifras: se lee como si fuera parte de la primera. */
.nota + .kpis { margin-top: var(--space-4); }

.kpi label { margin-block-start: 0; }

/* --- Dos niveles dentro del panel abierto -------------------------------
   Las principales grandes y arriba; las de apoyo, más pequeñas y separadas por
   una regla. La separación es lo que dice que son dos cosas distintas. */
.kpis-principales {
  grid-template-columns: repeat(auto-fit, minmax(calc(var(--space-20) * 2.4), 1fr));
  margin-block-end: var(--space-5);
}

.kpis-principales .metrica { font-size: var(--text-metric-panel); }

.kpis-apoyo {
  padding-block-start: var(--space-5);
  border-block-start: var(--border-width-hairline) solid var(--color-border);
  margin-block-end: var(--space-5);
}

.kpis-apoyo .metrica { font-size: var(--text-metric-panel-menor); }

/* Los pies de cifra son notas, no contenido. Cuatro explicaciones del mismo
   peso bajo cuatro números competían entre ellas y con los números. */
.pie {
  display: block;
  font-size: var(--text-2xs);
  line-height: var(--leading-snug);
  color: var(--color-text-tertiary);
}

/* --- Ícono de información con tooltip ---------------------------------
   Sin JavaScript: se abre al pasar por encima y también al recibir foco, para
   que quien navegue con teclado llegue al mismo texto. */
.info {
  position: relative;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  inline-size: var(--info-tamano);
  block-size: var(--info-tamano);
  margin-inline-start: var(--space-1);
  border-radius: var(--radius-full);
  background: var(--color-surface-sunken);
  color: var(--color-text-tertiary);
  font-size: var(--text-2xs);
  cursor: help;
  vertical-align: middle;
}

.info .tooltip {
  position: absolute;
  inset-inline-start: 50%;
  bottom: calc(100% + var(--space-2));
  z-index: 50;
  inline-size: var(--tooltip-ancho);
  transform: translateX(-50%);
  padding: var(--space-3);
  border-radius: var(--radius-control);
  background: var(--color-surface-inverse);
  color: var(--color-text-inverse);
  font-size: var(--text-2xs);
  line-height: var(--leading-snug);
  font-weight: var(--weight-regular);
  text-align: start;
  opacity: 0;
  visibility: hidden;
  transition: opacity var(--duration-fast) var(--ease-standard);
}

.info:hover .tooltip,
.info:focus-visible .tooltip { opacity: 1; visibility: visible; }

/* Lo que queda de la tabla cuando el show tiene una sola función. */
.linea-funcion {
  font-size: var(--text-label);
  color: var(--color-text-secondary);
  margin-block-end: var(--space-5);
}
.kpi .metrica { font-size: var(--text-2xl); margin: var(--space-1) 0 0; }

.notas { display: flex; flex-direction: column; gap: var(--space-4); }

.nota-item {
  border-inline-start: var(--border-width-regular) solid var(--color-border-strong);
  padding-inline-start: var(--space-4);
}

.nota-item p { margin: 0 0 var(--space-1); white-space: pre-wrap; }

/* -------------------------------------------------------------------------
   Histórico
   ------------------------------------------------------------------------- */

/* El aviso de que estas cifras no son la liquidación final. Permanente, en
   todas las pantallas de histórico. */
.nota-permanente {
  display: block;
  padding: var(--space-3) var(--space-4);
  margin-bottom: var(--space-5);
  background: var(--color-nota-surface);
  border: var(--border-width-hairline) solid var(--color-nota-border);
  border-radius: var(--radius-control);
  color: var(--color-nota-text);
  font-size: var(--text-label);
}

/* Rejilla de cifras del registro de cierre. */
.cifras {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(calc(var(--space-20) * 2), 1fr));
  gap: var(--space-5) var(--space-4);
}

.cifra label { margin-top: 0; }

.cifra .metrica { font-size: var(--text-2xl); margin: var(--space-1) 0 0; }

/* Encabezados de tabla que ordenan. */
th a {
  color: inherit;
  text-decoration: none;
  display: inline-flex;
  gap: var(--space-1);
  align-items: baseline;
}

th a:hover { color: var(--color-text); }

th a[aria-sort] { color: var(--color-text); }

.orden-marca { color: var(--color-text-tertiary); }

/* La curva. SVG en línea: ni librería de gráficas ni una petición fuera. */
.curva {
  display: block;
  width: 100%;
  height: auto;
  overflow: visible;
}

.curva .reticula {
  stroke: var(--color-curva-reticula);
  stroke-width: var(--border-width-regular);
  fill: none;
}

.curva .trazo {
  stroke: var(--color-curva-trazo);
  stroke-width: var(--curva-grosor);
  fill: none;
  stroke-linejoin: round;
  stroke-linecap: round;
}

.curva-pies {
  display: flex;
  justify-content: space-between;
  margin-top: var(--space-2);
}

/* Fila de hitos T-N. */
.hitos {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(var(--space-20), 1fr));
  gap: var(--space-3);
  margin-top: var(--space-5);
}

.hito {
  border: var(--border-hairline);
  border-radius: var(--radius-control);
  padding: var(--space-3);
}

.hito .valor {
  display: block;
  font-size: var(--text-xl);
  font-weight: var(--weight-regular);
  letter-spacing: var(--tracking-tight);
  font-variant-numeric: tabular-nums;
}

.hito .valor.vacio { color: var(--color-text-tertiary); }

.filtros {
  display: flex;
  gap: var(--space-2);
  flex-wrap: wrap;
  align-items: center;
  margin-bottom: var(--space-4);
}

/* -------------------------------------------------------------------------
   Utilidades de espaciado — las únicas que existen, y consumen tokens
   ------------------------------------------------------------------------- */

.sin-margen-arriba { margin-top: 0; }
.sin-margen-abajo { margin-bottom: 0; }
.apretado { margin-bottom: var(--space-3); }

/* -------------------------------------------------------------------------
   Pantallas estrechas
   El valor es --breakpoint-sm (640px). Va escrito porque una @media no puede
   leer una custom property; el token de tokens.css es la referencia.
   ------------------------------------------------------------------------- */

/* Entre 640 y 1000 px el encabezado se apila: dos columnas dejarían el bloque
   de contexto demasiado estrecho para sus cifras. */
@media (max-width: 1000px) {
  .kpis-fila { grid-template-columns: 1fr; }
  .metrica.hero { font-size: var(--text-4xl); }
}

@media (max-width: 640px) {
  /* Sin esto la barra desborda y arrastra la página entera en horizontal:
     el ancho del body pasa a ser el de la barra, no el de la ventana. */
  .top {
    height: auto;
    min-height: var(--header-height);
    flex-wrap: wrap;
    gap: var(--space-3);
    padding-top: var(--space-2);
    padding-bottom: var(--space-2);
  }

  main { padding: var(--space-6) var(--space-4) var(--space-12); }

  .card { padding: var(--space-4); }

  /* Los grupos de campos pasan a una columna en vez de repartirse. */
  .fila > * { flex: 1 1 100%; }
  .fila .estrecho { flex: 1 1 100%; }

  /* El sidebar no cabe: 232 px fijos más el contenido no bajan de 619 px, y la
     página desbordaba en horizontal. En estrecho pasa a ser una franja arriba,
     con los grupos en línea y desplazamiento propio si hacen falta. */
  .app { grid-template-columns: minmax(0, 1fr); }

  .sidebar {
    position: static;
    block-size: auto;
    flex-direction: row;
    align-items: center;
    gap: var(--space-4);
    padding: var(--space-3) var(--space-4);
    border-inline-end: none;
    border-block-end: var(--border-width-hairline) solid rgba(255, 255, 255, 0.5);
    overflow-x: auto;
    overflow-y: hidden;
  }

  .sidebar .marca { flex: 0 0 auto; }
  .nav-grupo { flex-direction: row; align-items: center; flex: 0 0 auto; }

  /* Los rótulos de grupo no caben, pero sin ellos los dos «Shows» —el del panel
     y el de administración— quedan pegados y vuelve la confusión que el sidebar
     venía a resolver. Una regla fina los separa; los tintes de ícono hacen el
     resto. */
  .nav-titulo {
    inline-size: var(--border-width-hairline);
    block-size: var(--space-5);
    padding: 0;
    overflow: hidden;
    text-indent: -9999px;
    background: var(--color-border-strong);
    margin-inline-end: var(--space-2);
  }

  .nav-grupo:first-of-type .nav-titulo { display: none; }
  .nav-item { white-space: nowrap; }
  .nav-pie { margin-block-start: 0; margin-inline-start: auto; }
  .menu-panel { inset-inline-end: 0; }

  .toolbar { flex-wrap: wrap; padding-block: var(--space-2); }
  .segmentado { --seg-ancho: 54px; }

  :root {
    /* En estrecho, los tres de venta se apilan y los dos de contexto caben
       juntos. Ninguno de los dos grupos deja una tarjeta sola. */
    --kpi-cols-venta: 1;
    --kpi-cols-contexto: 2;
    /* La fila se estrecha, no se reordena: las tres zonas siguen siendo tres. */
    --fila-pad-x: var(--space-3);
    --separador-inset: var(--space-3);
  }
  .kpis-fila { grid-template-columns: 1fr; }
  .metrica.hero { font-size: var(--text-4xl); }

  /* El acumulado manda; los boletos y la venta de hoy pasan bajo el nombre
     para que el monto no se estruje contra el título. */
  .fila-show > summary { gap: var(--space-3); }
  .fila-monto { font-size: var(--text-fila-titulo); }
}



/* =========================================================================
   ANCHO DE TELÉFONO (≤430px)
   No basta con que no desborde: a 390px hay que decidir qué se apila, qué se
   parte en dos líneas y qué se puede tocar con el pulgar.
   ========================================================================= */
@media (max-width: 430px) {

  /* --- La fila colapsada se parte en dos renglones ----------------------
     En una línea, el nombre y la metadata se cortaban con elipsis y lo primero
     que se perdía eran los días restantes, que es justo el dato que dice si
     hay tiempo de reaccionar. El orden de prioridad es nombre, días, ingreso,
     boletos: el nombre y la metadata se llevan el ancho entero, y el dinero
     baja a su propio renglón donde nunca compite. */
  .fila-show > summary {
    grid-template-columns: minmax(0, 1fr) auto;
    grid-template-areas:
      "txt  chevron"
      "val  chevron";
    column-gap: var(--space-3);
    row-gap: var(--space-2);
  }

  .fila-txt   { grid-area: txt; }
  .fila-valor { grid-area: val; }
  .chevron    { grid-area: chevron; align-self: center; }

  /* Con el ancho entero para sí, la metadata ya no necesita cortarse. Si un
     venue es larguísimo, prefiero dos líneas a perder «en 26 días». */
  .fila-meta { white-space: normal; }

  /* Ingreso a la izquierda y boletos a la derecha, en el mismo renglón: los
     dos completos, ninguno truncado. */
  .fila-valor {
    flex-direction: row;
    align-items: baseline;
    justify-content: space-between;
    gap: var(--space-3);
    text-align: start;
  }

  .fila-sub { white-space: normal; text-align: end; }

  /* --- Tiles: dos y uno ------------------------------------------------
     A tres columnas los rótulos se parten en tres líneas. Hoy y ayer van
     juntos porque son lo que se compara entre sí; el ticket promedio no se
     compara con ninguno de los dos y se lleva el ancho entero en vez de
     quedarse huérfano a media caja. */
  .tiles { grid-template-columns: 1fr 1fr; }
  .tile:last-child { grid-column: 1 / -1; }

  /* --- Área táctil: 44px, que es lo que pide Apple ----------------------
     Con el ratón, un enlace de 19px de alto se acierta siempre. Con el pulgar,
     no. Ninguno de estos crece de tamaño: crecen de área. */
  .nav-item,
  .menu-panel a,
  .menu-panel button,
  .segmentado button,
  button.mini, .btn.mini,
  .orden-lista a,
  .enlace-detalle {
    min-block-size: var(--tap-minimo);
    display: inline-flex;
    align-items: center;
  }

  .orden-lista {
    flex-wrap: wrap;
    row-gap: 0;
    padding-block: 0;
  }

  /* El ícono de información mide 15px y tiene que seguir midiendo 15px: lo que
     se agranda es la zona que responde al dedo, no el círculo. */
  .info::after {
    content: "";
    position: absolute;
    inset: calc((var(--tap-minimo) - var(--info-tamano)) / -2);
  }

  /* El tooltip nace centrado en un ícono que está pegado al canto derecho de
     la tarjeta; a este ancho se saldría de la pantalla. */
  .info .tooltip {
    inset-inline-start: auto;
    inset-inline-end: 0;
    transform: none;
    inline-size: var(--tooltip-ancho-telefono);
  }
}

/* -------------------------------------------------------------------------
   Control segmentado — preferencia de material
   Un thumb que se desliza, no tres botones sueltos. La posición la lleva
   --seg-indice, que sale del ajuste guardado.
   ------------------------------------------------------------------------- */

.segmentado[data-indice="0"] { --seg-indice: 0; }
.segmentado[data-indice="1"] { --seg-indice: 1; }
.segmentado[data-indice="2"] { --seg-indice: 2; }

.segmentado {
  position: relative;
  display: inline-flex;
  padding: var(--space-1);
  border-radius: var(--radius-control);
  background: rgba(255, 255, 255, 0.42);
  box-shadow: inset 0 0 0 var(--border-width-hairline) rgba(255, 255, 255, 0.7);
}

/* El thumb. Se mueve con la curva de resorte: sobrepasa un punto y vuelve. */
.segmentado::before {
  content: "";
  position: absolute;
  inset-block: var(--space-1);
  inline-size: var(--seg-ancho);
  inset-inline-start: calc(var(--space-1) + var(--seg-ancho) * var(--seg-indice, 1));
  border-radius: calc(var(--radius-control) - var(--space-1));
  background: var(--color-surface-solida);
  box-shadow: 0 1px 3px rgba(70, 55, 110, 0.14);
  transition: inset-inline-start var(--duracion-resorte) var(--resorte);
}

.segmentado button {
  position: relative;
  z-index: 1;
  inline-size: var(--seg-ancho);
  block-size: auto;
  padding: var(--space-1) var(--space-3);
  border: none;
  background: transparent;
  color: var(--color-text-secondary);
  font-size: var(--text-2xs);
  font-weight: var(--weight-regular);
  border-radius: calc(var(--radius-control) - var(--space-1));
}

.segmentado button:hover { background: transparent; color: var(--color-text); }

.segmentado button[aria-pressed="true"] {
  color: var(--color-text);
  font-weight: var(--weight-medium);
}

@media (prefers-reduced-motion: reduce) {
  .segmentado::before { transition: none; }
}

/* -------------------------------------------------------------------------
   Bloques de la lista: contador y regla
   ------------------------------------------------------------------------- */

.titulo-bloque {
  display: flex;
  align-items: center;
  gap: var(--space-3);
}

.bloque-cuenta {
  font-size: var(--text-caption);
  font-weight: var(--weight-regular);
  color: var(--color-text-tertiary);
  font-variant-numeric: tabular-nums;
}

.bloque-regla {
  flex: 1 1 auto;
  block-size: var(--border-width-hairline);
  background: var(--color-border);
}
