/* ═══════════════════════════════════════════════════════════════════════════
   Capa de tokens del panel Meivet.

   Va DESPUÉS del sistema de diseño activo (Nocturne u Modernist) y NO lo
   sustituye: añade lo que ninguno de los dos trae y que la aplicación venía
   resolviendo a mano, archivo por archivo, con 793 objetos de estilo en línea.

   Qué añade, y por qué hacía falta:

   1. ESCALA TIPOGRÁFICA. La aplicación usa 25 tamaños distintos, la mayoría
      fraccionarios (12.5 en 96 sitios, 11.5 en 54, 13.5 en 33). Tres tamaños
      dentro de un punto entre sí haciendo el mismo trabajo no son una escala,
      son ruido — y los fraccionarios el navegador los redondea distinto según
      el zoom, así que dos textos que deberían verse iguales no se ven iguales.
      Mientras tanto la escala del sistema de diseño (h1 42px, h2 32px…) está
      anulada en línea en todas las pantallas.

   2. ESCALA DE ESPACIO. `--space-*` no vale lo mismo en los dos temas —8.4px
      contra 12px en `--space-3`, por ejemplo—, y el código la mezcla con más de
      230 `gap` en píxeles crudos repartidos en doce valores sueltos. La
      divergencia entre temas es un efecto colateral de que los dos sistemas se
      escribieron por separado, no una decisión de diseño: la densidad alta que
      pide el panel se aplica igual en oscuro y en claro.

   3. MOVIMIENTO. En todo el proyecto había una sola `transition`. Sin
      duraciones ni curvas compartidas no hay forma de que la interfaz se sienta
      de una pieza.

   4. PROFUNDIDAD. `--shadow-sm` es un anillo de 1px en Nocturne y una sombra
      real en Modernist, así que `.elev-sm` significa dos cosas. Aquí los cuatro
      planos quedan definidos por su papel y resueltos por tema.

   5. ESTADO INTERACTIVO. Los `color-mix(...)` de hover y selección estaban
      escritos a mano en cada archivo, con porcentajes distintos.

   `--space-*`, `--radius-*`, `--shadow-*` y `--mv-*` SIGUEN EXISTIENDO y no se
   tocan: las pantallas migran a la escala nueva en su propia fase, no de golpe.
   ═══════════════════════════════════════════════════════════════════════════ */

