/* ==========================================================================
   Inventario VEX IQ — el club, ordenado
   Direccion: el estilo de Villacampa llevado a una herramienta de trabajo.
   Papel azulado, etiquetas mono en mayusculas, titulares grandes, tarjetas de
   borde fino, botones pastilla y las piezas siempre sobre fondo de contraste.
   Los colores y las fuentes salen de /design/tokens.css (contrato de diseno).
   ========================================================================== */
@import url('/design/tokens.css');

/* La unica pieza de paleta que no viene del contrato: el velo de los dialogos,
   el azul de tinta translucido. Todo lo demas de esta hoja sale de las
   variables de design/tokens.css. */
:root { --scrim: rgb(16 36 67 / 0.45); }

/* La linea fina con la que se dibujan las aristas de una pieza en el visor 3D
   del catalogo. La lee `constructor/app/tono.js` — el MISMO modulo del
   constructor, importado desde `app/viewer.js` —: tinta sobre el lienzo claro. */
:root { --lienzo-arista: #102443; }

/* --------------------------------------------------------------- base ---- */

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

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

body {
  margin: 0;
  min-height: 100dvh;
  background: var(--bg);
  color: var(--text);
  font-family: var(--font-text);
  font-size: var(--text-base);
  line-height: var(--leading-base);
  padding-bottom: calc(72px + env(safe-area-inset-bottom));
  -webkit-font-smoothing: antialiased;
}

h1, h2, h3, h4 {
  margin: 0;
  font-family: var(--font-display);
  font-weight: 700;
  letter-spacing: var(--tracking-3xl);
  line-height: var(--leading-3xl);
  color: var(--text);
  text-wrap: balance;
}

p { margin: 0; }
a { color: var(--link); }
img, video, canvas, svg { max-width: 100%; }
img { height: auto; }
button, input, select, textarea { font: inherit; color: inherit; }
button { -webkit-tap-highlight-color: transparent; }

:focus-visible {
  outline: 3px solid var(--focus);
  outline-offset: 2px;
  border-radius: var(--radius-sm);
}

::selection { background: var(--primary-soft); color: var(--text); }

.skip {
  position: absolute;
  left: -999px;
  top: 8px;
  z-index: 100;
  background: var(--accent);
  color: var(--on-accent);
  padding: 12px 16px;
  border-radius: var(--radius-pill);
  font-weight: 600;
  text-decoration: none;
}
.skip:focus { left: 12px; }

.oculto-visual {
  position: absolute; width: 1px; height: 1px; margin: -1px;
  clip-path: inset(50%); overflow: hidden; white-space: nowrap;
}

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

/* ----------------------------------------------------------- estructura -- */

.wrap { width: 100%; max-width: 1240px; margin-inline: auto; padding-inline: var(--space-4); }
@media (min-width: 720px) { .wrap { padding-inline: var(--space-5); } }

.main { display: block; min-height: 50vh; }

/* `hidden` manda SIEMPRE. Una clase con `display` (p. ej. `.campo { display:
   grid }`) gana a la regla del navegador y el bloque escondido se veia: la
   puerta enseñaba a la vez el codigo y el usuario con su contraseña. */
[hidden] { display: none !important; }

.pie {
  margin-top: var(--space-8);
  padding: var(--space-5) var(--space-4) var(--space-7);
  border-top: 1px solid var(--border);
  color: var(--text-muted);
  font-size: var(--text-xs);
  display: grid;
  gap: var(--space-2);
  max-width: 1240px;
  margin-inline: auto;
}
.pie__peq { color: var(--text-muted); }

/* --------------------------------------------------------------- topbar -- */

.topbar {
  position: sticky;
  top: 0;
  z-index: 30;
  background: var(--surface);
  border-bottom: 1px solid var(--border);
}

.topbar__in {
  max-width: 1240px;
  margin-inline: auto;
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--space-3);
  padding: var(--space-2) var(--space-4);
  min-height: 60px;
}
@media (min-width: 720px) { .topbar__in { padding-inline: var(--space-5); } }

.marca { display: flex; align-items: center; gap: var(--space-3); text-decoration: none; color: inherit; min-width: 0; }
/* El logo de Villacampa (escudo + nombre, para fondo claro): 525x134, a 34 px de
   alto mide 133. «Constructor» va a su lado como etiqueta pequena. */
.marca__logo { display: block; flex: 0 0 auto; height: 34px; width: auto; }
.marca__texto { min-width: 0; display: grid; gap: 2px; padding-left: var(--space-3); border-left: 1px solid var(--border); }
.marca__texto b { font-family: var(--font-mono); font-weight: 600; font-size: var(--text-xs); letter-spacing: 0.1em; text-transform: uppercase; color: var(--text-muted); white-space: nowrap; }
.marca__texto small {
  font-family: var(--font-mono); font-size: 12px; letter-spacing: 0.09em;
  text-transform: uppercase; color: var(--text-muted);
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}

.topbar__acciones { display: flex; align-items: center; gap: var(--space-2); }

.sync {
  display: inline-flex; align-items: center; gap: 8px;
  padding: 8px 12px; border-radius: var(--radius-pill);
  border: 1px solid var(--border); background: var(--surface);
  font-size: var(--text-xs); font-weight: 600; color: var(--text-muted);
  white-space: nowrap;
}
.sync::before { content: ""; width: 8px; height: 8px; border-radius: 50%; background: var(--border-strong); }
.sync--ok::before { background: var(--success); }
.sync--pendiente::before { background: var(--warning); }
.sync--sin-conexion::before { background: var(--danger); }
.sync--sincronizando::before { background: var(--info); }
.sync--solo-lectura { border-style: dashed; }

.cuenta__punto { width: 8px; height: 8px; border-radius: 50%; background: var(--border-strong); }
.cuenta__punto--activo { background: var(--success); }
.btn--cuenta { padding-inline: 16px; }

/* En pantallas pequenas el estado de sincronizacion vive en Ajustes: el chip
   apretaba el nombre y el titulo quedaba cortado. */
@media (max-width: 560px) {
  .sync { display: none; }
  .marca__texto b { overflow: hidden; text-overflow: ellipsis; }
  /* A 390 px la cabecera lleva icono + nombre + icono de perfil. El nombre no se
     parte ni se acorta a media palabra: la linea de debajo («216 piezas · kit
     2.a gen.») se va, y esa cuenta se lee dentro de la app. */
  .marca__texto small { display: none; }
}

/* ---------------------------------------------------------------- tabs --- */

