/*
 * LA HOJA DE ESTILOS DE LA CONSOLA
 * ================================
 *
 * Una sola, sin preprocesador y sin empaquetador, igual que `apps/sharetrip/publico/estilos.css`.
 *
 * ── 1 · NI UN LITERAL DE COLOR FUERA DE ESTE BLOQUE ─────────────────────────────────
 *
 * Los cuatro temas son copia literal de `apps/aliados/src/theme/colors.ts` —46 tokens por
 * tema, cuatro temas—, con el nombre traducido de `camelCase` a `kebab-case` y nada más:
 * `goldFg` es `--gold-fg`. La correspondencia es mecánica a propósito, para que quien
 * compare las dos listas no tenga que traducir nombres.
 *
 * **Debajo de este bloque no hay un solo `#` ni un solo `rgb(`.** Todo el resto de la hoja
 * usa `var(--…)`. Es la misma regla que la app de aliados aplica a `StyleSheet.create`, y
 * aquí vale más todavía: un color a mano en una consola que se mira ocho horas al día es lo
 * que hace que el modo claro tenga una tarjeta oscura y nadie sepa de dónde salió.
 *
 * ── 2 · TRES NIVELES TIPOGRÁFICOS QUE SE DISTINGUEN DE UN VISTAZO ───────────────────
 *
 * Es la corrección concreta que pidió el dueño después de ver la app móvil: los encabezados
 * de sección y las etiquetas de campo salían **idénticos** —mismo tamaño, mismo tono, las
 * mismas versalitas— y el resultado era una pared de texto en la que no se sabía qué
 * agrupaba a qué. Aquí los tres niveles cambian en **cinco** ejes a la vez, no en uno:
 *
 *   | Nivel      | Familia           | Tamaño | Peso | Caja      | Tono      |
 *   |------------|-------------------|--------|------|-----------|-----------|
 *   | `.seccion` | Instrument Serif  | 21 px  | 400  | normal    | `--fg`    |
 *   | `.etiqueta`| Inter Tight       | 11 px  | 600  | VERSALITA | `--soft`  |
 *   | `.ayuda`   | Inter Tight       | 12.5px | 400  | normal    | `--muted` |
 *
 * Con una diferencia sola —pongamos el tamaño— dos niveles se confunden en cuanto uno de los
 * dos textos es corto. Con cinco, se distinguen incluso en una fila de tabla apretada. Las
 * versalitas viven **sólo** en la etiqueta: son la marca de «esto rotula el dato de al
 * lado», y si también las llevara el encabezado dejarían de significar eso.
 *
 * **Y el tono está MEDIDO, no elegido a ojo.** Es la corrección que hubo que hacer el 2 de
 * agosto de 2026: `.etiqueta` usaba `--dim`, que da entre 3,07:1 y 4,11:1 y no llega ni al
 * 4,5:1 de AA. Los tres niveles usan ahora los mismos tres roles que
 * `apps/aliados/src/theme/jerarquia.ts`, y la escalera es **estrictamente decreciente en los
 * cuatro temas** (razón de contraste sobre `--bg`):
 *
 *   | Nivel      | Token     | dark  | light | indigo-dark | indigo-light |
 *   |------------|-----------|-------|-------|-------------|--------------|
 *   | `.seccion` | `--fg`    | 17,65 | 17,03 | 17,62       | 16,78        |
 *   | `.etiqueta`| `--soft`  | 11,86 |  9,58 | 11,74       |  9,67        |
 *   | `.ayuda`   | `--muted` |  6,16 |  4,59 |  6,18       |  4,86        |
 *
 * Los tres pasan AA en los cuatro temas, y ninguna de esas doce cifras está escrita a mano:
 * las calcula `pruebas/jerarquia.test.js` leyendo esta misma hoja. Cambiar un token mueve la
 * cifra y la prueba cae con la escalera delante.
 *
 * ── 3 · DENSIDAD: ESTO ES UNA HERRAMIENTA DE TRABAJO ────────────────────────────────
 *
 * Una consola no es una portada. Las filas son de 40 px y no de 64, el interlineado es 1.35
 * y no 1.7, y las tablas llevan hilo de separación en vez de tarjetas con sombra: lo que se
 * hace aquí es comparar la fila doce con la cuarenta, y para eso hay que verlas a la vez.
 * Los números van tabulares y alineados a la derecha, que es lo que permite comparar
 * `1.284` con `987` sin leerlos.
 */

@font-face {
  font-family: 'Instrument Serif';
  src: url('/fuentes/InstrumentSerif-400.woff') format('woff');
  font-weight: 400;
  font-style: normal;
  /* `swap`: primero se lee con la fuente del sistema y luego cambia. Una consola en blanco
     durante 300 ms mientras baja una tipografía es peor que una tipografía que salta. */
  font-display: swap;
}

@font-face {
  font-family: 'Inter Tight';
  src: url('/fuentes/InterTight-400.woff') format('woff');
  font-weight: 400;
  font-style: normal;
  font-display: swap;
}
@font-face {
  font-family: 'Inter Tight';
  src: url('/fuentes/InterTight-500.woff') format('woff');
  font-weight: 500;
  font-style: normal;
  font-display: swap;
}
@font-face {
  font-family: 'Inter Tight';
  src: url('/fuentes/InterTight-600.woff') format('woff');
  font-weight: 600;
  font-style: normal;
  font-display: swap;
}
@font-face {
  font-family: 'Inter Tight';
  src: url('/fuentes/InterTight-700.woff') format('woff');
  font-weight: 700;
  font-style: normal;
  font-display: swap;
}

/* ═══════════════════════════════════════════════ los cuatro temas, tal cual la app */