:root {
  /* ── Tipografía ─────────────────────────────────────────────────────────
     Nueve pasos, todos enteros. Cada uno con su interlineado emparejado: en
     una interfaz densa el interlineado no puede ser un múltiplo fijo, porque
     el texto pequeño necesita proporcionalmente más aire que el grande.

     Tabla de migración desde los 25 tamaños actuales — la conversión es
     mecánica, no interpretativa:

       10, 10.5              → --txt-3xs   (versalitas, contadores)
       11, 11.5              → --txt-2xs   (pies, notas al margen)
       12, 12.5              → --txt-xs    (texto secundario, metadatos)
       13, 13.5              → --txt-sm    (celdas de tabla, cuerpo denso)
       14, 14.5, 15, 15.5    → --txt-md    (cuerpo)
       16, 17                → --txt-lg    (títulos de bloque)
       18, 19, 20, 21        → --txt-xl    (títulos de pantalla)
       23, 24, 26, 27        → --txt-2xl   (cifras destacadas, h1 de detalle)
       30, 34, 40            → --txt-3xl   (el indicador de impacto)
  */
  --txt-3xs: 10px;
  --txt-3xs-lh: 1.4;
  --txt-2xs: 11px;
  --txt-2xs-lh: 1.45;
  --txt-xs: 12px;
  --txt-xs-lh: 1.45;
  --txt-sm: 13px;
  --txt-sm-lh: 1.5;
  --txt-md: 14px;
  --txt-md-lh: 1.5;
  --txt-lg: 16px;
  --txt-lg-lh: 1.4;
  --txt-xl: 19px;
  --txt-xl-lh: 1.3;
  --txt-2xl: 24px;
  --txt-2xl-lh: 1.2;
  --txt-3xl: 32px;
  --txt-3xl-lh: 1.1;
  /* Un paso más, para la cifra que encabeza una pantalla entera. Lo pide el
     indicador central de Reportes, que tiene que pesar más que las dos cifras
     de grupo que compara —y esas ya están en `--txt-3xl`—. */
  --txt-4xl: 40px;
  --txt-4xl-lh: 1.05;

  /* Ajuste óptico: el texto grande necesita apretarse y el pequeño abrirse
     para que la mancha de gris se lea pareja. */
  --tr-apretado: -0.02em;
  --tr-normal: 0;
  --tr-versalita: 0.1em;

  /* ── Espacio ────────────────────────────────────────────────────────────
     Enteros, mismo valor en ambos temas. Escala de 4 con un paso intermedio
     donde hace falta: el panel es denso y entre 4 y 8 hay decisiones reales.  */
  --sp-0: 0;
  --sp-1: 2px;
  --sp-2: 4px;
  --sp-3: 6px;
  --sp-4: 8px;
  --sp-5: 12px;
  --sp-6: 16px;
  --sp-7: 20px;
  --sp-8: 24px;
  --sp-9: 32px;

  /* ── Compatibilidad: la escala vieja, alineada ────────────────────────────
     §2.4 diagnosticó que `--space-*` no vale lo mismo en los dos temas y la
     refactorización lo cerró en el código de la aplicación — pero **las dos
     hojas del sistema de diseño conservan 17 usos cada una**, y una de ellas es
     el `padding` de `.btn`:

         .btn { padding: var(--space-2) calc(var(--space-3) * 1.2); }

     Nocturne da 5.6 / 10.08 px y Modernist 8 / 14.4. La auditoría final contó
     **1192 apariciones de 5.6 px** en el tema oscuro: de ahí salía que los
     controles midieran 30–36 px en oscuro y 35–40 en claro, y que cada diálogo
     cambiara de alto al cambiar de tema.

     Aquí se redefine en función de `--sp-*`, que sí vale igual en los dos. No
     se tocan las dos hojas —son «CSS real, se porta tal cual» (§1)— y esta capa
     carga después, así que gana sin `!important`.

     Los valores elegidos son los que ya tenía Modernist, que es la escala limpia
     de cuatro: el tema oscuro se airea hasta igualarlo. La dirección contraria
     —compactar el claro— dejaba los botones en 30 px de alto, y el principio 6
     pide mismo ritmo, no el ritmo más apretado de los dos. */
  --space-1: var(--sp-2);
  --space-2: var(--sp-4);
  --space-3: var(--sp-5);
  --space-4: var(--sp-6);
  --space-6: var(--sp-8);
  --space-8: var(--sp-9);

  /* Queda un valor que la redefinición de arriba no alcanza: el `calc()` del
     relleno lateral de `.btn` multiplica por 1.2 y produce **14.4 px**, que no
     está en ninguna escala. Ya no diverge entre temas —antes era 10.08 en
     oscuro y 14.4 en claro—, pero sigue siendo un fraccionario, y era el último
     de volumen: 188 apariciones. Se sustituye la declaración entera, que es lo
     único que se puede hacer sin tocar las dos hojas. */
  --sp-10: 40px;

  /* ── Movimiento ─────────────────────────────────────────────────────────
     El movimiento informa; no adorna. Nada por encima de 240 ms: por encima
     de ahí una interfaz de uso continuo se siente lenta, no fluida.

     Curvas asimétricas a propósito: al entrar, salida rápida y frenado suave
     (el elemento «llega»); al salir, arranque suave y aceleración (el elemento
     «se va»). Es lo que hace que un panel no parezca que parpadea.  */
  --mo-instantaneo: 80ms;
  --mo-rapido: 120ms;
  --mo-normal: 160ms;
  --mo-lento: 240ms;
  --ea-salida: cubic-bezier(0.16, 1, 0.3, 1);
  --ea-entrada: cubic-bezier(0.7, 0, 0.84, 0);
  --ea-estandar: cubic-bezier(0.4, 0, 0.2, 1);

  /* ── Elevación de traslación ────────────────────────────────────────────
     Cuánto se mueve un elemento al aparecer. Pequeño a propósito.  */
  --mo-desliz: 4px;
  --mo-desliz-lg: 8px;
}

/* ── Profundidad ──────────────────────────────────────────────────────────
   Cuatro planos, definidos por su papel y no por su aspecto:

     fondo       el lienzo de la aplicación
     superficie  paneles y tarjetas apoyados en el fondo
     elevado     lo que flota sobre el contenido sin ser modal (menús, avisos)
     flotante    lo modal: diálogos y el buscador ⌘K

   Cada tema los resuelve como corresponde a su naturaleza: en oscuro se eleva
   aclarando y con anillo, en claro con sombra proyectada.  */

