/* Estilos base mobile-first. Un solo archivo mientras el sistema es pequeño. */

/* Paleta.
   Todo color vive aquí: es lo que permite que el modo oscuro sea un solo bloque al final
   del archivo en vez de una segunda hoja de estilos. Los pares (texto sobre su fondo) se
   midieron con la fórmula WCAG en ambos modos; ninguno baja de 4.5:1. */
:root {
    color-scheme: light;

    --tinta: #1c2733;
    --tinta-suave: #5b6b7c;
    --fondo: #f4f6f8;
    --papel: #ffffff;
    --borde: #d9e0e7;

    --acento: #12507b;
    --acento-claro: #e7f0f7;
    --acento-texto: #ffffff;   /* texto sobre un fondo de acento */

    /* La barra es su propia pareja: en claro es el acento, en oscuro no puede serlo
       —texto blanco sobre azul claro no contrasta— y se va a un azul casi negro. */
    --barra-fondo: #12507b;
    --barra-texto: #ffffff;

    --exito: #1c6b45;   --exito-fondo: #e4f4ec;
    --error: #a32020;   --error-fondo: #fbe9e9;
    --aviso: #8a5a00;   --aviso-fondo: #fdf1d8;
    --info: #17537f;    --info-fondo: #e0ecf8;
    --violeta: #4b3b8f; --violeta-fondo: #e6e6fa;
    --neutro: #4a5a6a;  --neutro-fondo: #e9edf1;

    --radio: 8px;
}

* { box-sizing: border-box; }

body {
    margin: 0;
    font-family: system-ui, -apple-system, "Segoe UI", Roboto, sans-serif;
    font-size: 16px;
    line-height: 1.5;
    color: var(--tinta);
    background: var(--fondo);
}

h1 { font-size: 1.4rem; margin: 0 0 .75rem; }
h2 { font-size: 1.1rem; margin: 0 0 .5rem; }
code { font-family: ui-monospace, SFMono-Regular, Menlo, monospace; font-size: .85em; }
a { color: var(--acento); }

.oculto {
    position: absolute; width: 1px; height: 1px;
    overflow: hidden; clip: rect(0 0 0 0); white-space: nowrap;
}

/* Foco siempre visible. Azul sobre fondos claros y blanco dentro de la barra oscura,
   para que el indicador contraste en ambos casos. */
:focus-visible {
    outline: 3px solid var(--acento);
    outline-offset: 2px;
    border-radius: 2px;
}
.barra :focus-visible { outline-color: var(--barra-texto); }

/* Salto al contenido: invisible hasta recibir el foco con el tabulador. */
.salto {
    position: absolute; left: .5rem; top: -4rem; z-index: 20;
    padding: .6rem .9rem; background: var(--papel); color: var(--acento);
    border: 1px solid var(--acento); border-radius: var(--radio);
    font: inherit; font-size: .95rem; cursor: pointer;
    text-decoration: none; transition: top .15s ease-in-out;
}
.salto:focus { top: .5rem; }

/* El contenido es destino de foco por programa, no un control: no lleva recuadro propio.
   Quien salta ya ve que la página se movió, y el siguiente Tab sigue desde aquí. */
#contenido:focus { outline: none; }

/* Barra superior y navegación */
.barra {
    display: flex; align-items: center; gap: .5rem;
    padding: .6rem .8rem;
    background: var(--barra-fondo); color: var(--barra-texto);
    position: sticky; top: 0; z-index: 10;
}
.barra__marca { color: var(--barra-texto); text-decoration: none; font-weight: 600; flex: 1; }
.barra__menu {
    background: none; border: 1px solid rgba(255,255,255,.4); color: var(--barra-texto);
    border-radius: var(--radio); padding: .25rem .55rem; font-size: 1rem; cursor: pointer;
}
/* Buzón: el contador tiene que verse, pero sin gritar más que el nombre del sistema. */
.barra__avisos {
    display: inline-flex; align-items: center; gap: .35rem;
    color: var(--barra-texto); text-decoration: none; font-size: .95rem;
    padding: .35rem .5rem; border-radius: var(--radio); min-height: 44px;
}
.barra__avisos:hover { background: rgb(255 255 255 / .12); }
.barra__contador {
    background: var(--error); color: #fff; font-size: .72rem; font-weight: 700;
    border-radius: 99px; padding: .05rem .4rem; min-width: 1.35rem; text-align: center;
}
.barra__salir { margin: 0; }
.barra__salir .boton--texto { color: var(--barra-texto); }