[data-tema='dark'] {
  --outer: #07080B;
  --bg: #0B0D12;
  --panel: #101319;
  --panel2: #151922;
  --fg: #F4F4F2;
  --soft: #C7CAD3;
  --muted: #8C919E;
  --dim: #6E7382;
  --dim2: #5D626F;
  --dim3: #4E5361;
  --faint: #3C4354;
  --accent: #9FBBFF;
  --gold: #35D6B0;
  --gold-fg: #04221B;
  --green: #7BC98F;
  --red: #E5715F;
  --btn-bg: #F4F4F2;
  --btn-fg: #0B0D12;
  --knob: #F4F4F2;
  --bar: #3C4354;
  --bar-dim: #2A2F3C;
  --line1: rgba(255,255,255,.06);
  --line2: rgba(255,255,255,.08);
  --line3: rgba(255,255,255,.11);
  --line4: rgba(255,255,255,.14);
  --line5: rgba(255,255,255,.2);
  --line6: rgba(255,255,255,.28);
  --gold-line: rgba(53,214,176,.34);
  --gold-line2: rgba(53,214,176,.55);
  --red-line: rgba(229,113,95,.28);
  --red-line2: rgba(229,113,95,.5);
  --nav-bg: rgba(11,13,18,.94);
  --scrim: rgba(5,6,9,.72);
  --notif-bg: rgba(26,29,38,.94);
  --glow: rgba(143,178,255,.07);
  --shell-shadow: rgba(0,0,0,.7);
  --teal: #35D6B0;
  --teal-dim: #1E8F7B;
  --teal-line: rgba(53,214,176,.28);
  --teal-wash: rgba(53,214,176,.10);
  --glass-bg: rgba(255,255,255,.055);
  --glass-bd: rgba(255,255,255,.10);
  --tile: rgba(255,255,255,.028);
  --tile-bd: rgba(180,215,205,.09);
  --tile-icon: rgba(178,214,201,.20);
  --tile-glow: rgba(53,214,176,.10);
}

[data-tema='light'] {
  --outer: #E6E4DF;
  --bg: #FAF9F6;
  --panel: #FFFFFF;
  --panel2: #F1EFEA;
  --fg: #14171E;
  --soft: #3C424E;
  --muted: #6B7280;
  --dim: #8A8F9C;
  --dim2: #A3A8B3;
  --dim3: #B8BCC5;
  --faint: #C9CCD3;
  --accent: #2F58C4;
  --gold: #0B7A66;
  --gold-fg: #FFFFFF;
  --green: #1F7A4C;
  --red: #C0392B;
  --btn-bg: #14171E;
  --btn-fg: #FAF9F6;
  --knob: #FFFFFF;
  --bar: #C9CCD3;
  --bar-dim: #E2E0DA;
  --line1: rgba(20,23,30,.06);
  --line2: rgba(20,23,30,.09);
  --line3: rgba(20,23,30,.13);
  --line4: rgba(20,23,30,.17);
  --line5: rgba(20,23,30,.24);
  --line6: rgba(20,23,30,.34);
  --gold-line: rgba(11,122,102,.30);
  --gold-line2: rgba(11,122,102,.5);
  --red-line: rgba(192,57,43,.28);
  --red-line2: rgba(192,57,43,.5);
  --nav-bg: rgba(250,249,246,.94);
  --scrim: rgba(30,28,24,.45);
  --notif-bg: rgba(255,255,255,.96);
  --glow: rgba(47,88,196,.07);
  --shell-shadow: rgba(60,56,48,.22);
  --teal: #0E8F79;
  --teal-dim: #0B6E5D;
  --teal-line: rgba(14,143,121,.30);
  --teal-wash: rgba(14,143,121,.09);
  --glass-bg: rgba(255,255,255,.55);
  --glass-bd: rgba(20,23,30,.10);
  --tile: rgba(20,23,30,.030);
  --tile-bd: rgba(14,143,121,.13);
  --tile-icon: rgba(20,80,68,.20);
  --tile-glow: rgba(14,143,121,.08);
}

[data-tema='indigo-dark'] {
  --outer: #05060E;
  --bg: #0A0C17;
  --panel: #10131F;
  --panel2: #161A29;
  --fg: #F3F3F8;
  --soft: #C6C8D8;
  --muted: #8C90A7;
  --dim: #6E7289;
  --dim2: #5D6178;
  --dim3: #4E5269;
  --faint: #3D425B;
  --accent: #A9B6FF;
  --gold: #8E93FF;
  --gold-fg: #0B0C26;
  --green: #7BC98F;
  --red: #E5715F;
  --btn-bg: #F3F3F8;
  --btn-fg: #0A0C17;
  --knob: #F3F3F8;
  --bar: #3D425B;
  --bar-dim: #292E42;
  --line1: rgba(255,255,255,.06);
  --line2: rgba(255,255,255,.08);
  --line3: rgba(255,255,255,.11);
  --line4: rgba(255,255,255,.14);
  --line5: rgba(255,255,255,.2);
  --line6: rgba(255,255,255,.28);
  --gold-line: rgba(142,147,255,.34);
  --gold-line2: rgba(142,147,255,.55);
  --red-line: rgba(229,113,95,.28);
  --red-line2: rgba(229,113,95,.5);
  --nav-bg: rgba(10,12,23,.94);
  --scrim: rgba(4,5,12,.72);
  --notif-bg: rgba(24,28,44,.94);
  --glow: rgba(150,160,255,.08);
  --shell-shadow: rgba(0,0,0,.7);
  --teal: #8E93FF;
  --teal-dim: #5A5FD1;
  --teal-line: rgba(142,147,255,.28);
  --teal-wash: rgba(142,147,255,.10);
  --glass-bg: rgba(255,255,255,.055);
  --glass-bd: rgba(255,255,255,.10);
  --tile: rgba(255,255,255,.028);
  --tile-bd: rgba(190,195,255,.09);
  --tile-icon: rgba(185,190,255,.20);
  --tile-glow: rgba(142,147,255,.10);
}