.tabs { display: none; }

@media (min-width: 900px) {
  .tabs {
    display: flex; gap: var(--space-1);
    max-width: 1240px; margin-inline: auto;
    padding: 0 var(--space-5) var(--space-2);
    overflow-x: auto; scrollbar-width: none;
  }
  .tabs::-webkit-scrollbar { display: none; }
}

.tab {
  appearance: none; border: 1px solid transparent; background: transparent;
  color: var(--text-muted); font-weight: 600; font-size: var(--text-sm);
  padding: 8px 16px; border-radius: var(--radius-pill); cursor: pointer;
  white-space: nowrap; min-height: 38px;
  transition: background var(--dur-2) var(--ease-standard), color var(--dur-2), transform var(--dur-1);
}
.tab:hover { background: var(--primary-soft); color: var(--primary); }
.tab[aria-current="page"] { background: var(--accent); color: var(--on-accent); }
.tab:active { transform: scale(.97); }

/* --------------------------------------------------------------- bottom -- */

.bottom {
  position: fixed; inset-inline: 0; bottom: 0; z-index: 40;
  display: flex; align-items: flex-end; gap: 4px;
  background: var(--surface);
  border-top: 1px solid var(--border);
  padding: 8px max(8px, env(safe-area-inset-left)) calc(8px + env(safe-area-inset-bottom)) max(8px, env(safe-area-inset-right));
}
@media (min-width: 900px) { .bottom { display: none; } body { padding-bottom: 0; } }

.bottom__item {
  flex: 1 1 0; display: flex; flex-direction: column; align-items: center; gap: 4px;
  min-height: 52px; padding: 8px 4px; border: 0; background: none; cursor: pointer;
  color: var(--text-muted); font-size: 12px; font-weight: 600; letter-spacing: .01em;
  border-radius: var(--radius-sm);
}
.bottom__item svg { width: 22px; height: 22px; }
.bottom__item[aria-current="page"] { color: var(--accent); }
.bottom__item--scan .bottom__icono {
  display: grid; place-items: center;
  width: 46px; height: 46px; margin-top: -16px;
  border-radius: var(--radius-pill);
  background: var(--accent); color: var(--on-accent);
  box-shadow: var(--shadow-2);
  transition: transform var(--dur-2) var(--ease-enter);
}
.bottom__item--scan:active .bottom__icono { transform: scale(.94); }
.bottom__item--scan svg { width: 24px; height: 24px; }

/* --------------------------------------------------------------- botones -- */

.btn {
  display: inline-flex; align-items: center; justify-content: center; gap: 10px;
  border: 1px solid transparent; border-radius: var(--radius-pill);
  padding: 12px 24px; min-height: var(--control-h);
  font-weight: 600; font-size: var(--text-sm); line-height: 1.2;
  cursor: pointer; text-decoration: none; white-space: nowrap;
  transition: background var(--dur-2) var(--ease-standard), border-color var(--dur-2),
    color var(--dur-2), transform var(--dur-1) var(--ease-standard), box-shadow var(--dur-2);
}
.btn svg { width: 18px; height: 18px; flex: 0 0 auto; }
.btn:active { transform: scale(.98); }
/* .55 dejaba el texto de un boton deshabilitado en 3,6:1 (el «Volver al
   manifiesto» de Cantidades): con .7 pasa 5,7:1 y sigue leyendose apagado. */
.btn[disabled] { opacity: .7; cursor: not-allowed; transform: none; }

.btn--primary { background: var(--accent); color: var(--on-accent); }
.btn--primary:hover { background: var(--primary-hover); box-shadow: var(--shadow-2); }
/* El fantasma se ve POR su borde: es lo unico que dice donde empieza el boton
   sobre la superficie. Va en el gris estructural (3:1 o mas) y el hover se
   queda con el cambio de fondo, la senal que le queda al subir el de reposo. */
.btn--ghost { background: var(--surface); border-color: var(--border-strong); color: var(--text); }
.btn--ghost:hover { background: var(--primary-soft); }
.btn--quiet { background: transparent; color: var(--primary); padding-inline: 16px; }
.btn--quiet:hover { background: var(--primary-soft); }
.btn--peligro { background: var(--danger-soft); color: var(--danger); }
.btn--peligro:hover { background: var(--danger); color: var(--surface); }
/* Sin min-height propio: hereda el alto del .btn. En las filas que se tocan
   (conteo, conteo por colegio, cantidades) el objetivo tactil comodo es 44. */
.btn--sm { padding: 10px 16px; font-size: var(--text-xs); }
.btn--icono { width: 44px; padding: 0; }
.btn--ancho { width: 100%; }

.enlace-flecha {
  display: inline-flex; align-items: center; gap: 8px;
  font-weight: 600; font-size: var(--text-sm); color: var(--primary);
  text-decoration: none; min-height: 32px;
}
.enlace-flecha svg { width: 16px; height: 16px; transition: transform var(--dur-2) var(--ease-enter); }
.enlace-flecha:hover svg { transform: translateX(3px); }

/* -------------------------------------------------------------- etiquetas -- */

.eyebrow {
  display: inline-flex; align-items: center; gap: 8px;
  font-family: var(--font-mono); font-size: 12px; font-weight: 600;
  letter-spacing: 0.14em; text-transform: uppercase; color: var(--primary);
}
/* La marca que abre el eyebrow: un circulo con el signo + del set de iconos
   (ui.js). Antes era un glifo de texto; con el icono va del mismo trazo que
   los demas y no depende de la fuente del sistema. */
.eyebrow__marca {
  display: grid; place-items: center;
  width: 16px; height: 16px; flex: 0 0 auto;
  border: 1.5px solid currentColor; border-radius: var(--radius-pill);
}
.eyebrow--claro { color: var(--on-primary-soft); }

/* -------------------------------------------------------------- secciones -- */

/* La banda que abre cada pantalla: etiqueta mono + titular, sobre el tono de
   panel. Es el gesto de la referencia (sus secciones van en azul hielo) y lo
   que da al conjunto el 30 % de secundario del contrato. */
.banda {
  background: var(--surface-2);
  border-radius: var(--radius-lg);
  padding: var(--space-5);
  margin-top: var(--space-4);
}
@media (min-width: 900px) { .banda { padding: var(--space-6); } }

.seccion { margin-block: var(--space-6); }
.seccion:first-child { margin-top: var(--space-5); }