/* Cerrada por defecto en móvil; el botón de menú agrega .nav--abierta. */
.nav { display: none; flex-direction: column; background: var(--papel); border-bottom: 1px solid var(--borde); }
.nav--abierta { display: flex; }
.nav a { padding: .8rem 1rem; text-decoration: none; border-bottom: 1px solid var(--borde); }
/* Página actual: no se marca solo con color, lleva además un borde de apoyo. */
.nav a[aria-current="page"] {
    font-weight: 700; color: var(--acento);
    background: var(--acento-claro); box-shadow: inset 3px 0 0 var(--acento);
}

.contenido { padding: 1rem; max-width: 60rem; margin: 0 auto; }
.pie { padding: 1rem; text-align: center; color: var(--tinta-suave); font-size: .85rem; }

/* Bloques */
.tarjeta {
    background: var(--papel); border: 1px solid var(--borde);
    border-radius: var(--radio); padding: 1rem; margin-bottom: 1rem;
}
.tarjeta--angosta { max-width: 26rem; margin: 2rem auto; }
.apagado { color: var(--tinta-suave); }
.descripcion { font-size: .85rem; margin: 0 0 .35rem; }

.aviso { padding: .7rem .9rem; border-radius: var(--radio); margin: 0 0 1rem; }
.aviso--exito { background: var(--exito-fondo); color: var(--exito); }
.aviso--error { background: var(--error-fondo); color: var(--error); }
.aviso--aviso { background: var(--aviso-fondo); color: var(--aviso); }

/* Con tres o cuatro avisos apilados la pantalla se vuelve inservible: cada uno se cierra.
   El flex vive solo aquí, no en .aviso: esa clase también la usan párrafos con <strong> y
   <code> dentro, y convertirlos en contenedores flex partiría el texto en trozos sueltos. */
.aviso--cerrable { display: flex; align-items: flex-start; gap: .5rem; }
.aviso--cerrable > span { flex: 1; }
.aviso__cerrar {
    flex: 0 0 auto; min-width: 1.75rem; min-height: 1.75rem;
    background: none; border: none; color: inherit;
    font-size: 1.25rem; line-height: 1; cursor: pointer; padding: 0;
}
.aviso__cerrar:hover { opacity: .7; }

/* Pastillas genéricas: sirven en cualquier pantalla y no significan un estado de solicitud.
   Para eso están las .estado--*, más abajo, que se reservan a los nueve estados del flujo. */
.pastilla {
    display: inline-block; padding: .05rem .45rem; border-radius: 99px;
    background: var(--acento-claro); color: var(--acento); font-size: .78rem;
}
.pastilla--exito { background: var(--exito-fondo); color: var(--exito); }
.pastilla--aviso { background: var(--aviso-fondo); color: var(--aviso); }
.pastilla--alerta { background: var(--error-fondo); color: var(--error); }
.pastilla--apagada { background: var(--neutro-fondo); color: var(--neutro); }

/* Formularios */
.formulario label { display: block; font-weight: 600; margin: .8rem 0 .25rem; font-size: .9rem; }
.formulario input, .formulario select {
    width: 100%; padding: .6rem; font-size: 1rem;
    border: 1px solid var(--borde); border-radius: var(--radio); background: var(--papel);
}
.formulario .casilla { display: flex; align-items: center; gap: .5rem; font-weight: 400; }
.formulario .casilla input { width: auto; }

/* La ficha de un material creció con los datos del inventario (dónde está, con qué técnica,
   cuántas quedan). Se agrupan para que el formulario siga leyéndose de corrido. */
.grupo-campos {
    border: 1px solid var(--borde); border-radius: var(--radio);
    padding: .2rem 1rem 1rem; margin: 1.4rem 0 0;
}
.grupo-campos legend { padding: 0 .4rem; font-weight: 600; font-size: .9rem; color: var(--neutro); }

/* Campo rechazado por el servidor. El rojo no es la única señal: debajo va el motivo,
   enlazado con aria-describedby, y el JS lleva el foco al primero al cargar. */
.formulario [aria-invalid="true"] { border-color: var(--error); border-width: 2px; background: var(--error-fondo); }
.error-campo { color: var(--error); font-size: .85rem; font-weight: 600; margin: .3rem 0 0; }
.error-campo::before { content: "⚠ "; }