[data-tema='oscuro'] {
  --pl-fondo-bg: var(--color-bg);
  --pl-fondo-borde: transparent;
  --pl-fondo-sombra: none;

  --pl-superficie-bg: var(--color-surface);
  --pl-superficie-borde: color-mix(in srgb, var(--color-text) 9%, transparent);
  --pl-superficie-sombra: none;

  --pl-elevado-bg: color-mix(in srgb, var(--color-text) 5%, var(--color-surface));
  --pl-elevado-borde: color-mix(in srgb, var(--color-text) 15%, transparent);
  --pl-elevado-sombra: 0 4px 14px rgba(0, 0, 0, 0.45);

  --pl-flotante-bg: color-mix(in srgb, var(--color-text) 7%, var(--color-surface));
  --pl-flotante-borde: color-mix(in srgb, var(--color-text) 20%, transparent);
  --pl-flotante-sombra: 0 18px 48px rgba(0, 0, 0, 0.62);
  --pl-velo: rgba(9, 10, 18, 0.62);

  /* Estado interactivo. Los porcentajes salen de los que ya usaba el código,
     unificados: había 5%, 7%, 10%, 12%, 14% y 16% para lo mismo. */
  /* ── Peso tipográfico ─────────────────────────────────────────────────────
     La Fase 0 cerró la escala de tamaño en ocho pasos y **el peso nunca se
     tokenizó**. Medidos en las diez pantallas salían cinco: 400, 500, 600, 700
     y 800. No son cinco papeles, son tres:

       · cuerpo    → 400
       · destacado → `--peso-fuerte`
       · titular   → `--font-heading-weight`, que vale 500 en Nocturne y 800 en
                     Modernist **a propósito**: es la personalidad tipográfica
                     de cada sistema, Inter frente a Archivo, y no se unifica.

     El 700 no lo elegía nadie: es el valor por defecto que el navegador da a
     `<th>` y a `<strong>`. Y tenía consecuencia — en tema oscuro una cabecera
     de tabla de 11 px pesaba 700 y el título de la pantalla, de 19 px, pesaba
     500: el peso contradecía la jerarquía de tamaño en vez de reforzarla. */
  --peso-cuerpo: 400;
  --peso-fuerte: 600;

  /* ── Anillo de señal ──────────────────────────────────────────────────────
     Un `inset 0 0 0 Npx <color>` no es profundidad: es un contorno que marca
     algo —lo seleccionado, lo urgente, lo enfocado—. El histograma de la
     auditoría contaba 24 sombras distintas y parecía desgobierno de planos,
     pero la profundidad real la llevan `--pl-*`; lo que no tenía nombre era
     esto, y por eso convivían grosores de 1px, 1.5px y `--mv-rule` para el
     mismo papel. */
  --anillo: 1px;

  --st-hover: color-mix(in srgb, var(--color-text) 7%, transparent);
  --st-activo: color-mix(in srgb, var(--color-text) 12%, transparent);
  --st-sel-bg: color-mix(in srgb, var(--color-accent) 16%, transparent);
  /* Un control **ya seleccionado** sigue siendo pulsable, así que también
     responde al puntero — y responde subiendo un escalón desde su propio
     estado, no volviendo al neutro. Sin este token el hover de un chip activo
     o de una pestaña activa pintaba `--st-sel-bg`, que es exactamente lo que
     ya tenía en reposo: el control parecía inerte. */
  --st-sel-bg-fuerte: color-mix(in srgb, var(--color-accent) 24%, transparent);
  --st-sel-borde: color-mix(in srgb, var(--color-accent) 40%, transparent);
  /* El acento sobre SU PROPIO tinte, que es lo que este token significa. No
     vale el acento de marca: el relleno al 16 % aclara el fondo y #9184d9 se
     queda en 3.72:1 encima —lo comprobó la sección activa de la navegación—.
     Se sube un escalón de la rampa, que sobre el tinte llega a 7:1. */
  --st-sel-fg: var(--color-accent-300);

  /* El acento CUANDO HACE DE TEXTO. En oscuro coincide con el de marca —#9184d9
     da 5.45:1 sobre el fondo—, así que aquí no hay diferencia. Existe por el
     tema claro; ver la nota de allí. */
  --fg-acento: var(--color-accent);

  /* El rojo semántico **como texto**. `--sem-crit` está calibrado para pintar
     fondos y marcas, y sobre el plano flotante —el de un diálogo— se queda en
     4.06:1: el mensaje de error junto a un campo caía por debajo del mínimo y
     no salía en ningún barrido porque los datos de desarrollo no producen un
     fallo de validación. Se mezcla al 66 % con el color de texto, el mismo
     valor que `Pildora` usa desde la Fase 13 y por la misma razón —menos color
     semántico es más color de texto, que es el extremo legible—: 5.56:1 sobre
     el diálogo, conservando el tono. */
  --fg-crit: color-mix(in srgb, var(--sem-crit) 66%, var(--color-text));

  /* Fondo de la pieza del logotipo. El archivo es un JPEG con fondo blanco y
     ese blanco estaba escrito a mano —`#f3f5fe`— en el armazón y en el login. */
  --mv-marca-fondo: #f3f5fe;
}