.seccion__cab {
  display: flex; flex-wrap: wrap; align-items: flex-end; justify-content: space-between;
  gap: var(--space-3); margin-bottom: var(--space-4);
}
.seccion__titulo { font-size: var(--text-2xl); letter-spacing: var(--tracking-4xl); }
.seccion__sub { color: var(--text-muted); max-width: 62ch; margin-top: var(--space-2); font-size: var(--text-base); }

/* ------------------------------------------------------------------ hero -- */

.hero {
  position: relative; overflow: hidden;
  background: var(--surface-2);
  border-radius: var(--radius-lg);
  padding: var(--space-6) var(--space-5);
  margin-top: var(--space-4);
}
.hero h1 { font-size: clamp(1.75rem, 4.6vw, 2.6rem); letter-spacing: -0.03em; line-height: 1.06; margin-top: var(--space-3); }
.hero__sub { margin-top: var(--space-3); color: var(--text-muted); max-width: 58ch; }
.hero__acciones { display: flex; flex-wrap: wrap; gap: var(--space-2); margin-top: var(--space-5); }
.hero__meta { display: flex; flex-wrap: wrap; gap: var(--space-4); margin-top: var(--space-4); color: var(--text-muted); font-size: var(--text-xs); }
.hero__meta b { color: var(--text); font-family: var(--font-display); font-size: var(--text-lg); font-variant-numeric: tabular-nums; }
.hero::after {
  content: ""; position: absolute; right: -60px; top: -60px;
  width: 240px; height: 240px; border-radius: 50%;
  border: 22px solid color-mix(in srgb, var(--accent) 14%, transparent);
  pointer-events: none;
}
@media (min-width: 900px) { .hero { padding: var(--space-7) var(--space-6); } }

/* ---------------------------------------------------------------- tarjetas -- */

.tarjeta {
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: var(--radius-md);
  box-shadow: var(--shadow-1);
  overflow: hidden;
}
.tarjeta__cuerpo { padding: var(--space-4); display: grid; gap: var(--space-3); }
/* Un boton dentro de una tarjeta no se estira a lo ancho: se queda de su tamano. */
.tarjeta__cuerpo > .btn { justify-self: start; }
.tarjeta__titulo { font-size: var(--text-lg); }
.tarjeta--tinta { background: var(--surface-2); border-color: color-mix(in srgb, var(--accent) 22%, var(--border)); }

.rejilla { display: grid; gap: var(--space-3); }
.rejilla--2 { grid-template-columns: 1fr; }
.rejilla--aire { gap: var(--space-5); }
.rejilla--3 { grid-template-columns: 1fr; }
@media (min-width: 640px) { .rejilla--2, .rejilla--3 { grid-template-columns: repeat(2, 1fr); } }
@media (min-width: 1024px) { .rejilla--3 { grid-template-columns: repeat(3, 1fr); } }
/* Una tarjeta seguida de una rejilla de tarjetas (colegios: las piezas del
   colegio y sus cajas): la rejilla no se pega, lleva el aire de la casa. */
.tarjeta + .rejilla { margin-top: var(--space-4); }

/* ------------------------------------------------------------------ stats -- */

.stats { display: grid; grid-template-columns: repeat(2, 1fr); gap: var(--space-3); }
@media (min-width: 860px) { .stats { grid-template-columns: repeat(4, 1fr); } }
.stat { background: var(--surface-2); border: 1px solid var(--border); border-radius: var(--radius-md); padding: var(--space-4); display: grid; gap: 4px; }
.stat__num { font-family: var(--font-display); font-size: var(--text-2xl); font-weight: 700; letter-spacing: -0.02em; font-variant-numeric: tabular-nums; }
.stat__num--ok { color: var(--success); }
.stat__num--aviso { color: var(--warning); }
.stat__num--mal { color: var(--danger); }
.stat__etiqueta { font-family: var(--font-mono); font-size: 12px; text-transform: uppercase; letter-spacing: 0.1em; color: var(--text-muted); }
.stat__pista { font-size: var(--text-xs); color: var(--text-muted); }

/* --------------------------------------------------------------- colegios -- */

.colegio-dot { width: 10px; height: 10px; border-radius: 50%; flex: 0 0 auto; background: var(--border-strong); }
.colegio-dot--azul { background: var(--accent); }
.colegio-dot--ambar { background: var(--warning); }
.colegio-dot--verde { background: var(--success); }
.colegio-dot--violeta { background: var(--violet); }

.colegio-chip { display: inline-flex; align-items: center; gap: 8px; font-weight: 600; font-size: var(--text-xs); }

/* ---------------------------------------------------------------- campos -- */

/* `align-content: start` es la clave del alineado: sin el, la rejilla reparte
   el alto sobrante entre las filas y un campo acaba con el input mas alto que
   el de al lado (pasaba con Nombre/Kits y con Colegio/Etiqueta). */
.campo { display: grid; gap: 8px; align-content: start; }
.campo > label { font-weight: 600; font-size: var(--text-sm); }
.campo input, .campo select, .campo textarea {
  border: 1px solid var(--border-strong); border-radius: var(--radius-sm);
  padding: 12px; min-height: 48px; width: 100%;
  background: var(--surface); font-size: 16px; /* 16px: iOS no hace zoom al enfocar */
  transition: border-color var(--dur-2), box-shadow var(--dur-2);
}
.campo textarea { min-height: 88px; resize: vertical; }
.campo input:focus-visible, .campo select:focus-visible, .campo textarea:focus-visible {
  border-color: var(--accent); outline-offset: 0;
}
.campo__ayuda { font-size: var(--text-xs); color: var(--text-muted); }
/* Una nota de campo seguida de chips (colegios, falta y sobra del escáner):
   sin esto la nota y los chips quedaban pegados. */
.campo__ayuda + .chips { margin-top: var(--space-2); }
.campo--num input { font-variant-numeric: tabular-nums; text-align: right; max-width: 140px; }
/* En un formulario, el campo corto de la cuenta manda sobre el ancho del
   formulario: los kits de un colegio son un numero de pocas cifras. */
.campo input.cantidad-campo { width: 96px; }

/* El campo de cantidad por kit dentro de una tabla (Ajustes): la misma piel
   que los campos del formulario, en tamano de celda y alineado a la derecha. */