/* El buscador de materiales no respondió. No es un error del usuario —escribir el código
   a mano sigue funcionando—, así que se avisa en ámbar y no en rojo. */
.aviso-fetch { color: var(--aviso); font-weight: 600; }
.aviso-fetch::before { content: "⚠ "; }

.boton {
    display: inline-block; padding: .55rem .9rem; font-size: .95rem;
    border: 1px solid var(--borde); border-radius: var(--radio);
    background: var(--papel); color: var(--tinta); text-decoration: none; cursor: pointer;
}
.boton--principal { background: var(--acento); border-color: var(--acento); color: var(--acento-texto); }
.boton--texto { background: none; border: none; color: var(--acento); padding: .7rem .6rem; }
/* Lo que borra, cancela o rechaza va en rojo: no debe parecerse a Guardar. */
.boton--peligro { color: var(--error); border-color: var(--error); }
.boton--peligro:hover { background: var(--error-fondo); }
/* Área táctil mínima recomendada (~44px) para todo lo que se toca con el dedo. */
.boton, .boton--texto { min-height: 44px; display: inline-flex; align-items: center; justify-content: center; }
.acciones { display: flex; gap: .5rem; align-items: center; margin-top: 1rem; }
.acciones--fijas { position: sticky; bottom: 0; background: var(--fondo); padding: .6rem 0; }

/* En móvil el grupo de botones baja a línea completa bajo el título: apretados junto al h1
   quedaban ilegibles y por debajo del área táctil. */
.titulo-accion {
    display: flex; flex-wrap: wrap; align-items: center;
    justify-content: space-between; gap: .5rem 1rem;
}
/* Solo el grupo de botones, no la pastilla de estado que también vive aquí. */
.titulo-accion__acciones { display: flex; flex-wrap: wrap; gap: .5rem; }
.buscador { display: flex; gap: .5rem; margin: .75rem 0 1rem; }
.buscador input { flex: 1; padding: .55rem; border: 1px solid var(--borde); border-radius: var(--radio); }

/* Enlace de acceso recién generado. Se muestra una única vez, así que el campo va ancho y
   en monoespaciada: hay que poder verlo entero y comprobar que se copió completo.
   min-width: 0 es lo que permite que un texto largo encoja dentro del flex en vez de
   desbordar la tarjeta hacia el lado. */
.enlace-generado { display: flex; flex-wrap: wrap; gap: .5rem; align-items: center; }
.enlace-generado input {
    flex: 1 1 18rem; min-width: 0; padding: .55rem;
    font-family: ui-monospace, SFMono-Regular, Menlo, monospace; font-size: .85rem;
    border: 1px solid var(--borde); border-radius: var(--radio);
    background: var(--fondo); color: var(--tinta);
}

/* Los tres reportes se enlazan entre sí: son la misma pregunta mirada de tres formas. */
.filtros--pestanas { display: flex; flex-wrap: wrap; gap: .5rem; }

/* Filtros del catálogo: apilados en móvil, en línea desde tablet. */
.filtros { display: grid; grid-template-columns: 1fr; gap: .5rem; margin: .75rem 0 1rem; }
.filtros input, .filtros select, .filtros button {
    padding: .55rem; font-size: .95rem;
    border: 1px solid var(--borde); border-radius: var(--radio); background: var(--papel);
}
.filtros button { background: var(--papel); cursor: pointer; }

/* Listados en fichas (mejor que una tabla en móvil) */
.fichas { list-style: none; margin: 0; padding: 0; }
.ficha {
    background: var(--papel); border: 1px solid var(--borde); border-radius: var(--radio);
    padding: .8rem; margin-bottom: .6rem;
}
.ficha--inactiva { opacity: .65; }
/* Aviso sin leer: barra lateral, no solo un color de fondo que se pierda al imprimir. */
.ficha--nueva { border-left: 4px solid var(--acento); background: var(--acento-claro); }
.ficha__cuerpo { display: flex; flex-direction: column; gap: .15rem; }
.ficha__cuerpo .pastilla { align-self: flex-start; }
.ficha__acciones { display: flex; flex-wrap: wrap; align-items: center; gap: .25rem; margin-top: .5rem; border-top: 1px solid var(--borde); padding-top: .4rem; }
.ficha__acciones form { margin: 0; }
/* El título completo de la ficha navega: un blanco grande, sin el subrayado de un enlace
   suelto en medio del texto. */