[data-tema='indigo-light'] {
  --outer: #E4E3EF;
  --bg: #F8F8FC;
  --panel: #FFFFFF;
  --panel2: #EFEFF7;
  --fg: #15162B;
  --soft: #3D3F58;
  --muted: #686C86;
  --dim: #888BA3;
  --dim2: #A1A4BA;
  --dim3: #B6B9CB;
  --faint: #C7CAD8;
  --accent: #3B45C0;
  --gold: #3F3DBE;
  --gold-fg: #FFFFFF;
  --green: #1F7A4C;
  --red: #C0392B;
  --btn-bg: #15162B;
  --btn-fg: #F8F8FC;
  --knob: #FFFFFF;
  --bar: #C7CAD8;
  --bar-dim: #E2E1EC;
  --line1: rgba(21,22,43,.06);
  --line2: rgba(21,22,43,.09);
  --line3: rgba(21,22,43,.13);
  --line4: rgba(21,22,43,.17);
  --line5: rgba(21,22,43,.24);
  --line6: rgba(21,22,43,.34);
  --gold-line: rgba(63,61,190,.30);
  --gold-line2: rgba(63,61,190,.5);
  --red-line: rgba(192,57,43,.28);
  --red-line2: rgba(192,57,43,.5);
  --nav-bg: rgba(248,248,252,.94);
  --scrim: rgba(24,24,40,.45);
  --notif-bg: rgba(255,255,255,.96);
  --glow: rgba(59,69,192,.07);
  --shell-shadow: rgba(52,52,80,.22);
  --teal: #4C4FD8;
  --teal-dim: #3A3DAF;
  --teal-line: rgba(76,79,216,.30);
  --teal-wash: rgba(76,79,216,.09);
  --glass-bg: rgba(255,255,255,.55);
  --glass-bd: rgba(21,22,43,.10);
  --tile: rgba(21,22,43,.030);
  --tile-bd: rgba(76,79,216,.13);
  --tile-icon: rgba(45,46,120,.20);
  --tile-glow: rgba(76,79,216,.08);
}

/*
 * EL PRIMER PINTADO, ANTES DE QUE CORRA `tema.js`
 * ===============================================
 *
 * `:root` sin `data-tema` es lo que hay durante los milisegundos que tarda el módulo en
 * cargarse. Si aquí no hubiera nada, la consola arrancaría sin variables —fondo blanco,
 * texto negro— y cambiaría de golpe: el parpadeo que todo el mundo conoce. Se copia el tema
 * oscuro por defecto, y una consulta de medios pone el claro cuando el sistema lo pide.
 *
 * Los dos selectores llevan `:not([data-tema])` para que **pierdan** en cuanto `tema.js`
 * escribe el atributo: a partir de ahí manda la preferencia de la persona, no la del sistema.
 */
:root:not([data-tema]) {
  color-scheme: dark;
}
@media (prefers-color-scheme: light) {
  :root:not([data-tema]) {
    color-scheme: light;
  }
}

/* ═══════════════════════════════════════════════════════════ base */

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

html {
  /* Sin esto, el tema oscuro tiene barras de desplazamiento blancas. `tema.js` lo vuelve a
     poner al aplicar; esto es sólo para el primer pintado. */
  background: var(--bg);
}

body {
  margin: 0;
  background: var(--bg);
  color: var(--fg);
  font-family: 'Inter Tight', -apple-system, BlinkMacSystemFont, 'Segoe UI', system-ui, sans-serif;
  font-size: 14px;
  line-height: 1.35;
  -webkit-font-smoothing: antialiased;
  text-rendering: optimizeLegibility;
}

a {
  color: var(--accent);
  text-decoration: none;
}
a:hover {
  text-decoration: underline;
}

button,
input,
select,
textarea {
  font: inherit;
  color: inherit;
}

/*
 * El foco visible NO se quita, nunca.
 *
 * Es lo primero que borra cualquier «reset» y lo único que tiene quien navega con teclado
 * para saber dónde está. En una consola donde un `Enter` suspende una droguería, no saber
 * qué botón está enfocado es un clic a ciegas.
 */
:focus-visible {
  outline: 2px solid var(--accent);
  outline-offset: 2px;
  border-radius: 4px;
}

/* ═══════════════════════════════════ los tres niveles tipográficos · ver §2 */

.seccion {
  margin: 0;
  font-family: 'Instrument Serif', Georgia, 'Times New Roman', serif;
  font-size: 21px;
  font-weight: 400;
  line-height: 1.15;
  letter-spacing: 0;
  color: var(--fg);
}

.seccion--grande {
  font-size: 30px;
}

.etiqueta {
  display: block;
  font-family: 'Inter Tight', system-ui, sans-serif;
  font-size: 11px;
  font-weight: 600;
  line-height: 1.2;
  letter-spacing: 0.07em;
  text-transform: uppercase;
  /*
   * `--soft` y NO `--dim`, que es lo que había. Medido, no estimado: `--dim` da entre
   * **3,07:1 y 4,11:1** según el tema, por debajo del 4,5:1 que pide AA para texto normal.
   * Es exactamente el gris que `apps/aliados/src/theme/contraste.ts` declara **incapaz de
   * pintar texto**, y la consola había heredado el mismo error que el dueño ya había hecho
   * corregir en la app móvil. Con `--soft` la etiqueta queda en 9,58–11,86:1.
   *
   * Los números de los cuatro temas los mide `pruebas/jerarquia.test.js`, que además exige
   * que la escalera sea estrictamente decreciente. Si alguien cambia un token, esa prueba
   * cae con las tres cifras delante — que es lo que impide que esto se vuelva a torcer sin
   * que nadie lo note.
   */
  color: var(--soft);
}