.cantidad-campo {
  width: 96px; min-height: var(--control-h); padding: 8px 10px; text-align: right;
  border: 1px solid var(--border-strong); border-radius: var(--radius-sm);
  background: var(--surface); color: var(--text);
  font-size: var(--text-sm); font-variant-numeric: tabular-nums;
}
.cantidad-campo:focus-visible { border-color: var(--accent); }
.cantidad-campo:disabled { opacity: 0.6; }
/* Los campos apagados (un usuario de solo lectura): se ven, pero se nota que
   no se pueden tocar. */
input:disabled { opacity: .6; cursor: not-allowed; }
/* Los campos de numero sin clase propia: el conteo de una pieza, el reparto
   entre colegios y las cantidades de una caja. La misma piel que
   .cantidad-campo, para que no asomen las esquinas del navegador. */
.caja-tarjeta__numeros input[type="number"],
.tabla input[type="number"] {
  width: 96px; min-height: var(--control-h); padding: 8px 10px; text-align: right;
  border: 1px solid var(--border-strong); border-radius: var(--radius-sm);
  background: var(--surface); color: var(--text);
  font-size: var(--text-sm); font-variant-numeric: tabular-nums;
}
.caja-tarjeta__numeros input[type="number"]:focus-visible,
.tabla input[type="number"]:focus-visible { border-color: var(--accent); }

/* Los desplegables llevan la piel de un campo aunque vayan sueltos (los
   filtros de conteo, cantidades y conteo por colegio): sin esto asoman las
   esquinas rectas y el borde gris del navegador y rompen el estilo. */
select {
  border: 1px solid var(--border-strong); border-radius: var(--radius-sm);
  padding: 12px; min-height: 48px; width: 100%;
  background: var(--surface); font-size: 16px; /* 16px: iOS no hace zoom al enfocar */
  transition: border-color var(--dur-2), box-shadow var(--dur-2);
}
select:focus-visible { border-color: var(--accent); }

.cantidad-afectadas { display: block; margin-top: var(--space-1); }

/* Las flechitas del navegador en los campos de numero: con la piel propia
   resaltan y estorban. El paso se da escribiendo o con los botones de menos
   y mas de la ficha. */
input[type="number"] { appearance: textfield; -moz-appearance: textfield; }
input[type="number"]::-webkit-outer-spin-button,
input[type="number"]::-webkit-inner-spin-button { -webkit-appearance: none; appearance: none; margin: 0; }

.fila-campos { display: grid; gap: var(--space-3); }
@media (min-width: 640px) { .fila-campos--2 { grid-template-columns: 1fr 1fr; } }

/* La zona de filtros de una lista (buscador, selectores, chips y cuenta):
   cada bloque con su aire, y separada de la lista que filtra. Antes iban
   pegados unos a otros. */
.filtros { display: grid; gap: var(--space-4); margin-block: var(--space-4); }

/* ----------------------------------------------------------------- chips -- */

/* Los chips se envuelven en varias filas en vez de salirse a la derecha: con
   la barra de scroll oculta, el que sobraba desaparecia sin dejar rastro. */
.chips { display: flex; flex-wrap: wrap; gap: var(--space-2); padding-bottom: 4px; }
/* El chip es un control: su borde es lo que dice donde se puede tocar sobre la
   superficie, asi que va en el gris estructural. El hover se queda con el
   color del texto, porque el borde ya no tiene a donde subir. */
.chip {
  appearance: none; border: 1px solid var(--border-strong); background: var(--surface);
  border-radius: var(--radius-pill); padding: 8px 16px; min-height: 38px;
  font-size: var(--text-xs); font-weight: 600; color: var(--text-muted);
  cursor: pointer; white-space: nowrap;
  display: inline-flex; align-items: center; gap: 8px;
  transition: background var(--dur-2), color var(--dur-2), border-color var(--dur-2), transform var(--dur-1);
}
/* Un chip con casilla (los permisos de una persona): la casilla se queda de
   casilla. Dentro de un `.campo` heredaba la piel y el tamano del campo de
   texto (145 x 48), empujaba el rotulo a una segunda linea y lo partia. */
.chip input[type="checkbox"] {
  appearance: none; -webkit-appearance: none;
  width: 18px; height: 18px; min-height: 0; padding: 0; margin: 0;
  border: 2px solid var(--border-strong); border-radius: 4px;
  background: var(--surface); position: relative; flex: 0 0 auto; cursor: pointer;
  transition: background var(--dur-2), border-color var(--dur-2);
}
.chip input[type="checkbox"]:checked { background: var(--accent); border-color: var(--accent); }
/* La marca se dibuja a mano: con el acento nativo, dentro de un chip ya
   encendido la casilla quedaba del mismo azul que su fondo. */
.chip input[type="checkbox"]:checked::after {
  content: ""; position: absolute; left: 4px; top: 0; width: 6px; height: 11px;
  border: solid var(--on-accent); border-width: 0 2px 2px 0; transform: rotate(45deg);
}
.chip input[type="checkbox"]:focus-visible { outline: 2px solid var(--focus); outline-offset: 2px; }
/* Marcado: el chip se enciende igual que un chip pulsado, para que se vea de
   un vistazo que permiso tiene la persona. */
.chip:has(input[type="checkbox"]:checked) {
  background: var(--accent); border-color: var(--accent); color: var(--on-accent);
}
/* Sobre el chip encendido la casilla va en blanco con la marca azul: se ve. */
.chip:has(input[type="checkbox"]:checked) input[type="checkbox"]:checked {
  background: var(--on-accent); border-color: var(--on-accent);
}
.chip:has(input[type="checkbox"]:checked) input[type="checkbox"]:checked::after { border-color: var(--accent); }
/* La casilla que no se puede tocar (Ver va siempre) se ve apagada pero
   marcada: es un permiso que tiene, no uno que le falte. */
.chip:has(input[type="checkbox"]:disabled) { cursor: default; }
.chip:has(input[type="checkbox"]:disabled) input[type="checkbox"] { cursor: default; }
.chip:hover { color: var(--text); }
.chip:active { transform: scale(.97); }
.chip[aria-pressed="true"] { background: var(--accent); border-color: var(--accent); color: var(--on-accent); }

.badge {
  display: inline-flex; align-items: center; gap: 4px;
  padding: 4px 12px; border-radius: var(--radius-pill);
  font-size: 12px; font-weight: 600; letter-spacing: .01em;
  background: var(--surface-2); color: var(--text);
}
.badge--ok { background: var(--success-soft); color: var(--success); }
.badge--aviso { background: var(--warning-soft); color: var(--warning); }
.badge--mal { background: var(--danger-soft); color: var(--danger); }
.badge--info { background: var(--primary-soft); color: var(--on-primary-soft); }
/* El numero del badge (cuantas faltan o sobran) va mas grande que la palabra:
   es el dato que se busca de un vistazo al contar. */