.ficha__enlace { text-decoration: none; }
.ficha__enlace:hover { text-decoration: underline; }

/* Estados de una solicitud: color por etapa del flujo. */
.estado--borrador  { background: var(--neutro-fondo); color: var(--neutro); }
.estado--enviada   { background: var(--info-fondo); color: var(--info); }
.estado--visada    { background: var(--violeta-fondo); color: var(--violeta); }
.estado--aprobada  { background: var(--exito-fondo); color: var(--exito); }
.estado--preparada { background: var(--aviso-fondo); color: var(--aviso); }
.estado--entregada { background: var(--exito-fondo); color: var(--exito); }
.estado--cerrada   { background: var(--neutro-fondo); color: var(--neutro); }
.estado--rechazada { background: var(--error-fondo); color: var(--error); }
.estado--cancelada { background: var(--error-fondo); color: var(--error); }

/* Ficha de datos y línea de tiempo del detalle de solicitud. */
.datos { margin: 0; display: grid; grid-template-columns: 1fr; gap: 0 1rem; }
.datos dt { font-weight: 600; font-size: .85rem; color: var(--tinta-suave); }
.datos dd { margin: 0 0 .5rem; }

.historial { margin: 0 0 1rem; padding-left: 1.1rem; }
.historial li { margin-bottom: .6rem; }
/* Un comentario no es un cambio de estado: se distingue sin sacarlo de la línea de tiempo. */
.hito--comentario::marker { color: var(--acento); }
.hito__texto {
    margin-top: .2rem; padding: .35rem .55rem;
    background: var(--fondo); border-left: 3px solid var(--borde); border-radius: var(--radio);
}
.hito--comentario .hito__texto { border-left-color: var(--acento); }

.linea-accion { display: inline-block; margin: 0 .35rem .35rem 0; }

/* Devoluciones: una fila por ítem, con su formulario al lado.
   (`pastilla--alerta` vivía aquí; está arriba con el resto de su familia.) */
.tarjeta--alerta { border-left: 4px solid var(--error); }
.devolucion-item { border-top: 1px solid var(--borde); padding-top: .7rem; margin-top: .7rem; }
.devolucion-item:first-of-type { border-top: none; padding-top: 0; margin-top: 0; }
.devolucion label { margin-top: .5rem; }
.agregar-item { border-top: 1px solid var(--borde); margin-top: 1rem; padding-top: .5rem; }

/* Combobox de materiales: lista propia, no el <datalist> nativo. */
.autocompletar { position: relative; }
.sugerencias {
    position: absolute; z-index: 15; left: 0; right: 0; top: 100%;
    list-style: none; margin: .15rem 0 0; padding: .25rem;
    max-height: 16rem; overflow-y: auto;
    background: var(--papel); border: 1px solid var(--borde);
    border-radius: var(--radio); box-shadow: 0 6px 18px rgb(0 0 0 / .12);
}
.sugerencia {
    display: flex; align-items: baseline; gap: .5rem; flex-wrap: wrap;
    padding: .5rem .6rem; min-height: 44px; border-radius: var(--radio); cursor: pointer;
}
/* El resaltado no depende solo del color: la opción activa además se marca en negrita. */
.sugerencia[aria-selected="true"] { background: var(--acento-claro); font-weight: 600; }
.sugerencia:hover { background: var(--acento-claro); }
.sugerencia__nombre { flex: 1; min-width: 0; }
.sugerencia__unidad { color: var(--tinta-suave); font-size: .8rem; }
.sugerencia__area {
    font-size: .72rem; padding: .05rem .4rem; border-radius: 99px;
    background: var(--acento-claro); color: var(--acento);
}
.sugerencia__donde, .sugerencia__existencia { color: var(--tinta-suave); font-size: .78rem; }
.sugerencia__donde::before { content: "📍 "; }

/* Encabezado de bloque dentro de una tabla (MATERIALES, SOLUCIONES…), como las bandas de
   color del formulario en papel. */
.fila-grupo th {
    background: var(--acento); color: var(--acento-texto);
    font-size: .72rem; letter-spacing: .04em; text-align: left; padding: .3rem .4rem;
}