.ayuda {
  margin: 0;
  font-size: 12.5px;
  font-weight: 400;
  line-height: 1.45;
  letter-spacing: 0;
  text-transform: none;
  color: var(--muted);
}

/* El dato en sí. No es un nivel de rótulo: es lo que se viene a leer. */
.dato {
  font-size: 14px;
  font-weight: 500;
  color: var(--fg);
}
.dato--vacio {
  color: var(--dim2);
  font-weight: 400;
}
.dato--numero {
  font-variant-numeric: tabular-nums;
}

/* ═══════════════════════════════════════════════════════════ el armazón */

.armazon {
  display: grid;
  grid-template-columns: 224px minmax(0, 1fr);
  min-height: 100vh;
}

.lateral {
  display: flex;
  flex-direction: column;
  gap: 18px;
  padding: 18px 14px;
  border-right: 1px solid var(--line2);
  background: var(--panel);
  position: sticky;
  top: 0;
  height: 100vh;
  overflow-y: auto;
}

.marca {
  display: flex;
  align-items: baseline;
  gap: 7px;
  padding: 2px 8px 0;
}
.marca__nombre {
  font-family: 'Instrument Serif', Georgia, serif;
  font-size: 22px;
  line-height: 1;
  color: var(--fg);
}
.marca__renglon {
  font-size: 10.5px;
  font-weight: 500;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--teal);
}

.navegacion {
  display: flex;
  flex-direction: column;
  gap: 1px;
}

/*
 * El rótulo de un grupo de la barra. Mismo trato visual que `.etiqueta` —versalitas, 600—
 * pero en un tono más apagado a propósito: rotula navegación, no un dato, y no debe
 * competir con los enlaces que agrupa. El aire de arriba (14px) es lo que separa un bloque
 * del anterior sin necesitar un filete.
 */
.navegacion__grupo {
  margin: 14px 0 4px;
  padding: 0 10px;
  font-size: 10px;
  font-weight: 600;
  letter-spacing: 0.09em;
  text-transform: uppercase;
  color: var(--dim);
}
.navegacion__grupo:first-child {
  margin-top: 2px;
}