.badge__num { font-size: 15px; font-weight: 800; line-height: 1; font-variant-numeric: tabular-nums; }

/* --------------------------------------------------------------- busqueda -- */

.buscador { position: relative; }
.buscador input {
  width: 100%; border: 1px solid var(--border-strong); border-radius: var(--radius-pill);
  padding: 12px 16px 12px 44px; min-height: 48px; font-size: 16px; background: var(--surface);
}
.buscador svg { position: absolute; left: 15px; top: 50%; transform: translateY(-50%); width: 18px; height: 18px; color: var(--text-muted); pointer-events: none; }

/* ---------------------------------------------------------------- piezas -- */

.pieza-media {
  position: relative;
  background: var(--primary-soft);
  border-radius: var(--radius-sm);
  aspect-ratio: 1 / 1;
  overflow: hidden;
  display: grid; place-items: center;
}
.pieza-media img { width: 100%; height: 100%; object-fit: cover; display: block; }
.pieza-media--mini { width: 56px; aspect-ratio: 1; flex: 0 0 auto; }

.pieza {
  background: var(--surface); border: 1px solid var(--border); border-radius: var(--radius-md);
  overflow: hidden; cursor: pointer; text-align: left; padding: 0;
  display: grid; gap: 0; box-shadow: var(--shadow-1);
  transition: transform var(--dur-2) var(--ease-enter), box-shadow var(--dur-2), border-color var(--dur-2);
}
.pieza:hover { transform: translateY(-3px); box-shadow: var(--shadow-2); border-color: var(--border-strong); }
.pieza__datos { padding: var(--space-3); display: grid; gap: 4px; }
.pieza__nombre { font-weight: 600; font-size: var(--text-sm); line-height: 1.3; }
.pieza__meta { font-family: var(--font-mono); font-size: 12px; letter-spacing: .06em; color: var(--text-muted); text-transform: uppercase; }
/* Para que sirve la pieza: el texto que se lee al abrir su ficha. */
.ficha__uso {
  margin: var(--space-3) 0 0;
  padding: var(--space-3) var(--space-4);
  border-radius: var(--radius-md);
  background: var(--surface-2);
  border: 1px solid var(--border);
  font-size: var(--text-sm);
  line-height: 1.55;
  color: var(--text);
}
.pieza__cant { font-family: var(--font-display); font-weight: 700; font-variant-numeric: tabular-nums; }

.rejilla-piezas { display: grid; grid-template-columns: repeat(2, 1fr); gap: var(--space-3); }
@media (min-width: 640px) { .rejilla-piezas { grid-template-columns: repeat(3, 1fr); } }
@media (min-width: 1024px) { .rejilla-piezas { grid-template-columns: repeat(4, 1fr); } }

/* La ficha de una pieza: el escenario en grande (3D o foto) y los datos al lado. */
.ficha { display: grid; gap: var(--space-4); }
@media (min-width: 900px) {
  .ficha { grid-template-columns: minmax(0, 1.4fr) minmax(300px, 1fr); align-items: start; }
}
.ficha__media { display: grid; gap: var(--space-3); min-width: 0; }
.ficha__pestanas { display: flex; gap: var(--space-2); }
.ficha__escenario {
  position: relative;
  display: grid;
  border-radius: var(--radius-md);
  overflow: hidden;
  aspect-ratio: 16 / 11;
  min-height: 260px;
}
/* La foto es cuadrada: cuando se mira la foto, el escenario se pone cuadrado y
   se limita el ancho, asi la imagen lo llena ENTERA (sin recortes ni franjas).
   OJO: nada de `margin-inline: auto` aqui — como elemento de rejilla, los
   margenes automaticos le quitan el estirar y el escenario se encogia a su
   minimo (260 px) y la pieza parecia pequena. Se centra con justify-self. */
.ficha__escenario--foto { aspect-ratio: 1 / 1; width: min(100%, 520px); justify-self: center; }
/* La vista se ancla al escenario (inset: 0): con `height: 100%` a secas el
   porcentaje no resolvia y la imagen se dibujaba mas alta que el marco y se
   recortaba por abajo. */
.ficha__vista { position: absolute; inset: 0; display: grid; place-items: center; min-width: 0; min-height: 0; }
.ficha__vista[hidden] { display: none; }
.ficha__vista img { width: 100%; height: 100%; object-fit: contain; display: block; }
.ficha__vista .viewer3d { width: 100%; height: 100%; aspect-ratio: auto; border-radius: 0; background: transparent; }

/* --------------------------------------------------------------- tablas --- */

.tabla-envoltura { overflow-x: auto; border: 1px solid var(--border); border-radius: var(--radius-md); background: var(--surface); }
.tabla { width: 100%; border-collapse: collapse; font-size: var(--text-sm); }
.tabla th {
  font-family: var(--font-mono); font-size: 12px; font-weight: 600;
  text-transform: uppercase; letter-spacing: 0.09em; color: var(--text-muted);
  text-align: left; padding: 12px 16px; background: var(--surface-2);
  position: sticky; top: 0;
}
.tabla td { padding: 12px 16px; border-top: 1px solid var(--border); vertical-align: middle; }
.tabla .num { text-align: right; font-variant-numeric: tabular-nums; }
.tabla tbody tr:hover td { background: var(--primary-soft); }

/* ----------------------------------------------------------------- lista -- */

.lista { display: grid; gap: var(--space-2); }
/* La parte de la fila que abre la ficha de la pieza: un boton, para que se
   pueda tocar con el dedo y con el teclado, sin tocar los numeros de al lado. */
.lista__abrir {
  display: grid; grid-template-columns: auto minmax(0, 1fr); gap: var(--space-3);
  align-items: center; text-align: left; background: none; border: 0; padding: 0;
  color: inherit; cursor: pointer; border-radius: var(--radius-sm);
}
.lista__abrir:hover .lista__nombre, .lista__abrir:focus-visible .lista__nombre { text-decoration: underline; }

.lista__fila {
  display: flex; align-items: center; gap: var(--space-3);
  padding: var(--space-3); border: 1px solid var(--border); border-radius: var(--radius-sm);
  background: var(--surface);
}
/* Los numeros y el registro de la fila viven pegados a la derecha: la pieza
   manda a la izquierda y la cuenta queda en columna, facil de recorrer. */