/* Registros de auditoría y notificaciones */
.registro { padding: .8rem; }
.registro details { margin-top: .5rem; }
.registro summary { cursor: pointer; font-size: .85rem; }
.json {
    background: var(--fondo); border: 1px solid var(--borde); border-radius: var(--radio);
    padding: .5rem; margin: .25rem 0 .75rem; font-size: .8rem;
    white-space: pre-wrap; word-break: break-word; overflow-x: auto;
}

/* Pie de los listados largos: cuántos hay y cómo pasar de página. */
.paginacion { margin-top: 1rem; }
.paginacion p { margin: 0; }
.paginacion .acciones { margin-top: .5rem; }

/* Contadores del inicio: cada uno es un enlace grande a la bandeja ya filtrada. */
.pendientes { list-style: none; margin: 0; padding: 0; display: grid; gap: .5rem; }
.pendiente {
    display: flex; align-items: center; gap: .7rem;
    padding: .6rem .8rem; min-height: 44px;
    border: 1px solid var(--borde); border-left: 4px solid var(--acento);
    border-radius: var(--radio); background: var(--acento-claro);
    color: var(--tinta); text-decoration: none;
}
.pendiente:hover { border-color: var(--acento); }
.pendiente--urgente { border-left-color: var(--error); background: var(--error-fondo); }
.pendiente__total { font-size: 1.35rem; min-width: 2ch; text-align: right; color: var(--acento); }
.pendiente--urgente .pendiente__total { color: var(--error); }

.lista-enlaces { margin: 0; padding-left: 1.1rem; }
.claves { list-style: none; margin: 0; padding: 0; display: flex; flex-wrap: wrap; gap: .35rem; }
.claves li { background: var(--acento-claro); border-radius: var(--radio); padding: .15rem .45rem; }

/* Tablas. En móvil desplazan en horizontal dentro de su tarjeta.
   La clase se llamaba .tabla-permisos, pero la usaban las ocho tablas del sistema
   (materiales, importaciones, reportes…): el nombre mentía. */
.tabla-scroll { overflow-x: auto; -webkit-overflow-scrolling: touch; }
.tabla { width: 100%; min-width: 24rem; border-collapse: collapse; font-size: .9rem; }
.tabla th, .tabla td { padding: .45rem .3rem; border-bottom: 1px solid var(--borde); text-align: left; vertical-align: top; }
.tabla th { font-size: .75rem; text-transform: uppercase; color: var(--tinta-suave); }
.tabla .centro { text-align: center; }
.tabla .descripcion { display: block; }
.fila--efectiva code { font-weight: 700; }

/* Encabezado que ordena: se ve que es pulsable sin gritarlo. */
.orden { color: inherit; text-decoration: none; border-bottom: 1px dotted currentColor; }
.orden:hover { color: var(--acento); }
.orden--activa { color: var(--acento); font-weight: 700; border-bottom-style: solid; }

/* Barra proporcional de los reportes: una columna de números no se lee de un vistazo.
   Es decoración —los valores están en las celdas—, por eso va aria-hidden y no lleva
   leyenda propia: el orden de los segmentos es el mismo de las columnas. */
.grafico {
    display: flex; width: 100%; max-width: 14rem; height: 6px; margin-top: .3rem;
    border-radius: 99px; overflow: hidden; background: var(--neutro-fondo);
}
.grafico__parte--exito        { background: var(--exito); }
.grafico__parte--alerta       { background: var(--error); }
.grafico__parte--alerta-suave { background: var(--violeta); }
.grafico__parte--aviso        { background: var(--aviso); }

/* El radio de la matriz de permisos es diminuto: la etiqueta que lo envuelve le da un
   área táctil de 44px sin cambiar la apariencia. */
.celda-radio {
    display: flex; align-items: center; justify-content: center;
    min-height: 44px; min-width: 44px; margin: 0; cursor: pointer;
}
.celda-radio input[type="radio"] { width: 1.15rem; height: 1.15rem; }