[data-tema='claro'] {
  --pl-fondo-bg: var(--color-bg);
  --pl-fondo-borde: transparent;
  --pl-fondo-sombra: none;

  --pl-superficie-bg: var(--color-surface);
  --pl-superficie-borde: color-mix(in srgb, var(--color-text) 14%, transparent);
  --pl-superficie-sombra: none;

  --pl-elevado-bg: #fdfcfc;
  --pl-elevado-borde: color-mix(in srgb, var(--color-text) 22%, transparent);
  --pl-elevado-sombra: 0 3px 12px color-mix(in srgb, #2d2b2b 18%, transparent);

  --pl-flotante-bg: #fdfcfc;
  --pl-flotante-borde: color-mix(in srgb, var(--color-text) 30%, transparent);
  --pl-flotante-sombra: 0 14px 40px color-mix(in srgb, #2d2b2b 26%, transparent);
  --pl-velo: rgba(45, 43, 43, 0.34);

  --st-hover: color-mix(in srgb, var(--color-text) 5%, transparent);
  --st-activo: color-mix(in srgb, var(--color-text) 10%, transparent);
  --st-sel-bg: color-mix(in srgb, var(--color-accent) 10%, transparent);
  --st-sel-bg-fuerte: color-mix(in srgb, var(--color-accent) 16%, transparent);
  --st-sel-borde: color-mix(in srgb, var(--color-accent) 55%, transparent);
  /* Ver la nota del tema oscuro: aquí el tinte oscurece en vez de aclarar, así
     que el escalón va hacia el otro lado. */
  --st-sel-fg: var(--color-accent-800);

  /* El rojo de marca de Modernist (#ec3013) da 3.76:1 sobre el fondo claro: vale
     para un relleno o un borde, y NO vale para texto —el proyecto exige 4.5:1—.
     Se usaba igual en el rótulo de las tarjetas, que además es de 10 px. El
     acento como texto baja un escalón de la rampa, que conserva la identidad y
     llega a 6,4:1. */
  --fg-acento: var(--color-accent-700);

  /* En claro el rojo semántico es oscuro (`#9c1500`) y sobre el diálogo da
     8.13:1: se queda puro, porque mezclarlo con el texto solo lo oscurecería
     más y le quitaría identidad sin ganar legibilidad. Igual que `--fg-acento`,
     el token existe para que el tema decida. */
  --fg-crit: var(--sem-crit);

  --mv-marca-fondo: #f3f5fe;
}

/* Quien pide menos movimiento recibe la interfaz entera sin él. No es una
   preferencia estética: para parte de las personas el movimiento provoca
   malestar físico. Se anula aquí, en el token, para que ninguna regla de
   `interaccion.css` tenga que acordarse de comprobarlo. */
@media (prefers-reduced-motion: reduce) {
  :root {
    --mo-instantaneo: 0.01ms;
    --mo-rapido: 0.01ms;
    --mo-normal: 0.01ms;
    --mo-lento: 0.01ms;
    --mo-desliz: 0px;
    --mo-desliz-lg: 0px;
  }
}

/* ── Utilidades de escala ─────────────────────────────────────────────────
   Para que migrar una pantalla sea sustituir un `fontSize` en línea por una
   clase, sin inventar nada por el camino. */
.t-3xs { font-size: var(--txt-3xs); line-height: var(--txt-3xs-lh); }
.t-2xs { font-size: var(--txt-2xs); line-height: var(--txt-2xs-lh); }
.t-xs  { font-size: var(--txt-xs);  line-height: var(--txt-xs-lh); }
.t-sm  { font-size: var(--txt-sm);  line-height: var(--txt-sm-lh); }
.t-md  { font-size: var(--txt-md);  line-height: var(--txt-md-lh); }
.t-lg  { font-size: var(--txt-lg);  line-height: var(--txt-lg-lh); letter-spacing: var(--tr-apretado); }
.t-xl  { font-size: var(--txt-xl);  line-height: var(--txt-xl-lh); letter-spacing: var(--tr-apretado); }
.t-2xl { font-size: var(--txt-2xl); line-height: var(--txt-2xl-lh); letter-spacing: var(--tr-apretado); }
.t-3xl { font-size: var(--txt-3xl); line-height: var(--txt-3xl-lh); letter-spacing: var(--tr-apretado); }

/* Versalita de sección: el rótulo pequeño en mayúsculas que ya usan las
   tarjetas (`.card-kicker`) y media docena de sitios a mano. */
.t-versalita {
  font-size: var(--txt-3xs);
  line-height: var(--txt-3xs-lh);
  letter-spacing: var(--tr-versalita);
  text-transform: uppercase;
}

/* Cifras: alineadas en vertical al recorrer una columna con la vista. Regla
   del proyecto para toda columna numérica. */
.t-cifra { font-variant-numeric: tabular-nums; }

/* ═══ Correcciones de contraste sobre el sistema de diseño ═══════════════════
   Las tres reglas siguientes corrigen texto que las hojas de Nocturne y
   Modernist dejan por debajo del 4.5:1 que exige el proyecto. Van aquí y no en
   esas hojas porque son de terceros: se complementan, no se editan.
   ═══════════════════════════════════════════════════════════════════════════ */

/* El rótulo de las tarjetas se pinta con el acento de marca. En el tema claro
   daba 3.47:1 sobre la superficie, en un texto de 10 px. */
.card-kicker {
  color: var(--fg-acento);
}

/* La cabecera de tabla usa el texto al 60 % de opacidad, que se queda en
   4.06–4.24:1 en las dos hojas. Y es texto de 11 px en versalitas, que es
   justo donde menos margen hay. Sale de la rampa `--mv-text-*`, verificada. */
.table th {
  color: var(--mv-text-3);
  /* Ver `--peso-fuerte`: el 700 por defecto del navegador dejaba la cabecera
     más pesada que el título de la pantalla en el tema oscuro. */
  font-weight: var(--peso-fuerte);
}

/* Mismo caso que `<th>`: el 700 del navegador no lo eligió nadie. */
strong,
b {
  font-weight: var(--peso-fuerte);
}

/* El botón primario del tema claro es texto casi blanco sobre el rojo de marca
   (#ec3013): 3.76:1. Es el control más prominente de la interfaz —«Nueva cita»,
   «Atender», «Registrar movimiento»— y lo llevaba incumpliendo en todas las
   pantallas. Se baja el relleno un escalón de la rampa: sigue siendo el rojo de
   la marca, y el texto encima pasa de 3.76 a 7.4:1. */
[data-tema='claro'] .btn-primary {
  background: var(--color-accent-700);
  color: var(--color-accent-100);
}
[data-tema='claro'] .btn-primary:hover {
  background: var(--color-accent-800);
}
[data-tema='claro'] .btn-primary:active {
  background: var(--color-accent-900);
}

/* `.btn-ghost` se pinta con el acento de marca, y en el tema claro da 3.76:1.
   Es el botón de las acciones en línea —«Ver ficha» en cada fila de clientes,
   los enlaces de vuelta— y estaba por debajo del mínimo en toda la aplicación. */
.btn-ghost {
  color: var(--fg-acento);
}

/* Un control desactivado queda exento del mínimo de contraste según la norma,
   pero al 45 % una etiqueta de 12 px cuesta leerla incluso sabiendo que está
   apagada. Medio escalón más: sigue leyéndose como inactivo. */
.btn:disabled {
  opacity: 0.55;
}

/* La etiqueta de campo de las dos hojas es
   `color-mix(in srgb, var(--color-text) 70%, transparent)`, que es opacidad
   sobre texto con otro nombre —octava aparición de §10.6.1, y la primera dentro
   del sistema de diseño—. Sobre `--color-bg` llega justo; sobre `--mv-panel`,
   que es el fondo de **todo** diálogo, cae a 4.06:1 en el tema claro. Lo pagaban
   las once etiquetas de «Nuevo cliente» y «Nueva cita», y lo habría pagado
   cualquier `.field` que se apoyara en un panel. Sale de la rampa, verificada
   sobre las dos superficies. */
.field > label {
  color: var(--mv-text-3);
}

.btn {
  padding: var(--sp-4) var(--sp-6);
}

/* ── Densidad de fila ───────────────────────────────────────────────────────
   Un botón dentro de una celda **no dicta el alto de la fila**. «Ver ficha» de
   la lista de clientes mide 35 px con el relleno de arriba, y con los 8 px de
   `.table td` a cada lado dejaba la fila en 52 — un 33 % más alta que las de
   inventario, configuración y reportes, que tienen el mismo relleno y la misma
   tipografía y salen a 39–40.

   No era una decisión de densidad de esa pantalla: era el control estirando su
   celda. El principio 2 pide un solo eje de densidad ajustado con un token, no
   una altura distinta por pantalla según lo que le toque llevar dentro.

   El relleno lateral no se toca: lo que sobra es el vertical. En modo tableta
   `.mv-tableta` sigue subiendo todos los controles a 46 px. */
.table td .btn {
  padding-block: var(--sp-2);
}

/* El único radio fuera de la escala (4 · 8 · 14 · 50 %) era un 6 px que no
   estaba declarado en ninguna parte: sale de `.tag`, que lo calcula con
   `calc(var(--radius-md) * 0.75)`. Mismo patrón que el `calc(… * 1.2)` del
   relleno de `.btn` — un multiplicador que aterriza fuera de la escala. */
.tag {
  border-radius: var(--radius-sm);
  /* 3 y 10 px, ninguno en la escala. */
  padding: var(--sp-2) var(--sp-5);
  /* **El hueco entre el glifo y su etiqueta, que no lo pone un `{' '}`.**

     `.tag` es `inline-flex` y **un nodo de texto de solo espacios entre dos
     elementos flex se descarta** — lo dice la especificación, y es la razón de
     que la columna Origen de Roles saliera «●Sistema» pegado y la de horarios
     «●Disponible». Los dos sitios escribían `<span>●</span>{' '}Etiqueta`
     creyendo que separaba, y en un contenedor flex ese espacio no existe.

     Se arregla aquí y no en los dos sitios porque el defecto es de la caja, no
     de quien la usa: cualquier `.tag` que mañana lleve un glifo delante —y el
     proyecto exige color + marca + etiqueta en todo estado— volvería a caer.
     Mismo `--sp-3` que ya usa `.pildora`, para que las dos se lean igual. */
  gap: var(--sp-3);
}

/* ── Los píxeles sueltos de las dos hojas base ──────────────────────────────
   Lo que quedaba fuera de `--sp-*` después de la tanda 1 y que no era un filete
   ni un desplazamiento de `sticky`. Se sobrescribe desde aquí, como todo lo
   demás: las dos hojas son «CSS real, se porta tal cual» (§1), y esta capa carga
   después. Cada valor va al paso más cercano de la escala. */

/* 5 px → 6. La etiqueta de campo, en todo formulario de la aplicación. */
.field > label {
  margin-bottom: var(--sp-3);
}

/* 6 / 10 px → 6 / 12. El relleno de todo campo. */
.input {
  padding: var(--sp-3) var(--sp-5);
}

/* 7 / 12 px → 8 / 12. El segmentado: día/semana de la agenda, escritorio/tableta
   del borrador, y el conmutador de tema. */
.seg-opt {
  padding: var(--sp-4) var(--sp-5);
}

/* Un botón cuadrado cuyo único contenido es un glifo se centra siempre.
   `meivet.css` alinea todos los botones a la izquierda en el tema claro —es la
   prescripción de Modernist para los botones con etiqueta— y eso arrastraba
   también a los de icono, que quedaban con el glifo pegado al borde izquierdo
   de su caja de 36×36. Se necesitan dos clases para ganar en especificidad. */
.btn.btn-icon {
  justify-content: center;
}


/* `.tag-outline` se pinta con el acento de marca y en el tema claro da 3.76:1.
   Marca «Presuntivo / Definitivo» en los diagnósticos del borrador de consulta,
   que es la distinción clínica de un diagnóstico, a 11 px.

   El texto sale de `--st-sel-fg` y no de `--fg-acento`: la etiqueta se apoya
   sobre superficies tintadas —la fila de lo ya registrado, por ejemplo— y ahí
   el acento se mide contra el tinte y no contra el fondo del panel, que es el
   patrón §10.6.3. `--st-sel-fg` existe justo para eso. El filete sí puede ser
   el acento: un borde no tiene que cumplir el mínimo de texto. */
.tag-outline {
  border-color: var(--fg-acento);
  color: var(--st-sel-fg);
}

/* ═══════════════════════════════════════════════════════════════════════════
   Visualización de datos.

   Las barras de Reportes se pintaban con los tokens semánticos —`--sem-ok` para
   «con recordatorio» y `--sem-crit` para «sin recordatorio»— y eso está mal por
   tres motivos, los tres medidos:

   1. **Las dos barras miden lo mismo**: la tasa de inasistencia, donde más
      largo es peor. Una barra verde que crece dice lo contrario que su
      longitud. El código ya había razonado esto para la cifra —«pintar de rojo
      un 0,0 % de inasistencia lo haría leer como una mala noticia»— y lo dejó
      puesto en la barra.
   2. **La paleta no pasa el validador** de la guía `dataviz`: en claro el verde
      `#245f45` tiene croma 0.076, por debajo del suelo, y **se lee como gris**;
      en oscuro dos de los tres quedan fuera de la banda de luminosidad; y la
      separación entre verde y rojo cae a ΔE 7.1–7.9 bajo deuteranopia — la
      banda de suelo. El par que un deuteranope no distingue es justo el que
      codifica la comparación central de la tesis.
   3. **Los colores de estado están reservados** para significar bueno/malo, no
      para decir de qué grupo es una barra.

   `--viz-serie-1` es el tono único de las barras: comparan magnitudes de la
   misma medida, que es nominal categórico de una sola serie. La polaridad la
   sigue llevando la cifra de «Diferencia», donde el color de estado sí
   significa lo que dice.

   El valor es el paso 600 de la rampa de acento de cada sistema de diseño, y
   pasa las seis comprobaciones en los dos temas:
   `#796cbf` sobre `#232532` · `#dd2b0f` sobre `#eae9e9`.
   ═══════════════════════════════════════════════════════════════════════════ */
:root {
  --viz-serie-1: var(--color-accent-600);
}

/* La pista sobre la que se apoya la barra. Recesiva: no es dato. */
.mv-viz-pista {
  display: block;
  border-radius: var(--mv-r);
  background: var(--mv-track);
  overflow: hidden;
}

.mv-viz-barra {
  display: block;
  height: 100%;
  background: var(--viz-serie-1);
  /* Extremo de dato redondeado, anclado a la línea base. */
  border-radius: 0 var(--mv-r) var(--mv-r) 0;
}

/* ═══════════════════════════════════════════════════════════════════════════
   Cuatro clases que el panel usaba y **ninguna hoja definía**.

   Salieron de un barrido que compara cada `className` literal del JSX contra las
   clases declaradas en las cinco hojas. Es la misma clase de defecto que ya
   habían encontrado a mano `mv-navitem:hover` (Fase 0) y `.mv-userbtn` (auditoría
   final): una clase escrita con confianza que no pinta nada, y cuyo síntoma es
   que la pantalla se ve *casi* bien, así que nadie la reporta.

   El barrido queda como comprobación al añadir una clase global nueva: si no
   está aquí abajo ni en las dos hojas del sistema de diseño, no existe.
   ═══════════════════════════════════════════════════════════════════════════ */

/* ── `.hint` · 25 usos en cinco archivos ─────────────────────────────────────
   La nota que explica un campo: por qué se piden las coordenadas *y* la
   dirección, qué hace el asistente cuando solo hay una sucursal, qué pasa sin
   teléfono. Se pintaba con el tamaño y el color del cuerpo, así que se leía con
   el mismo peso que el contenido del formulario y competía con él.

   `--mv-text-3` y no `--mv-text-4`: es la ayuda de un campo, y la auditoría
   final ya midió que ese escalón era el que caía por debajo del 4.5:1 en los dos
   temas (ver `.ayuda` en `capa.module.css`, misma decisión). */
.hint {
  margin: var(--sp-2) 0 0;
  font-size: var(--txt-2xs);
  line-height: var(--txt-2xs-lh);
  color: var(--mv-text-3);
}

/* La misma nota cuando lo que dice es un fallo. **Color, marca y sitio**, como
   cualquier otro estado del proyecto: el color solo no basta, y por eso los
   sitios que la usan escriben su `▲` delante. Sin esto, el error de un campo se
   veía exactamente igual que la ayuda que tiene al lado — que es la manera de
   que no se lea. */
.hint[role='alert'],
.hint-error {
  color: var(--sem-crit);
}

/* ── `.btn-sm` · 8 usos ──────────────────────────────────────────────────────
   El botón pequeño de dentro de una fila o de una tarjeta: «Quitar» en una línea
   de orden, «Cambiar» junto al cliente de una venta, las tres decisiones de
   Oportunidades. Sin la clase salían del tamaño de un botón principal y le
   robaban el peso a la fila que acompañan. */
.btn-sm {
  min-height: 28px;
  padding: var(--sp-2) var(--sp-4);
  font-size: var(--txt-2xs);
  line-height: var(--txt-2xs-lh);
}

/* En tableta vuelve al mínimo tocable: la regla de `meivet.css` existe para que
   ningún control baje de 46 px con el animal delante, y un botón pequeño no es
   una excepción — es justo el que se falla. */
.mv-tableta .btn-sm {
  min-height: 46px;
  padding: var(--sp-3) var(--sp-5);
}

/* ── `.num` · 5 usos ─────────────────────────────────────────────────────────
   Una cifra que se compara con la de la línea de arriba: precio, costo y margen
   de un tratamiento, uno debajo de otro. En tipografía proporcional esas tres
   columnas no se alinean, que es lo único que hacía falta para poder leerlas
   como una resta. */
.num {
  font-variant-numeric: tabular-nums;
  font-feature-settings: 'tnum' 1;
}

/* ── `.sr-only` · 1 uso ──────────────────────────────────────────────────────
   Texto para el lector de pantalla. La técnica es la de `SoloLectores` en
   `primitivas.tsx` —`clip-path`, que no arrastra la caja fuera del documento ni
   ensancha el desplazamiento horizontal—, y la clase existe además del
   componente porque **un `<label htmlFor>` no se puede envolver en un `<span>`**
   sin romper su asociación con el campo.

   Sin ella, la etiqueta «Motivo» de la bandeja de escalaciones se veía. */
.sr-only {
  position: absolute;
  width: 1px;
  height: 1px;
  padding: 0;
  margin: -1px;
  overflow: hidden;
  clip-path: inset(50%);
  white-space: nowrap;
  border: 0;
}

/* ═══════════════════════════════════════════════════════════════════════════
   El botón sin variante, que en los dos sistemas de diseño es invisible.

   `.btn` nace con `border: 1px solid transparent` y `background: transparent`,
   y el color y el borde los ponen `.btn-primary`, `.btn-secondary` y
   `.btn-ghost`. **Un `className="btn"` a secas queda entonces como texto en
   tipografía de titular, sin caja y sin ningún indicio de que se puede
   pulsar** — que es lo que pasaba en 54 sitios del panel, entre ellos «Volver a
   los permisos» del diálogo de roles, «Anular» en el detalle de una orden y
   «Ver todos» de media docena de estados vacíos.

   No es un descuido de los sistemas de diseño: los tres pares que traen
   —principal, secundario, fantasma— cubren la jerarquía completa, y `.btn`
   solo es su base. Lo que faltaba era decidir qué hace el panel cuando alguien
   escribe la base sin variante, y la respuesta no puede ser «nada visible».
   Se resuelve como un secundario, que es lo que esos 54 sitios querían decir:
   una acción disponible, sin la carga de la principal.

   `:not()` triple y no un `:not([class*='btn-'])`: `btn-sm` **sí** tiene que
   recibir este borde —es un tamaño, no una variante— y un selector por
   subcadena se lo quitaría.
   ═══════════════════════════════════════════════════════════════════════════ */
.btn:not(.btn-primary):not(.btn-secondary):not(.btn-ghost) {
  border-color: var(--color-divider);
}
.btn:not(.btn-primary):not(.btn-secondary):not(.btn-ghost):hover:not(:disabled) {
  background: color-mix(in srgb, var(--color-text) 7%, transparent);
}
.btn:not(.btn-primary):not(.btn-secondary):not(.btn-ghost):active:not(:disabled) {
  background: color-mix(in srgb, var(--color-text) 14%, transparent);
}