.lista__fila > .caja-tarjeta__numeros { margin-left: auto; }

/* En el telefono la fila se parte en dos lineas: la pieza arriba, y los
   numeros con el registro abajo, repartidos a lo ancho. */
@media (max-width: 640px) {
  .lista__fila:has(> .lista__abrir) { flex-wrap: wrap; row-gap: var(--space-2); }
  .lista__fila:has(> .lista__abrir) > .lista__abrir { flex: 1 1 100%; }
  .lista__fila:has(> .lista__abrir) > .caja-tarjeta__numeros { flex: 1 1 100%; margin-left: 0; justify-content: space-between; }
  .lista__fila:has(> .lista__abrir) .badge { flex: 1 1 auto; min-width: 0; }
}
.lista__fila--activa { border-color: var(--accent); box-shadow: 0 0 0 3px var(--primary-soft); }
.lista__texto { min-width: 0; flex: 1; display: grid; gap: 4px; }
.lista__nombre { font-weight: 600; font-size: var(--text-sm); }
.lista__meta { font-size: var(--text-xs); color: var(--text-muted); }

/* ------------------------------------------------------------- progreso -- */

.progreso { display: grid; gap: 8px; }
.progreso__barra { height: 10px; border-radius: var(--radius-pill); background: var(--surface-2); overflow: hidden; }
/* La barra crece con transform (scaleX), no con width: animar width re-coloca la
   pagina en cada fotograma. */
.progreso__relleno { width: 100%; height: 100%; border-radius: inherit; background: var(--accent); transform-origin: left center; transition: transform var(--dur-4) var(--ease-standard); }
.progreso__pie { display: flex; justify-content: space-between; align-items: baseline; gap: var(--space-3); font-size: var(--text-xs); color: var(--text-muted); }
/* Los faltantes del resumen, en grande y en rojo: el numero que se mira. */
.progreso__num { font-size: 14px; font-weight: 800; color: var(--text); font-variant-numeric: tabular-nums; }
.progreso__num--mal { color: var(--danger); }

/* --------------------------------------------------------------- dialogos -- */

dialog.dlg {
  border: 0; border-radius: var(--radius-lg); padding: 0;
  width: min(680px, calc(100vw - 24px));
  max-height: min(88dvh, 900px);
  background: var(--surface); color: var(--text);
  box-shadow: var(--shadow-3);
  overflow: hidden;
}
dialog.dlg--ancho { width: min(920px, calc(100vw - 24px)); }
dialog.dlg::backdrop { background: var(--scrim); backdrop-filter: blur(2px); }

.dlg__cab {
  display: flex; align-items: center; justify-content: space-between; gap: var(--space-3);
  padding: var(--space-4) var(--space-5);
  border-bottom: 1px solid var(--border);
}
.dlg__titulo { font-size: var(--text-lg); }
.dlg__cuerpo { padding: var(--space-5); display: grid; gap: var(--space-4); overflow: auto; max-height: 68dvh; }
.dlg__pies {
  display: flex; flex-wrap: wrap; justify-content: flex-end; gap: var(--space-2);
  padding: var(--space-4) var(--space-5); border-top: 1px solid var(--border);
  background: var(--surface);
}

/* ----------------------------------------------------------------- toast -- */

.toasts {
  position: fixed; z-index: 60;
  left: 50%; transform: translateX(-50%);
  bottom: calc(84px + env(safe-area-inset-bottom));
  width: min(440px, calc(100vw - 32px));
  display: grid; gap: 8px;
}
@media (min-width: 900px) { .toasts { bottom: 24px; } }
.toast {
  display: flex; align-items: center; gap: var(--space-3);
  background: var(--text); color: var(--bg);
  border-radius: var(--radius-md); padding: 12px 16px;
  box-shadow: var(--shadow-3); font-size: var(--text-sm); font-weight: 500;
}
.toast svg { width: 18px; height: 18px; flex: 0 0 auto; }
.toast--ok svg { color: var(--success); }
.toast--mal svg { color: var(--danger); }

/* --------------------------------------------------------------- alertas -- */

.alert {
  max-width: 1240px; margin: var(--space-4) auto 0; padding: 12px 16px;
  border-radius: var(--radius-md); border: 1px solid var(--border);
  background: var(--surface); color: var(--text);
  font-size: var(--text-sm); font-weight: 500;
}
.alert--mal { background: var(--danger-soft); border-color: var(--danger); color: var(--danger); }
.alert--aviso { background: var(--warning-soft); border-color: var(--warning); color: var(--warning); }
.alert--ok { background: var(--success-soft); border-color: var(--success); color: var(--success); }

/* -------------------------------------------------------------- esqueleto -- */

.esqueleto { border-radius: var(--radius-sm); background: var(--surface-2); min-height: 16px; }

.vacio { text-align: center; padding: var(--space-7) var(--space-4); color: var(--text-muted); display: grid; gap: var(--space-2); justify-items: center; }
.vacio strong { color: var(--text); font-family: var(--font-display); font-size: var(--text-lg); }

/* -------------------------------------------------------------- entrar ---- */

/* El ancho de la tarjeta de entrar. Lleva su propio margen lateral porque esta
   vista no va dentro de `.wrap`: sin el, en un telefono la tarjeta tocaba los
   dos bordes de la pantalla y sus esquinas redondeadas se cortaban. El 440 se
   queda igual en escritorio; solo cambia cuando la pantalla es mas estrecha. */
.entrar { width: min(440px, calc(100% - 2 * var(--space-4))); margin: clamp(2rem, 9vh, 6rem) auto; display: grid; gap: var(--space-5); }
.entrar__tarjeta { padding: var(--space-6) var(--space-5); display: grid; gap: var(--space-4); background: var(--surface-2); }
.entrar__codigo input { letter-spacing: .35em; font-family: var(--font-mono); font-size: 1.4rem; text-align: center; }

/* -------------------------------------------------------------- cajas ----- */

.caja-tarjeta { display: grid; gap: var(--space-3); background: var(--surface-2); }
.caja-tarjeta__cab { display: flex; align-items: flex-start; justify-content: space-between; gap: var(--space-3); }
.caja-codigo {
  font-family: var(--font-mono); font-size: 12px; font-weight: 600; letter-spacing: .08em;
  background: var(--text); color: var(--bg); padding: 4px 12px; border-radius: var(--radius-sm);
}
/* La ubicacion respira bajo el titulo de la caja: sin esto el nombre y la
   direccion quedaban a 2 px, pegados. */