@media (min-width: 48rem) {
    /* Los filtros se reparten según cuántos campos traiga cada formulario. */
    .filtros { grid-template-columns: repeat(auto-fit, minmax(9rem, 1fr)); align-items: center; }
    .datos { grid-template-columns: max-content 1fr; }
    .datos dt { text-align: right; }
    .devolucion { display: flex; align-items: center; gap: .5rem; margin-top: .5rem; }
    .devolucion label { margin: 0; }
    .devolucion select { width: auto; }
    .devolucion input[type="text"] { flex: 1; }
    .nav { display: flex; flex-direction: row; flex-wrap: wrap; }
    .nav a { border-bottom: none; }
    .nav a[aria-current="page"] { box-shadow: inset 0 -3px 0 var(--acento); }
    .barra__menu { display: none; }
    .ficha { display: flex; align-items: center; justify-content: space-between; gap: 1rem; }
    .ficha__cuerpo { flex: 1; min-width: 0; flex-direction: row; align-items: center; gap: .75rem; flex-wrap: wrap; }
    .ficha__acciones { flex: 0 0 auto; flex-wrap: nowrap; margin-top: 0; border-top: none; padding-top: 0; }
}

/* Impresión.
   Los reportes de consumo y de faltantes son justo lo que alguien imprime o guarda en PDF
   para llevar a una reunión, y salían con barra, menú, filtros y botones ocupando la
   primera página. Aquí se deja solo el contenido. */
@media print {
    /* Fondos claros y tinta negra: ahorra tóner y se lee mejor fotocopiado. */
    body { background: #fff; color: #000; font-size: 11pt; }

    /* Cromo de la aplicación: no aporta nada en papel. Ningún botón funciona impreso,
       así que se van todos, incluidos los que viven sueltos junto a un título. */
    .barra, .nav, .pie, .salto, .filtros, .buscador, .acciones,
    .ficha__acciones, .aviso__cerrar, .boton { display: none !important; }

    .contenido { max-width: none; padding: 0; }
    .tarjeta { border: none; padding: 0; margin: 0 0 .8rem; break-inside: avoid; }

    /* Sin scroll horizontal en papel: la tabla se imprime completa y encoge si hace falta. */
    .tabla-scroll { overflow: visible; }
    .tabla { min-width: 0; font-size: 10pt; }
    .tabla th, .tabla td { border-bottom: 1px solid #999; }
    thead { display: table-header-group; }  /* el encabezado se repite en cada página */
    tr, .ficha { break-inside: avoid; }

    /* Las pastillas pierden el color de fondo: en blanco y negro no distinguen nada.
       El texto que llevan dentro ya dice cuál es el estado. */
    .pastilla { border: 1px solid #666; background: none !important; color: #000 !important; }

    /* La barra sí conserva el color: ahí el color *es* el dato, no un adorno, y sin él
       saldría una franja gris que no dice nada. */
    .grafico, .grafico__parte { -webkit-print-color-adjust: exact; print-color-adjust: exact; }

    /* Un enlace impreso no se puede pulsar; el destino se escribe al lado. */
    a { color: #000; text-decoration: none; }
    .contenido a[href^="http"]::after { content: " (" attr(href) ")"; font-size: 9pt; }
}

/* Modo oscuro.
   Sigue la preferencia del sistema: no hay interruptor propio porque en macOS, Windows y
   Android eso ya se decide una vez para todo el equipo, y un segundo interruptor solo
   agrega una pantalla más de configuración que mantener.

   Es únicamente esta redefinición de la paleta: ninguna regla de arriba conoce un color
   literal, así que no hay una segunda hoja de estilos que se pueda desincronizar. */
@media (prefers-color-scheme: dark) {
    :root {
        color-scheme: dark;   /* que los controles nativos y las barras también se oscurezcan */

        --tinta: #e3eaf2;
        --tinta-suave: #a3b3c4;
        --fondo: #10171f;
        --papel: #19222d;
        --borde: #2e3b4a;

        /* El azul institucional a oscuras es ilegible como texto: se aclara para el texto y
           se conserva profundo para los fondos. */
        --acento: #79b8e8;
        --acento-claro: #1b2c3b;
        --acento-texto: #10171f;

        --barra-fondo: #0c1620;
        --barra-texto: #e3eaf2;

        --exito: #74d3a0;   --exito-fondo: #14301f;
        --error: #ff9b9b;   --error-fondo: #3a1b1b;
        --aviso: #e5b96a;   --aviso-fondo: #322612;
        --info: #86c0ec;    --info-fondo: #14293b;
        --violeta: #b7abf2; --violeta-fondo: #241f3c;
        --neutro: #aab8c6;  --neutro-fondo: #232d38;
    }

    /* El borde del botón de menú es blanco translúcido: sirve igual sobre la barra oscura. */

    /* Las tarjetas en oscuro se distinguen por ser más claras que el fondo, no por sombra. */
    .json { background: #0b1219; }
}