.navegacion__enlace {
  display: block;
  padding: 7px 10px;
  border: 1px solid transparent;
  border-radius: 8px;
  color: var(--soft);
  font-size: 13.5px;
  font-weight: 500;
  text-decoration: none;
}
.navegacion__cuerpo {
  display: flex;
  align-items: center;
  gap: 9px;
  min-width: 0;
}
.navegacion__titulo {
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.navegacion__enlace:hover {
  background: var(--tile);
  color: var(--fg);
  text-decoration: none;
}
/*
 * El activo se distingue por TRES cosas a la vez —lavado, filete y peso—, no por una: en
 * una barra de siete enlaces, un solo eje de diferencia se pierde en cuanto el tema es
 * claro. El borde va declarado transparente en el reposo para que activarse no mueva ni
 * un píxel el texto.
 */
.navegacion__enlace[aria-current='page'] {
  background: var(--teal-wash);
  border-color: var(--teal-line);
  color: var(--fg);
  font-weight: 600;
}
.navegacion__enlace[aria-current='page'] .icono {
  stroke: var(--teal);
}

/* Las teclas del atajo, a la derecha del enlace y sólo visibles con la barra en reposo. */
.navegacion__cuerpo .teclas {
  margin-left: auto;
}

/*
 * LOS ICONOS DE NAVEGACIÓN
 *
 * La tinta no viene en el SVG (`ilustraciones.js` no escribe ni un color): se hereda de
 * aquí. `currentColor` es lo que hace que el icono acompañe al texto en reposo, en hover y
 * en foco sin declarar tres variantes; el estado activo lo pinta la regla del enlace.
 */
.icono-marco {
  display: inline-flex;
  flex: 0 0 auto;
}
.icono {
  display: block;
  fill: none;
  stroke: currentColor;
  stroke-width: 1.5;
  stroke-linecap: round;
  stroke-linejoin: round;
  opacity: 0.85;
}

/*
 * UNA TECLA SE PINTA COMO TECLA
 *
 * Es la corrección de una queja literal del dueño: los atajos salían como letras grises
 * sueltas («g t») y se leían como texto roto. Un `<kbd>` con borde, fondo y monoespaciada
 * se reconoce como tecla sin leyenda. El tono es de los apagados de la escalera porque es
 * una pista, no un dato: quien no usa el teclado no debe ni fijarse.
 */
.teclas {
  display: inline-flex;
  gap: 3px;
  flex: 0 0 auto;
}
.tecla {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  min-width: 16px;
  height: 16px;
  padding: 0 4px;
  border: 1px solid var(--line3);
  border-bottom-width: 2px;
  border-radius: 4px;
  background: var(--panel2);
  font-family: ui-monospace, SFMono-Regular, Menlo, monospace;
  font-size: 10px;
  line-height: 1;
  color: var(--dim);
}

/*
 * La marca de «esta sección todavía no está construida».
 *
 * Va en la barra y no sólo dentro de la pantalla porque la pregunta que responde —«¿ya
 * puedo hacer esto?»— se hace antes de entrar. Enseñar el enlace como si funcionara y
 * descubrirlo al llegar es hacer perder un clic cada vez.
 */
.navegacion__pendiente {
  margin-left: auto;
  padding: 1px 6px;
  border: 1px solid var(--line3);
  border-radius: 999px;
  font-size: 9.5px;
  font-weight: 600;
  letter-spacing: 0.04em;
  text-transform: uppercase;
  color: var(--dim2);
}

.lateral__pie {
  margin-top: auto;
  display: flex;
  flex-direction: column;
  gap: 10px;
  padding: 12px 8px 0;
  border-top: 1px solid var(--line2);
}

/*
 * EL PIE DE LA BARRA: QUIÉN, DÓNDE, Y LOS AJUSTES — COMPUESTO, NO APILADO
 *
 * Era una columna de textos sueltos y así lo leyó el dueño («texto suelto»). Ahora la
 * cuenta es una pieza —inicial en su círculo, y al lado nombre, correo y base— y debajo
 * van las dos filas de ajustes. La inicial no es adorno: en una pantalla compartida del
 * equipo, saber DE QUIÉN es la sesión abierta se resuelve de un vistazo desde la otra
 * punta de la mesa.
 */
.quien {
  display: flex;
  align-items: center;
  gap: 9px;
  min-width: 0;
  padding: 8px;
  border: 1px solid var(--line2);
  border-radius: 10px;
  background: var(--tile);
}
.quien__inicial {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  flex: 0 0 auto;
  width: 30px;
  height: 30px;
  border-radius: 50%;
  border: 1px solid var(--teal-line);
  background: var(--teal-wash);
  color: var(--teal);
  font-family: 'Instrument Serif', Georgia, serif;
  font-size: 16px;
}
.quien__datos {
  display: flex;
  flex-direction: column;
  gap: 1px;
  min-width: 0;
}
.quien__nombre {
  font-size: 13px;
  font-weight: 600;
  color: var(--fg);
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.quien__correo {
  font-size: 11.5px;
  color: var(--muted);
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.lateral__acciones {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 6px;
}

/*
 * CONTRA QUÉ BASE SE ESTÁ TRABAJANDO.
 *
 * Monoespaciada y a 11 px: es un identificador de sistema, no prosa, y en monoespaciada se
 * distingue `consola_ensayo` de `consola-ensayo` de un vistazo. Va al pie de la barra, bajo
 * el correo, porque «quién soy» y «dónde estoy» son la misma pregunta partida en dos.
 *
 * El tono es `--dim3`, de los más apagados de la escalera, y eso es deliberado: tiene que
 * estar SIEMPRE a la vista sin competir con la navegación. Un dato que sólo aparece cuando
 * algo falla no evita el fallo caro, que es trabajar media mañana contra la base equivocada
 * sin que nada dé error.
 */
.quien__base {
  font-family: ui-monospace, SFMono-Regular, Menlo, monospace;
  font-size: 11px;
  color: var(--dim3);
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
/* Sin dato, la raya: la misma regla 6 que aplica `campo()` en `iu.js`. */
.quien__base--vacia {
  color: var(--faint);
}

/* ═══════════════════════════════════════════════════════════ el lienzo */

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

.encabezado {
  display: flex;
  align-items: center;
  gap: 14px;
  padding: 14px 22px;
  border-bottom: 1px solid var(--line2);
  background: var(--nav-bg);
  position: sticky;
  top: 0;
  z-index: 5;
  backdrop-filter: saturate(1.4) blur(12px);
}
.encabezado__titulo {
  display: flex;
  flex-direction: column;
  gap: 3px;
  min-width: 0;
}
.encabezado__acciones {
  margin-left: auto;
  display: flex;
  align-items: center;
  gap: 8px;
}

.contenido {
  padding: 20px 22px 56px;
  min-width: 0;
}

.bloque {
  display: flex;
  flex-direction: column;
  gap: 12px;
  margin-bottom: 26px;
}
.bloque__cabecera {
  display: flex;
  align-items: baseline;
  gap: 12px;
  flex-wrap: wrap;
}
.bloque__cabecera .ayuda {
  flex: 1 1 260px;
}

/* ═══════════════════════════════════════════════════════════ superficies */

.tarjeta {
  border: 1px solid var(--line3);
  border-radius: 12px;
  background: var(--panel);
  padding: 16px;
}

.rejilla {
  display: grid;
  gap: 12px;
  grid-template-columns: repeat(auto-fill, minmax(210px, 1fr));
}

/* El par etiqueta + dato. Es la unidad de una ficha. */
.campo {
  display: flex;
  flex-direction: column;
  gap: 4px;
  min-width: 0;
}
.campo__valor {
  font-size: 14px;
  font-weight: 500;
  color: var(--fg);
  overflow-wrap: anywhere;
}
.campo__valor--vacio {
  color: var(--dim2);
  font-weight: 400;
}

/* ═══════════════════════════════════════════════════════════ tablas */

.tabla-marco {
  border: 1px solid var(--line3);
  border-radius: 12px;
  background: var(--panel);
  /* La tabla se desplaza DENTRO de su marco. Sin esto, una tabla ancha desplaza la página
     entera y la barra lateral se va con ella. */
  overflow-x: auto;
}

.tabla {
  width: 100%;
  border-collapse: collapse;
  font-size: 13.5px;
}

.tabla th {
  position: sticky;
  top: 0;
  z-index: 1;
  padding: 9px 12px;
  background: var(--panel2);
  border-bottom: 1px solid var(--line3);
  text-align: left;
  font-family: 'Inter Tight', system-ui, sans-serif;
  font-size: 11px;
  font-weight: 600;
  letter-spacing: 0.07em;
  text-transform: uppercase;
  color: var(--dim);
  white-space: nowrap;
}

.tabla td {
  padding: 9px 12px;
  border-bottom: 1px solid var(--line1);
  vertical-align: middle;
  color: var(--soft);
}

.tabla tbody tr:last-child td {
  border-bottom: 0;
}

/*
 * Las filas se distinguen por hilo Y por franja alterna, no por una sola cosa.
 *
 * Con veinticinco filas de nombres largos, el hilo solo no basta: la mirada salta de línea
 * al volver del extremo derecho de la fila. La franja es del 3 % —lo justo para que el ojo
 * la siga sin que se lea como dos colores de fondo.
 */
.tabla tbody tr:nth-child(even) td {
  background: var(--tile);
}

.tabla tbody tr:hover td {
  background: var(--teal-wash);
  color: var(--fg);
}

.tabla__principal {
  color: var(--fg);
  font-weight: 500;
}
.tabla__numero {
  text-align: right;
  font-variant-numeric: tabular-nums;
}
.tabla__apretado {
  white-space: nowrap;
}

/* Una fila entera pinchable, sin meter un `<a>` en cada celda. */
.tabla tbody tr.tabla__fila--enlace {
  cursor: pointer;
}

/*
 * El foco de una fila pinchable se pinta POR DENTRO. El anillo global de `:focus-visible`
 * dibuja fuera del elemento, y en una tabla el anillo de una fila se corta contra las
 * vecinas y contra el marco con `overflow`. Quien recorre la tabla con Tab necesita ver
 * la fila enfocada entera, no un anillo mordido.
 */
.tabla tbody tr.tabla__fila--enlace:focus-visible {
  outline: none;
}
.tabla tbody tr.tabla__fila--enlace:focus-visible td {
  background: var(--teal-wash);
  color: var(--fg);
  box-shadow: inset 0 2px 0 var(--teal), inset 0 -2px 0 var(--teal);
}

/* ═══════════════════════════════════════════════════════════ distintivos */

.distintivo {
  display: inline-flex;
  align-items: center;
  gap: 5px;
  padding: 2px 8px;
  border: 1px solid var(--line3);
  border-radius: 999px;
  background: var(--tile);
  font-size: 11.5px;
  font-weight: 600;
  line-height: 1.5;
  color: var(--soft);
  white-space: nowrap;
}
.distintivo--marca {
  border-color: var(--teal-line);
  background: var(--teal-wash);
  color: var(--teal);
}
.distintivo--aviso {
  border-color: var(--gold-line);
  background: var(--tile);
  color: var(--gold);
}
.distintivo--malo {
  border-color: var(--red-line);
  background: var(--tile);
  color: var(--red);
}
.distintivo--apagado {
  color: var(--dim);
}

/* ═══════════════════════════════════════════════════════════ botones */

.boton {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 7px;
  padding: 8px 14px;
  border: 1px solid var(--line4);
  border-radius: 9px;
  background: var(--panel2);
  color: var(--fg);
  font-size: 13.5px;
  font-weight: 600;
  cursor: pointer;
  white-space: nowrap;
}
.boton:hover:not(:disabled) {
  border-color: var(--line6);
  background: var(--tile);
}
.boton:disabled {
  opacity: 0.45;
  cursor: not-allowed;
}

.boton--primario {
  border-color: transparent;
  background: var(--teal);
  color: var(--gold-fg);
}
.boton--primario:hover:not(:disabled) {
  background: var(--teal);
  border-color: var(--gold-line2);
}

.boton--peligro {
  border-color: var(--red-line2);
  color: var(--red);
  background: transparent;
}
.boton--peligro:hover:not(:disabled) {
  background: var(--tile);
  border-color: var(--red);
}

.boton--plano {
  border-color: transparent;
  background: transparent;
  color: var(--soft);
  padding: 6px 9px;
}
.boton--plano:hover:not(:disabled) {
  background: var(--tile);
  color: var(--fg);
}

.boton--pequeno {
  padding: 5px 10px;
  font-size: 12.5px;
}

/* ═══════════════════════════════════════════════════════════ formularios */

.formulario {
  display: flex;
  flex-direction: column;
  gap: 14px;
}

.control {
  display: flex;
  flex-direction: column;
  gap: 5px;
  min-width: 0;
}

.entrada,
.area,
.lista-desplegable {
  width: 100%;
  padding: 8px 11px;
  border: 1px solid var(--line3);
  border-radius: 9px;
  background: var(--bg);
  color: var(--fg);
  font-size: 14px;
}
.entrada:focus,
.area:focus,
.lista-desplegable:focus {
  border-color: var(--teal-line);
}
.entrada::placeholder,
.area::placeholder {
  color: var(--dim2);
}
.area {
  min-height: 84px;
  resize: vertical;
  line-height: 1.45;
}

/*
 * Las dos casillas que viven DENTRO de una tabla, en «Por publicar».
 *
 * `.entrada` mide el 100 % de su contenedor, que es lo correcto en un formulario y lo
 * contrario de lo que hace falta en una celda: un importe de cinco cifras estirado hasta el
 * ancho de la columna empuja las demás fuera de la pantalla. Se estrecha a la cifra más larga
 * que va a llevar y se alinea a la derecha, como el resto de los números de la tabla.
 *
 * Van aquí y no en un `style` en línea porque la política de contenido de la consola es
 * `style-src 'self'`: un atributo `style` no se aplicaría y la casilla saldría del ancho de
 * un formulario dentro de una celda, sin un solo error en consola.
 */
.entrada--precio {
  width: 10ch;
  padding: 6px 9px;
  text-align: right;
}
.marca-de-fila {
  accent-color: var(--teal);
  width: 15px;
  height: 15px;
}

/*
 * EL ECO DEL PRECIO — LO QUE SE VA A GUARDAR, DEBAJO DE LO QUE SE ESCRIBIÓ
 *
 * En «Por publicar» la casilla habla en pesos y la columna guarda centavos, y entre las dos
 * hay una lectura que puede salir mal: «12.500» son doce mil quinientos pesos en Colombia y
 * `Number('12.500')` es 12,5. El conversor ya lo resuelve (`publico/precio.js`); esto es lo
 * que hace que se VEA, porque un conversor correcto que nadie mira sigue dependiendo de que
 * nadie teclee mal.
 *
 * Alineado a la derecha bajo la casilla, con la misma anchura, para que la cifra de arriba y
 * la de abajo se comparen sin mover los ojos. En `--dim` y no en el color del texto normal:
 * es una confirmación, no un dato que haya que leer fila por fila cuando todo va bien.
 */
.celda-de-precio {
  display: inline-flex;
  flex-direction: column;
  align-items: flex-end;
  gap: 3px;
}
.eco-de-precio {
  max-width: 26ch;
  font-size: 12px;
  line-height: 1.35;
  color: var(--dim);
  text-align: right;
  /*
   * `white-space: normal` porque la columna es `apretado` y `.tabla__apretado` pone
   * `nowrap`: el importe convertido cabe en una línea, pero el MOTIVO por el que no se pudo
   * leer no, y se salía de la tabla cortado a media palabra —«Escríbelo s…»—. Un aviso
   * truncado justo donde dice qué hacer es un aviso que no sirve; visto en la primera
   * captura de esta pantalla, corregido antes de entregarla.
   */
  white-space: normal;
  overflow-wrap: anywhere;
}
/* El motivo por el que un importe no se pudo leer va en rojo: no es una confirmación, es algo
 * que hay que arreglar antes de publicar. Mismo color que `aviso--malo`, que es donde se
 * repite la lista al pulsar. */
.eco-de-precio.es-malo {
  color: var(--red);
}

.filtros {
  display: flex;
  flex-wrap: wrap;
  align-items: flex-end;
  gap: 10px;
}
.filtros .control {
  flex: 0 1 auto;
}
.filtros .entrada {
  min-width: 260px;
}

.casilla {
  display: inline-flex;
  align-items: center;
  gap: 7px;
  font-size: 13px;
  color: var(--soft);
  cursor: pointer;
  padding: 8px 0;
}
.casilla input {
  accent-color: var(--teal);
  width: 15px;
  height: 15px;
}

/* ═══════════════════════════════════════════════════════════ avisos */

.aviso {
  display: flex;
  flex-direction: column;
  gap: 3px;
  padding: 11px 14px;
  border: 1px solid var(--line3);
  border-radius: 10px;
  background: var(--panel2);
  font-size: 13.5px;
  color: var(--soft);
}
.aviso--malo {
  border-color: var(--red-line2);
  color: var(--red);
}
.aviso--bueno {
  border-color: var(--gold-line);
  color: var(--teal);
}

/*
 * El cintillo de «esto no es lo que crees».
 *
 * Se reserva para lo que, si no se dice, se toma por real. Hoy lo usa el aviso de que la
 * consola está hablando con datos de ensayo.
 */
.cintillo {
  padding: 7px 22px;
  border-bottom: 1px solid var(--gold-line);
  background: var(--teal-wash);
  color: var(--teal);
  font-size: 12.5px;
  font-weight: 600;
  letter-spacing: 0.02em;
}

/*
 * EL CINTILLO DE «SIN CONEXIÓN» — UN AVISO GLOBAL, NO UNO POR PANTALLA
 *
 * Existe por la mañana en que un `pkill` ajeno mató la API y el dueño leyó «nada
 * funciona»: cada pantalla fallaba por su cuenta y ninguna decía la causa común. Va fijo
 * abajo —no arriba— para no taparse con el encabezado pegajoso, y sobre `--notif-bg` con
 * el borde rojo: es una notificación del sistema, no un error de lo que se acaba de
 * pulsar. Quién lo enciende y lo apaga está en `api.js`.
 *
 * `[hidden]` se refuerza porque `display: flex` de la clase le ganaría al atributo, y un
 * cintillo de avería imposible de ocultar es una avería nueva.
 */
.conexion-caida {
  position: fixed;
  left: 50%;
  bottom: 18px;
  transform: translateX(-50%);
  z-index: 30;
  display: flex;
  align-items: baseline;
  gap: 5px;
  max-width: min(560px, calc(100vw - 32px));
  padding: 10px 16px;
  border: 1px solid var(--red-line2);
  border-radius: 12px;
  background: var(--notif-bg);
  color: var(--fg);
  font-size: 12.5px;
  box-shadow: 0 18px 50px -24px var(--shell-shadow);
}
.conexion-caida strong {
  color: var(--red);
  white-space: nowrap;
}
.conexion-caida span {
  color: var(--soft);
}
.conexion-caida[hidden] {
  display: none;
}

/* ═══════════════════════════════════════════════════════════ la hoja de atajos */

.hoja-de-atajos__fila {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 14px;
  padding: 6px 0;
  border-bottom: 1px solid var(--line1);
}
.hoja-de-atajos__fila:last-of-type {
  border-bottom: 0;
}
.hoja-de-atajos__que {
  font-size: 13px;
  color: var(--soft);
}

/* ═══════════════════════════════════════════════════════════ estados vacíos */

.vacio {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 10px;
  padding: 42px 24px;
  text-align: center;
}
.vacio__titulo {
  font-family: 'Instrument Serif', Georgia, serif;
  font-size: 20px;
  color: var(--fg);
}
.vacio .ayuda {
  max-width: 42ch;
}

/*
 * LAS CUATRO TINTAS DE LAS ILUSTRACIONES
 * ======================================
 *
 * `ilustraciones.js` no tiene ni un color: dibuja con estas clases y aquí se resuelven desde
 * el tema. El acento cambia con el tono del estado, que es la regla que traen las figuras de
 * la app de aliados: `empty` es marca —«todavía no ha pasado nada, y está bien»—, `search`
 * es azul —«tu búsqueda devolvió cero», hubo un gesto y no es una avería— y `error` es rojo,
 * con el lavado apagado, porque un fallo no se acompaña de un halo de marca.
 */
.figura {
  fill: none;
  stroke-width: 2;
  stroke-linecap: round;
  stroke-linejoin: round;
}
.figura .t-trazo {
  stroke: var(--soft);
}
.figura .t-tenue {
  stroke: var(--dim2);
}
.figura .t-acento {
  stroke: var(--teal);
}
.figura .r-lavado {
  fill: var(--teal-wash);
  stroke: none;
}
.figura .r-acento {
  fill: var(--teal);
  stroke: none;
}
.figura .r-tenue {
  fill: var(--tile);
  stroke: none;
}

.figura--search .t-acento {
  stroke: var(--accent);
}
.figura--search .r-acento {
  fill: var(--accent);
}
.figura--search .r-lavado {
  fill: var(--tile);
}

.figura--error .t-acento {
  stroke: var(--red);
}
.figura--error .r-acento {
  fill: var(--red);
}
.figura--error .r-lavado {
  fill: transparent;
}

/* ═══════════════════════════════════════════════════════════ la pantalla de acceso */

.acceso {
  display: flex;
  align-items: center;
  justify-content: center;
  min-height: 100vh;
  padding: 24px;
  background:
    radial-gradient(120% 80% at 50% 0%, var(--glow), transparent 60%),
    var(--bg);
}

.acceso__caja {
  width: 100%;
  max-width: 372px;
  display: flex;
  flex-direction: column;
  gap: 18px;
  padding: 26px;
  border: 1px solid var(--line3);
  border-radius: 16px;
  background: var(--panel);
  box-shadow: 0 24px 60px -30px var(--shell-shadow);
}

.acceso__marca {
  display: flex;
  flex-direction: column;
  gap: 4px;
}
.acceso__titulo {
  font-family: 'Instrument Serif', Georgia, serif;
  font-size: 32px;
  line-height: 1.05;
  color: var(--fg);
}

/* ═══════════════════════════════════════════════════════════ la ficha del medicamento */

.ficha {
  display: grid;
  grid-template-columns: minmax(0, 1fr) 300px;
  gap: 22px;
  align-items: start;
}

@media (max-width: 1080px) {
  .ficha {
    grid-template-columns: minmax(0, 1fr);
  }
}

@media (max-width: 820px) {
  .armazon {
    grid-template-columns: minmax(0, 1fr);
  }
  .lateral {
    position: static;
    height: auto;
    border-right: 0;
    border-bottom: 1px solid var(--line2);
  }
}

/*
 * EL RECUADRO DE LA FOTO — Y POR QUÉ TIENE DOS ESTADOS Y NO UNO
 * ============================================================
 *
 * Sin foto no se pinta un marco gris con un icono: se pinta la zona de soltar, porque lo que
 * falta ahí es un gesto y no un dato. Con foto se pinta la foto, y el gesto pasa a ser
 * «sustituir». Un solo estado obligaría a que el mismo recuadro dijera las dos cosas, y
 * acabaría diciendo la segunda mal.
 */
.foto {
  display: flex;
  flex-direction: column;
  gap: 10px;
}

.foto__marco {
  display: flex;
  align-items: center;
  justify-content: center;
  aspect-ratio: 4 / 3;
  border: 1px dashed var(--line4);
  border-radius: 12px;
  background: var(--panel2);
  color: var(--muted);
  text-align: center;
  padding: 18px;
  cursor: pointer;
}
.foto__marco:hover {
  border-color: var(--teal-line);
  background: var(--teal-wash);
}
.foto__marco--encima {
  border-color: var(--teal);
  border-style: solid;
  background: var(--teal-wash);
  color: var(--teal);
}
.foto__marco--puesta {
  border-style: solid;
  border-color: var(--line3);
  background: var(--panel2);
  padding: 0;
  overflow: hidden;
}
.foto__imagen {
  width: 100%;
  height: 100%;
  object-fit: contain;
  display: block;
}
.foto__soltar {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 6px;
}

/* ═══════════════════════════════════════════════════════════ paginación */

.paginacion {
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 4px 2px;
}
.paginacion__cuenta {
  font-size: 12.5px;
  color: var(--muted);
  font-variant-numeric: tabular-nums;
}
.paginacion__botones {
  margin-left: auto;
  display: flex;
  gap: 6px;
}

/* ═══════════════════════════════════════════════════════════ el diálogo */

.dialogo {
  border: 1px solid var(--line3);
  border-radius: 14px;
  background: var(--panel);
  color: var(--fg);
  padding: 0;
  width: min(440px, calc(100vw - 32px));
  box-shadow: 0 30px 80px -40px var(--shell-shadow);
}
.dialogo::backdrop {
  background: var(--scrim);
}
.dialogo__cuerpo {
  display: flex;
  flex-direction: column;
  gap: 14px;
  padding: 20px;
}
.dialogo__pie {
  display: flex;
  justify-content: flex-end;
  gap: 8px;
}

/* ═══════════════════════════════════════════════════════════ el cargando */

/*
 * Sin dato todavía NO es lo mismo que sin dato.
 *
 * Mientras la petición está en vuelo se dice «cargando…», no se pinta el estado vacío: un
 * estado vacío durante la carga afirma que no hay nada, y es exactamente la clase de
 * afirmación falsa que prohíbe la regla 6 del producto. Cuando la respuesta llega, o hay
 * filas o hay vacío, y las dos cosas son verdad.
 */
.cargando {
  display: flex;
  align-items: center;
  gap: 9px;
  padding: 34px 24px;
  justify-content: center;
  color: var(--muted);
  font-size: 13.5px;
}
.cargando::before {
  content: '';
  width: 13px;
  height: 13px;
  border: 2px solid var(--line5);
  border-top-color: var(--teal);
  border-radius: 50%;
  animation: girar 0.75s linear infinite;
}
@keyframes girar {
  to {
    transform: rotate(360deg);
  }
}
@media (prefers-reduced-motion: reduce) {
  .cargando::before {
    animation: none;
  }
}

/* Sólo para lectores de pantalla. */
.solo-lectores {
  position: absolute;
  width: 1px;
  height: 1px;
  padding: 0;
  margin: -1px;
  overflow: hidden;
  clip: rect(0 0 0 0);
  white-space: nowrap;
  border: 0;
}