.caja-tarjeta__ubi { display: flex; align-items: center; gap: 8px; color: var(--text-muted); font-size: var(--text-xs); margin-top: var(--space-1); }
.caja-tarjeta__ubi svg { width: 14px; height: 14px; }
.caja-tarjeta__numeros { display: flex; align-items: center; gap: var(--space-4); }
/* El estado (Sin contar / Faltan / Sobran) con ancho estable: la fila no salta
   al cambiar de estado y la pildora queda centrada. */
.caja-tarjeta__numeros .badge { min-width: 104px; justify-content: center; }
.caja-num { display: grid; gap: 4px; }
.caja-num b { font-family: var(--font-display); font-size: var(--text-xl); font-weight: 700; font-variant-numeric: tabular-nums; }
.caja-num span { font-family: var(--font-mono); font-size: 12px; text-transform: uppercase; letter-spacing: .08em; color: var(--text-muted); }
/* El check de «al dia» va en linea con los numeros: bajado un cuarto de em
   para que su tinta quede centrada con la de los digitos, no sobre la linea. */
.caja-num b svg { vertical-align: -0.25em; }

.etiqueta {
  display: grid; grid-template-columns: 96px 1fr; gap: var(--space-4); align-items: center;
  border: 1px solid var(--border); border-radius: var(--radius-md); padding: var(--space-4);
  background: var(--surface);
}
.etiqueta__qr { width: 96px; height: 96px; }
.etiqueta__qr svg, .etiqueta__qr img { width: 100%; height: 100%; }
.etiqueta__codigo { font-family: var(--font-mono); font-weight: 700; font-size: var(--text-lg); letter-spacing: .06em; }
.etiqueta__nombre { font-weight: 600; margin-top: 4px; }
.etiqueta__meta { font-size: var(--text-xs); color: var(--text-muted); margin-top: 4px; }

/* ------------------------------------------------------------- escaner ---- */

.escaner { display: grid; gap: var(--space-4); }
.escaner__lienzo { position: relative; border-radius: var(--radius-md); overflow: hidden; background: var(--surface-2); }
.escaner__lienzo canvas { display: block; width: 100%; height: auto; }
/* La barra de pasos (1 · Preparar…) va entre la banda y las tarjetas: debajo
   lleva el mismo aire que le deja la banda arriba, para no pegarse a la rejilla. */
.escaner__pasos { display: flex; gap: var(--space-2); flex-wrap: wrap; margin-bottom: var(--space-4); }
.paso-punto {
  display: inline-flex; align-items: center; gap: 8px; font-size: var(--text-xs); font-weight: 600;
  color: var(--text-muted); padding: 8px 12px; border-radius: var(--radius-pill); border: 1px solid var(--border);
  background: var(--surface);
}
.paso-punto--activo { color: var(--on-accent); background: var(--accent); border-color: var(--accent); }
.paso-punto--hecho { color: var(--success); border-color: var(--success); }

.escaner__resumen { display: flex; flex-wrap: wrap; gap: var(--space-3); align-items: center; }
.deteccion-mini { display: flex; align-items: center; gap: var(--space-2); padding: 8px 12px; border: 1px solid var(--border); border-radius: var(--radius-pill); background: var(--surface); font-size: var(--text-xs); font-weight: 600; }

/* ------------------------------------------- etiquetas y hojas impresas -- */

a.tarjeta { color: inherit; text-decoration: none; display: block; }

.etiquetas-previa { display: grid; grid-template-columns: 1fr; gap: var(--space-3); }
@media (min-width: 720px) { .etiquetas-previa { grid-template-columns: repeat(2, 1fr); } }

/* --------------------------------------------------- hojas para imprimir -- */

/* Los dialogos de las hojas: la previa ENTERA a un lado y los pasos al otro.
   La previa es la hoja de verdad (210 x 297 mm) escalada con transform: asi lo
   que se ve es exactamente lo que sale impreso, sin recortes ni sorpresas. */
.hoja-dlg { display: grid; gap: var(--space-5); }
@media (min-width: 760px) {
  .hoja-dlg { grid-template-columns: auto minmax(0, 1fr); align-items: start; }
}
.hoja-dlg__marco { width: calc(216mm * 0.3); height: calc(279mm * 0.3); overflow: hidden; justify-self: center; }
.hoja-dlg__hoja { width: 216mm; height: 279mm; transform: scale(0.3); transform-origin: top left; }

/* Que los fondos y el cuadro salgan TAMBIEN en papel: el navegador los quita
   por defecto al imprimir (la hoja azul salia blanca). Va como regla base y no
   solo dentro de @media print para que valga siempre, y en pantalla no hace nada. */
.hoja-real, .hoja-real--azul, .hoja-real__cuadrado, .hoja-real__regla,
.etiqueta, .tabla th {
  -webkit-print-color-adjust: exact;
  print-color-adjust: exact;
}
.hoja-dlg__pasos { display: grid; gap: var(--space-4); align-content: start; }

/* La hoja de verdad: medidas en milimetros para que al imprimir al 100 % el
   cuadrado mida lo que dice. */
.hoja-real {
  display: grid; align-content: space-between;
  padding: 14mm;
  background: var(--surface); color: var(--text);
  border: 1px solid var(--border);
}
.hoja-real--azul { background: var(--sky); color: var(--on-primary); border-color: var(--sky); }
.hoja-real__cab {
  display: flex; justify-content: space-between; gap: 8mm;
  font-family: var(--font-mono); font-size: 3.4mm; font-weight: 600;
  letter-spacing: 0.14em; text-transform: uppercase; opacity: 0.85;
}
.hoja-real__cuerpo { display: grid; gap: 6mm; justify-items: center; text-align: center; }
.hoja-real__titulo { font-family: var(--font-mono); font-weight: 700; font-size: 6.4mm; letter-spacing: 0.18em; text-transform: uppercase; }
.hoja-real__texto { font-size: 4.2mm; line-height: 1.5; max-width: 150mm; }
.hoja-real__pie { display: flex; align-items: flex-end; justify-content: space-between; gap: 8mm; }
.hoja-real__cuadrado { width: 60mm; height: 60mm; background: var(--text); }
.hoja-real__medida { font-family: var(--font-mono); font-size: 3.4mm; letter-spacing: 0.1em; text-transform: uppercase; }
.hoja-real__regla {
  width: 100mm; height: 4mm;
  border: 0.4mm solid currentColor;
  background: repeating-linear-gradient(90deg, currentColor 0 0.4mm, transparent 0.4mm 10mm);
}

/* Los pasos, numerados de verdad (guia del escaner y dialogos de las hojas). */
.pasos-lista { display: grid; gap: var(--space-3); margin: 0; padding: 0; list-style: none; counter-reset: paso; }
.pasos-lista li { display: grid; grid-template-columns: auto minmax(0, 1fr); gap: var(--space-3); align-items: start; counter-increment: paso; }
.pasos-lista li::before {
  content: counter(paso);
  display: grid; place-items: center;
  width: 26px; height: 26px; border-radius: var(--radius-pill);
  background: var(--accent); color: var(--on-accent);
  font-family: var(--font-mono); font-size: var(--text-xs); font-weight: 700;
}
.pasos-lista b { display: block; font-size: var(--text-base); }
.pasos-lista span { color: var(--text-muted); font-size: var(--text-sm); }

/* --------------------------------------------------------------- media ---- */

.viewer3d { position: relative; border-radius: var(--radius-md); overflow: hidden; background: var(--primary-soft); aspect-ratio: 4 / 3; }
.viewer3d canvas { display: block; width: 100%; height: 100%; }
.viewer3d__pie {
  position: absolute; inset-inline: 8px; bottom: 8px;
  display: flex; justify-content: space-between; gap: 8px;
  font-size: 12px; color: var(--text-muted);
}

/* ---------------------------------------------------------- animaciones --- */

@media (prefers-reduced-motion: no-preference) {
  .sube { animation: sube var(--dur-4) var(--ease-enter) both; animation-delay: calc(var(--i, 0) * 45ms); }
  @keyframes sube { from { opacity: 0; transform: translateY(12px); } to { opacity: 1; transform: none; } }

  .escala { animation: escala var(--dur-3) var(--ease-enter) both; }
  @keyframes escala { from { opacity: 0; transform: scale(.96); } to { opacity: 1; transform: none; } }

  .btn--primary:hover { transform: translateY(-1px); }
  .tarjeta, .stat { transition: box-shadow var(--dur-2) var(--ease-standard), transform var(--dur-2) var(--ease-enter); }
  .tarjeta:hover { box-shadow: var(--shadow-2); }
  .stat:hover { transform: translateY(-2px); }

  ::view-transition-old(root) { animation: salir var(--dur-2) var(--ease-exit) both; }
  ::view-transition-new(root) { animation: entrar var(--dur-3) var(--ease-enter) both; }
  @keyframes salir { to { opacity: 0; transform: translateY(-6px); } }
  @keyframes entrar { from { opacity: 0; transform: translateY(10px); } }
}

@keyframes girar { to { transform: rotate(360deg); } }

@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after { animation-duration: 0.001ms !important; animation-iteration-count: 1 !important; transition-duration: 0.001ms !important; }
  html { scroll-behavior: auto; }
}

/* ------------------------------------------------------------------ buzon -- */

/* El buzon (Ajustes › Buzon): cada mensaje es una ficha con su cabecera de
   etiquetas, el texto y las acciones abajo. Se lee de arriba abajo, como una
   lista de correo, y en el telefono las acciones bajan solas. */
.buzon__resumen { margin-bottom: var(--space-4); }

.buzon__lista { display: grid; gap: var(--space-3); }

.buzon__mensaje {
  display: grid;
  gap: var(--space-2);
  padding: var(--space-4);
  border: 1px solid var(--border);
  border-radius: var(--radius-md);
  background: var(--surface);
}

/* Lo que no se ha leido se ve de un vistazo: barra a la izquierda. */
.buzon__mensaje--nuevo { border-left: 4px solid var(--primary); }

.buzon__cab {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--space-2);
}

.buzon__fecha {
  margin-left: auto;
  font-family: var(--font-mono);
  font-size: var(--text-xs);
  color: var(--text-muted);
  text-transform: uppercase;
  letter-spacing: 0.04em;
}

.buzon__asunto {
  margin: 0;
  font-size: var(--text-lg);
  font-family: var(--font-display);
}

.buzon__quien {
  margin: 0;
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-2);
  align-items: baseline;
  font-size: var(--text-sm);
}

.buzon__nombre { font-weight: 600; }

.buzon__correo { color: var(--text-muted); word-break: break-all; }

/* El texto de una persona: se respetan sus saltos de linea y se corta una
   palabra larguisima antes que desbordar la ficha. */
.buzon__texto {
  margin: 0;
  white-space: pre-wrap;
  overflow-wrap: anywhere;
  font-size: var(--text-base);
}

.buzon__origen { margin: 0; font-size: var(--text-xs); }

.buzon__acciones {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-2);
  padding-top: var(--space-2);
  border-top: 1px solid var(--border);
}

.buzon__pie { margin: 0; font-size: var(--text-xs); }

@media (max-width: 520px) {
  .buzon__fecha { margin-left: 0; }
  .buzon__acciones > * { flex: 1 1 auto; }
}

/* ---------------------------------------------------------------- impresion */

@media print {
  @page { size: letter; margin: 0; }
  /* Los navegadores NO imprimen los fondos por defecto: sin esto la hoja azul
     sale blanca y el cuadro negro de calibracion ni aparece. */
  .hoja-real, .hoja-real--azul, .hoja-real__cuadrado, .hoja-real__regla,
  .etiqueta, .tabla th, .badge, .chip {
    -webkit-print-color-adjust: exact;
    print-color-adjust: exact;
  }
  .topbar, .bottom, .pie, .alert, .toasts, .no-imprimir { display: none !important; }
  /* De la hoja solo se imprime la hoja: sin previa escalada ni pasos. */
  .hoja-dlg__marco { width: auto; height: auto; overflow: visible; }
  .hoja-dlg__hoja { transform: none; }
  .hoja-dlg__pasos, .dlg__pies, .dlg__cab { display: none !important; }
  .hoja-dlg { display: block; }
  body { padding: 0; background: #fff; color: #000; font-size: 12pt; }
  .main { display: block; }
  .dlg__cuerpo { max-height: none; overflow: visible; }
  dialog.dlg { box-shadow: none; width: 100%; max-height: none; }
  dialog.dlg::backdrop { display: none; }
  .hoja-etiquetas { display: grid; grid-template-columns: 1fr 1fr; gap: 6mm; }
  .etiqueta { break-inside: avoid; border: 1px dashed #666; }
  .tabla th { background: #eee; color: #000; }
  a { color: #000; text-decoration: none; }
}
