/* ============================================================
   NeoLabQC — Catálogos del laboratorio
   Estilo: Instrumento. Cromo oscuro para la navegación, fondo de página
   más profundo, canto recto, estado en color pleno.

   Sirve a dos contextos:
     · #nlqc-cat-selector → widget dentro de los plugins de guía (más los
       montajes adicionales [data-nlqc-cat-selector-extra] de nlqc-cat-selector.js,
       cuando una guía separa sus bloques en más de una tarjeta)
     · #nlqc-cat-app      → página central del catálogo

   TOKENS. Se consumen los del tema con valor de respaldo, para que el
   plugin no se vea roto si se activa sobre otro tema. Los propios
   existen porque el tema no los tiene:

   --nc-edge      Borde de tarjeta. El --color-border del tema es
                  rgba(0,0,0,.09), que sobre #F5F6F7 es casi invisible; una
                  ficha de catálogo necesita canto propio para no disolverse.
   --nc-edge-soft Divisiones internas, un paso por debajo.
   --nc-bar       Cabecera de tarjeta y encabezado de tabla. Es lo que da
                  estructura sin recurrir a la sombra, que ensucia.
   --nc-bar-2     Franja interior, un tono por debajo de --nc-bar.
   --nc-*-700     Tinta de estado. El -600 del tema sobre su -50 queda justo
                  de contraste para texto pequeño.
   ============================================================ */

/* La pila de avisos cuelga de <body>, fuera de #nlqc-cat-app: si no entra en
   este bloque se queda sin tokens y sin tipografía. Los montajes adicionales
   ([data-nlqc-cat-selector-extra]) tampoco son descendientes de
   #nlqc-cat-selector: sin su propia entrada aquí, las variables --nc-* no
   llegan por herencia y todo lo que pinten dentro queda sin borde, sin
   color, sin nada — el CSS referencia var(--nc-edge) etc. sin respaldo. */
#nlqc-cat-app,
#nlqc-cat-selector,
[data-nlqc-cat-selector-extra],
.nlqc-cat-gate,
.nlqc-cat-toasts {
  --nc-blue:       var(--brand-blue, #2D6BC4);
  --nc-blue-dark:  var(--brand-blue-dark, #1E4F9C);
  --nc-violet:     var(--brand-violet, #7C5CBF);

  --nc-bg:         var(--color-bg, #E8ECF1);
  --nc-surface:    var(--color-surface, #FFFFFF);
  --nc-text:       var(--color-text, #0F1117);
  --nc-text-mid:   var(--color-text-muted, #4B5563);
  --nc-text-soft:  var(--color-text-subtle, #8D95A1);
  --nc-gray-50:    var(--gray-50, #F5F6F7);
  --nc-gray-100:   var(--gray-100, #E2E5E9);
  --nc-gray-200:   var(--gray-200, #CDD1D8);
  --nc-gray-400:   var(--gray-400, #8D95A1);
  --nc-gray-800:   var(--gray-800, #1C2130);

  --nc-edge:       #BFC7D2;
  --nc-edge-soft:  #DCE1E8;
  --nc-bar:        #F1F4F8;
  --nc-bar-2:      #F9FAFC;
  --nc-shadow:     0 1px 2px rgba(12,17,29,.07);
  --nc-shadow-h:   0 10px 22px -8px rgba(12,17,29,.22);

  --nc-green-50:  var(--green-50, #F0FDF4);
  --nc-green-200: #BBF7D0;
  --nc-green-600: var(--green-600, #16A34A);
  --nc-green-700: #15803D;
  --nc-amber-50:  var(--amber-50, #FFFBEB);
  --nc-amber-200: #FDE68A;
  --nc-amber-700: #B45309;
  --nc-red-50:    var(--red-50, #FEF2F2);
  --nc-red-200:   #FECACA;
  --nc-red-600:   var(--red-600, #DC2626);
  --nc-red-700:   #B91C1C;
  --nc-blue-50:   var(--blue-50, #EFF6FF);
  --nc-blue-200:  #BFDBFE;
  --nc-blue-700:  #1D4ED8;

  --nc-r-sm: var(--radius-sm, 3px);
  --nc-r-md: var(--radius-md, 5px);
  --nc-r-lg: var(--radius-lg, 7px);

  --nc-sans: var(--font-sans, 'Inter', -apple-system, sans-serif);
  --nc-mono: var(--font-mono, 'JetBrains Mono', monospace);

  font-family: var(--nc-sans);
  color: var(--nc-text);
}

#nlqc-cat-app { max-width: 1000px; margin: 0 auto; padding: 0 0 4rem; }
#nlqc-cat-selector,
[data-nlqc-cat-selector-extra] { margin-bottom: 16px; }

/* ============================================================
   BOTONES — planos. El degradado queda para la landing, donde es un
   gesto de marca; en una herramienta de trabajo se lee como adorno.
   ============================================================ */
#nlqc-cat-app .nlqc-btn,
#nlqc-cat-selector .nlqc-btn,
[data-nlqc-cat-selector-extra] .nlqc-btn,
.nlqc-cat-gate .nlqc-btn {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  font-family: inherit;
  font-size: 13.5px;
  font-weight: 600;
  line-height: 1.2;
  padding: 9px 18px;
  border-radius: var(--nc-r-md);
  /* Sin color en el atajo: la regla base va prefijada por ID y ganaría a
     todas las variantes, que se escriben con clase suelta. */
  border-width: 1px;
  border-style: solid;
  cursor: pointer;
  text-decoration: none;
  white-space: nowrap;
  transition: background .14s, border-color .14s, color .14s, box-shadow .14s;
}

#nlqc-cat-app .nlqc-btn:focus-visible,
#nlqc-cat-selector .nlqc-btn:focus-visible,
[data-nlqc-cat-selector-extra] .nlqc-btn:focus-visible,
.nlqc-cat-gate .nlqc-btn:focus-visible {
  outline: none;
  box-shadow: 0 0 0 3px rgba(45,107,196,.28);
}
#nlqc-cat-app .nlqc-btn:active,
#nlqc-cat-selector .nlqc-btn:active,
[data-nlqc-cat-selector-extra] .nlqc-btn:active,
.nlqc-cat-gate .nlqc-btn:active { transform: translateY(.5px); }

.nlqc-btn--primary { background: var(--nc-blue); color: #fff; border-color: var(--nc-blue); }
.nlqc-btn--primary:hover { background: var(--nc-blue-dark); border-color: var(--nc-blue-dark); color: #fff; }
.nlqc-btn--primary:disabled { opacity: .55; cursor: default; }

/* Los secundarios viven sobre blanco: un botón blanco con borde tenue ahí
   no se ve. Llevan relleno propio y canto oscuro, y el hover cambia las dos
   cosas —relleno y borde— para que se note sin mover el texto. */
.nlqc-btn--ghost {
  background: #ffffff;
  color: var(--nc-gray-800);
  border-color: #A9B4C3;
  box-shadow: 0 1px 1px rgba(12,17,29,.04);
}
.nlqc-btn--ghost:hover {
  background: var(--nc-gray-800);
  border-color: var(--nc-gray-800);
  color: #fff;
}

.nlqc-btn--danger {
  background: var(--nc-red-50);
  color: var(--nc-red-700);
  border-color: #F3B4B4;
  box-shadow: 0 1px 1px rgba(12,17,29,.04);
}
.nlqc-btn--danger:hover { background: var(--nc-red-600); border-color: var(--nc-red-600); color: #fff; }

.nlqc-btn--alerta { background: var(--nc-blue); color: #fff; border-color: var(--nc-blue); }
.nlqc-btn--alerta:hover { background: var(--nc-blue-dark); color: #fff; }

.nlqc-btn--icon { padding: 7px 10px; font-size: 13px; }

/* Sobre la cabecera oscura de la ficha el relleno claro basta para
   destacarlos; el hover invierte al blanco pleno. */
.nlqc-cat-card:not(.is-inactive) .nlqc-cat-card__bar .nlqc-btn--ghost {
  background: rgba(255,255,255,.92);
  border-color: rgba(255,255,255,.92);
  color: var(--nc-gray-800);
}
.nlqc-cat-card:not(.is-inactive) .nlqc-cat-card__bar .nlqc-btn--ghost:hover { background: var(--nc-blue); border-color: var(--nc-blue); color: #fff }
.nlqc-cat-card:not(.is-inactive) .nlqc-cat-card__bar .nlqc-btn--danger {
  background: rgba(254,242,242,.92);
  border-color: rgba(254,242,242,.92);
}
.nlqc-cat-card:not(.is-inactive) .nlqc-cat-card__bar .nlqc-btn--danger:hover { background: var(--nc-red-600); border-color: var(--nc-red-600); color: #fff; }

/* Los botones dentro de barras y filas son secundarios por posición:
   ocupan menos sin necesitar una clase propia en el marcado. */
.nlqc-cat-card__bar .nlqc-btn,
.nlqc-cat-tabla .nlqc-btn,
.nlqc-cat-alerta .nlqc-btn,
.nlqc-cat-rowactions .nlqc-btn,
.nlqc-cat-addrow .nlqc-btn { font-size: 12.5px; padding: 6px 13px; }

/* El botón de añadir vive sobre superficies casi blancas (tabla de valores):
   necesita canto propio, no solo relleno. */
.nlqc-cat-addrow .nlqc-btn--ghost {
  background: var(--nc-surface);
  border-color: var(--nc-gray-800);
  color: var(--nc-gray-800);
  font-weight: 700;
}
.nlqc-cat-addrow .nlqc-btn--ghost:hover { background: var(--nc-gray-800); border-color: var(--nc-gray-800); color: #fff; }
.nlqc-cat-card__bar .nlqc-btn--icon,
.nlqc-cat-tabla .nlqc-btn--icon { padding: 5px 9px; }

/* ============================================================
   CAMPOS
   ============================================================ */
.nlqc-cat-field { display: flex; flex-direction: column; gap: 6px; flex: 1; min-width: 170px; }

.nlqc-cat-field label {
  display: flex;
  align-items: center;
  gap: 6px;
  flex-wrap: wrap;
  font-size: 12.5px;
  font-weight: 600;
  color: var(--nc-gray-800);
  margin: 0;
  text-transform: none;
  letter-spacing: 0;
}

/* El asterisco no puede ser solo color: <abbr title> lo anuncia al lector
   de pantalla y la leyenda del formulario lo define en texto. */
.nlqc-cat-req {
  color: var(--nc-red-600);
  font-weight: 700;
  text-decoration: none;
  border: none;
  cursor: help;
}
.nlqc-cat-opt { font-size: 11.5px; font-weight: 400; color: var(--nc-text-soft); }

.nlqc-cat-field input,
.nlqc-cat-field select,
.nlqc-cat-field textarea {
  width: 100%;
  box-sizing: border-box;
  padding: 9px 12px;
  border: 1px solid var(--nc-edge);
  border-radius: var(--nc-r-md);
  background: var(--nc-surface);
  font-family: inherit;
  font-size: 13.5px;
  color: var(--nc-text);
  transition: border-color .14s, box-shadow .14s;
}
.nlqc-cat-field textarea { resize: vertical; min-height: 40px; }
.nlqc-cat-field input.mono { font-family: var(--nc-mono); }
.nlqc-cat-field input::placeholder { color: var(--nc-gray-400); }

.nlqc-cat-field input:focus,
.nlqc-cat-field select:focus,
.nlqc-cat-field textarea:focus {
  outline: none;
  border-color: var(--nc-blue);
  box-shadow: 0 0 0 3px rgba(45,107,196,.12);
}
.nlqc-cat-field select:disabled { background: var(--nc-bar); color: var(--nc-text-soft); cursor: not-allowed; }

.nlqc-cat-field input.is-invalid,
.nlqc-cat-field select.is-invalid,
.nlqc-cat-field textarea.is-invalid { border-color: var(--nc-red-600); }
.nlqc-cat-field input.is-invalid:focus { box-shadow: 0 0 0 3px rgba(220,38,38,.12); }

.nlqc-cat-field .nlqc-cat-error { font-size: 12px; font-weight: 500; color: var(--nc-red-600); }
.nlqc-cat-help  { font-size: 11.5px; line-height: 1.5; color: var(--nc-text-soft); }

/* ============================================================
   PESTAÑAS Y BARRA DE HERRAMIENTAS
   ============================================================ */
.nlqc-cat-tabs {
  display: flex;
  gap: 0;
  flex-wrap: wrap;
  padding: 0 6px;
  background: var(--nc-gray-800);
  border: none;
  border-radius: var(--nc-r-md) var(--nc-r-md) 0 0;
  margin-bottom: 0;
}
.nlqc-cat-tab {
  padding: 13px 15px 11px;
  border: none;
  background: transparent;
  font-family: var(--nc-mono);
  font-size: 11.5px;
  font-weight: 500;
  letter-spacing: .09em;
  text-transform: uppercase;
  color: rgba(255,255,255,.6);
  cursor: pointer;
  border-bottom: 2px solid transparent;
  margin-bottom: 0;
  transition: color .14s, border-color .14s;
}
.nlqc-cat-tab:hover  { color: #fff; }
.nlqc-cat-tab.active { color: #fff; border-bottom-color: #7FB2FF; font-weight: 600; }

.nlqc-cat-toolbar {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
  margin-bottom: 18px;
  padding: 11px 12px;
  flex-wrap: wrap;
  background: var(--nc-surface);
  border: 1px solid var(--nc-edge);
  border-top: none;
  border-radius: 0 0 var(--nc-r-md) var(--nc-r-md);
}

.nlqc-cat-buscar { position: relative; flex: 1; min-width: 200px; max-width: 340px; }
.nlqc-cat-buscar input {
  width: 100%;
  box-sizing: border-box;
  padding: 9px 12px 9px 34px;
  border: 1px solid var(--nc-edge);
  border-radius: var(--nc-r-md);
  background: var(--nc-surface);
  font-family: inherit;
  font-size: 13.5px;
  color: var(--nc-text);
}
.nlqc-cat-buscar input:focus {
  outline: none;
  border-color: var(--nc-blue);
  box-shadow: 0 0 0 3px rgba(45,107,196,.12);
}
.nlqc-cat-buscar svg {
  position: absolute; left: 11px; top: 50%; transform: translateY(-50%);
  width: 15px; height: 15px; fill: none; stroke: var(--nc-gray-400); stroke-width: 2;
}

.nlqc-cat-filters { display: flex; gap: 6px; flex-wrap: wrap; }
.nlqc-cat-filter {
  padding: 8px 14px;
  border-radius: var(--nc-r-sm);
  border: 1px solid var(--nc-edge);
  background: var(--nc-surface);
  font-family: var(--nc-mono);
  font-size: 11px;
  font-weight: 500;
  letter-spacing: .07em;
  text-transform: uppercase;
  color: var(--nc-text-mid);
  cursor: pointer;
  transition: background .14s, color .14s, border-color .14s;
}
.nlqc-cat-filter:hover  { border-color: var(--nc-gray-400); color: var(--nc-text); }
.nlqc-cat-filter.active { background: var(--nc-gray-800); color: #fff; border-color: var(--nc-gray-800); }

/* ============================================================
   TARJETA DE FICHA
   La define la cabecera con fondo tenue, no la sombra. Blanco sobre
   #F5F6F7 con un borde al 9 % se disuelve; una barra separada por
   filete le da estructura de instrumento y además reparte el
   contenido: identidad arriba, datos abajo.
   ============================================================ */
.nlqc-cat-cards { display: flex; flex-direction: column; gap: 14px; }

.nlqc-cat-card {
  background: var(--nc-surface);
  border: 1px solid var(--nc-edge);
  border-radius: var(--nc-r-lg);
  overflow: hidden;
  box-shadow: var(--nc-shadow);
  transition: box-shadow .15s, border-color .15s;
}
.nlqc-cat-card:hover { box-shadow: var(--nc-shadow-h); border-color: var(--nc-gray-400); }

.nlqc-cat-card__bar {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 14px;
  flex-wrap: wrap;
  padding: 11px 16px;
  background: #1C2130;
  border-bottom: 1px solid #1C2130;
}
.nlqc-cat-card__ident {
  display: flex;
  align-items: center;
  gap: 9px;
  flex-wrap: wrap;
  min-width: 0;
}
.nlqc-cat-card-name {
  font-size: 14.5px;
  font-weight: 700;
  letter-spacing: -.008em;
  color: #FFFFFF;
}
.nlqc-cat-card-actions { display: flex; gap: 6px; align-items: center; flex-shrink: 0; }

/* Datos rotulados. Antes iban concatenados con puntos medios y había que
   adivinar qué era cada valor; con rótulo se escanean sin leerlos. */
.nlqc-cat-card__datos {
  display: flex;
  gap: 28px;
  flex-wrap: wrap;
  padding: 13px 16px 14px;
}
.nlqc-cat-dato { min-width: 0; }
.nlqc-cat-dato__k {
  display: block;
  font-family: var(--nc-mono);
  font-size: 10px;
  font-weight: 500;
  letter-spacing: .12em;
  text-transform: uppercase;
  color: var(--nc-text-soft);
  margin-bottom: 2px;
}
.nlqc-cat-dato__v { font-size: 13.5px; color: var(--nc-text); }
.nlqc-cat-dato__v.mono { font-family: var(--nc-mono); font-size: 13px; font-weight: 500; letter-spacing: -.01em; }
.nlqc-cat-dato__v--mute { color: var(--nc-text-mid); }

.nlqc-cat-card-autor {
  padding: 0 16px 12px;
  font-size: 11.5px;
  font-style: italic;
  color: var(--nc-text-soft);
}

/* Dada de baja: la ficha existe pero no se ofrece. El trazo discontinuo
   dice "esto no está en circulación" sin necesidad de leer la etiqueta. */
.nlqc-cat-card.is-inactive {
  background: var(--nc-bar-2);
  border-style: dashed;
  border-color: var(--nc-gray-200);
  box-shadow: none;
}
.nlqc-cat-card.is-inactive .nlqc-cat-card__bar { background: transparent; box-shadow: none; }
.nlqc-cat-card.is-inactive .nlqc-cat-card-name,
.nlqc-cat-card.is-inactive .nlqc-cat-dato__v { color: var(--nc-text-mid); }

/* Sin lote: inservible, y el canto lo dice antes que el texto. */
.nlqc-cat-card.sin-lote { border-color: var(--nc-red-200); }
.nlqc-cat-card.sin-lote .nlqc-cat-card__bar {
  background: #1C2130;
  border-bottom-color: var(--nc-red-600);
  box-shadow: inset 0 2px 0 var(--nc-red-600);
}

/* ============================================================
   PÍLDORAS DE ESTADO — el único lugar donde hay color
   ============================================================ */
.nlqc-cat-badge {
  font-family: var(--nc-mono);
  font-size: 10px;
  font-weight: 600;
  letter-spacing: .09em;
  text-transform: uppercase;
  padding: 3px 7px;
  border-radius: var(--nc-r-sm);
  white-space: nowrap;
  border: 1px solid;
}
.nlqc-cat-badge--nivel { color: #fff; background: var(--nc-blue);       border-color: var(--nc-blue); }
.nlqc-cat-badge--ok    { color: #fff; background: var(--nc-green-600);  border-color: var(--nc-green-600); }
/* Ámbar y no rojo: vencer es una fecha que pasó, no un error. */
.nlqc-cat-badge--venc  { color: #fff; background: #D97706;              border-color: #D97706; }
.nlqc-cat-badge--baja  { color: var(--nc-text-mid); background: transparent; border-color: var(--nc-gray-200); }
.nlqc-cat-badge--falta { color: #fff; background: var(--nc-red-600);    border-color: var(--nc-red-600); }

/* ============================================================
   AVISOS DE FICHA INCOMPLETA
   Dos gravedades. Rojo solo cuando la ficha no se puede usar; lo demás
   es informativo, porque a la tercera alarma falsa nadie mira las
   alarmas.
   ============================================================ */
.nlqc-cat-alerta {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
  flex-wrap: wrap;
  padding: 12px 16px;
  font-size: 13px;
  line-height: 1.55;
  border-top: 1px solid var(--nc-edge-soft);
}
.nlqc-cat-alerta::before {
  order: -1;
  flex: 0 0 auto;
  display: grid;
  place-items: center;
  width: 19px;
  height: 19px;
  border-radius: var(--nc-r-sm);
  font-family: var(--nc-mono);
  font-size: 12px;
  font-weight: 700;
  color: #fff;
}
.nlqc-cat-alerta > span { flex: 1 1 260px; }
.nlqc-cat-alerta--rojo {
  background: #FEE9E7;
  color: #912018;
  border-top: 2px solid var(--nc-red-600);
}
.nlqc-cat-alerta--rojo::before  { content: '!'; background: var(--nc-red-600); }
.nlqc-cat-alerta--info { background: var(--nc-bar); color: var(--nc-text-mid); }
.nlqc-cat-alerta--info::before  { content: 'i'; background: var(--nc-gray-400); }
.nlqc-cat-alerta strong { font-weight: 700; }

/* ============================================================
   TABLAS
   ============================================================ */

.nlqc-cat-tabla {
  width: 100%;
  border-collapse: collapse;
  background: var(--nc-surface);
  border: 2px solid #1c2130;
  border-radius: unset;
  overflow: hidden;
}
.nlqc-cat-tabla th {
  font-family: var(--nc-mono);
  font-size: 10px;
  font-weight: 500;
  letter-spacing: .1em;
  text-transform: uppercase;
  color: rgba(255,255,255,.72);
  text-align: left;
  padding: 9px 14px;
  background: var(--nc-gray-800);
  border-bottom: none;
}
.nlqc-cat-tabla td {
  font-size: 13px;
  padding: 10px 14px;
  border-bottom: 1px solid var(--nc-edge-soft);
  color: var(--nc-text);
  vertical-align: middle;
}
.nlqc-cat-tabla td.mono { font-family: var(--nc-mono); font-weight: 500; }
.nlqc-cat-tabla tr:last-child td { border-bottom: none; }
.nlqc-cat-tabla__acc { text-align: right; white-space: nowrap; width: 1%; }

/* ============================================================
   FORMULARIOS
   ============================================================ */
.nlqc-cat-form {
  background: var(--nc-surface);
  border: 1px solid var(--nc-edge);
  border-radius: var(--nc-r-lg);
  overflow: hidden;
  box-shadow: var(--nc-shadow);
  margin-top: 12px;
  margin-bottom: 14px;
}
.nlqc-cat-form__title {
  padding: 12px 18px;
  font-size: 14px;
  font-weight: 600;
  color: #FFFFFF;
  background: #1C2130;
}
.nlqc-cat-form__meta {
  margin-top: -10px;
  padding: 10px 18px 12px;
  background: #1C2130;
  border-bottom: 1px solid #1C2130;
  font-family: var(--nc-mono);
  font-size: 11px;
  color: rgba(255,255,255,.62);
}
.nlqc-cat-form__legend {
  padding: 10px 18px 15px;
  font-size: 13px;
  line-height: 1.6;
  color: var(--nc-text-mid);
  margin: 0;
}
.nlqc-cat-form__grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(200px, 1fr));
  gap: 16px;
  padding: 16px 18px 0;
}
.nlqc-cat-form__actions {
  display: flex;
  gap: 8px;
  flex-wrap: wrap;
  margin: 18px 18px 18px;
  padding-top: 16px;
  border-top: 1px solid var(--nc-edge-soft);
}

/* Lo obligatorio abierto, el resto plegado: la forma del formulario
   comunica el mensaje antes de que se lea una etiqueta. */
.nlqc-cat-details {
  margin: 18px 18px 0;
  border: 1px solid var(--nc-edge);
  border-radius: var(--nc-r-md);
  overflow: hidden;
}
.nlqc-cat-details > summary {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
  padding: 11px 14px;
  cursor: pointer;
  font-size: 13px;
  font-weight: 500;
  color: var(--nc-text);
  background: var(--nc-bar);
  list-style: none;
}
.nlqc-cat-details > summary::-webkit-details-marker { display: none; }
.nlqc-cat-details > summary::after {
  content: '▾';
  color: var(--nc-text-soft);
  font-size: 12px;
  transition: transform .15s;
}
.nlqc-cat-details[open] > summary::after { transform: rotate(180deg); }
.nlqc-cat-details > summary em { font-style: normal; font-size: 11.5px; font-weight: 400; color: var(--nc-text-soft); }
.nlqc-cat-details > summary:hover { background: var(--nc-gray-50); }
.nlqc-cat-details > .nlqc-cat-form__grid { padding: 14px; }

/* ============================================================
   SELECTOR DENTRO DEL ESTUDIO
   Un solo contenedor con bloques separados por filete. Cuatro paneles
   sueltos apilados se leían como una pared de color.
   ============================================================ */
#nlqc-cat-selector,
[data-nlqc-cat-selector-extra] {
  background: var(--nc-surface);
  border: 1px solid var(--nc-edge);
  border-radius: var(--nc-r-lg);
  overflow: hidden;
  box-shadow: var(--nc-shadow);
}

/* Padding solo vertical: las filas de dentro (.nlqc-cat-row) ya traen su propio
   padding horizontal de 18px, y el título se alinea con `margin` para no duplicarlo. */
.nlqc-cat-bloque { padding: 16px 0; }
.nlqc-cat-bloque + .nlqc-cat-bloque { border-top: 1px solid var(--nc-edge-soft); }
.nlqc-cat-bloque__title {
  display: flex;
  align-items: center;
  gap: 10px;
  font-size: 12.5px;
  font-weight: 600;
  color: var(--nc-gray-800);
  margin: 0 18px 12px;
  padding: 0;
  text-transform: none;
  letter-spacing: 0;
}
.nlqc-cat-bloque__title::after { content: ''; flex: 1; height: 1px; background: var(--nc-edge-soft); }

/* El picker deja de ser un panel: es una fila de campos. */
.nlqc-cat-picker {
  display: flex;
  align-items: flex-end;
  gap: 14px;
  flex-wrap: wrap;
  padding: 0;
  background: transparent;
  border: none;
  border-radius: 0;
}
.nlqc-cat-picker + .nlqc-cat-picker {
  margin-top: 16px;
  padding-top: 16px;
  border-top: 1px dashed var(--nc-edge-soft);
}
.nlqc-cat-picker__prod { flex: 1 1 320px; }

.nlqc-cat-rowactions { display: flex; gap: 6px; align-items: flex-end; padding-bottom: 1px; }

.nlqc-cat-addrow {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 10px;
  flex-wrap: wrap;
  margin-top: 14px;
}
.nlqc-cat-addrow__right { display: flex; gap: 12px; align-items: center; flex-wrap: wrap; }

.nlqc-cat-manage {
  font-size: 12.5px;
  font-weight: 600;
  color: var(--nc-blue);
  text-decoration: none;
  white-space: nowrap;
}
.nlqc-cat-manage:hover { text-decoration: underline; }

.nlqc-cat-formhost { flex: 1 1 100%; }
.nlqc-cat-formhost:empty { display: none; }

/* ============================================================
   FILA COLAPSADA — método, equipo (spec EP15-A3). Reemplaza el picker con
   <select> siempre visible: una línea por entidad, con un botón que despliega
   el panel de búsqueda dentro de la misma fila.
   ============================================================ */
.nlqc-cat-row {
  display: flex;
  align-items: center;
  gap: 14px;
  padding: 14px 18px;
  flex-wrap: wrap;
}
.nlqc-cat-row + .nlqc-cat-row,
.nlqc-cat-bloque + .nlqc-cat-row,
.nlqc-cat-row + .nlqc-cat-bloque { border-top: 1px solid var(--nc-edge-soft); }

.nlqc-cat-row__label {
  flex: 0 0 90px;
  font-size: 12.5px;
  font-weight: 600;
  color: var(--nc-gray-800);
}
.nlqc-cat-row__value { flex: 1 1 260px; font-size: 13.5px; color: var(--nc-text); }
.nlqc-cat-row__value--muted { color: var(--nc-text-soft); }
.nlqc-cat-row__sep { color: var(--nc-text-soft); margin: 0 2px; }
.nlqc-cat-row__sub { color: var(--nc-text-mid); font-size: 12.5px; }
.nlqc-cat-row__badge {
  display: inline-block;
  margin-left: 6px;
  padding: 1px 7px;
  border-radius: 999px;
  background: var(--nc-amber-50);
  border: 1px solid var(--nc-amber-200);
  color: var(--nc-amber-700);
  font-size: 11px;
  font-weight: 600;
}
.nlqc-cat-row__action {
  flex: 0 0 auto;
  padding: 7px 14px;
  border: 1px solid var(--nc-edge);
  border-radius: var(--nc-r-md);
  background: var(--nc-surface);
  color: var(--nc-blue);
  font-size: 12.5px;
  font-weight: 600;
  cursor: pointer;
  transition: background .12s, border-color .12s;
}
.nlqc-cat-row__action:hover { background: var(--nc-bar); }
.nlqc-cat-row__action:disabled { color: var(--nc-text-soft); cursor: default; }
.nlqc-cat-row__action:focus-visible {
  outline: none;
  box-shadow: 0 0 0 3px rgba(45,107,196,.18);
  border-color: var(--nc-blue);
}

/* ── Panel de búsqueda inline (combobox) ── */
.nlqc-cat-panel {
  flex: 1 1 100%;
  margin-top: 10px;
  border: 1px solid var(--nc-edge);
  border-radius: var(--nc-r-md);
  background: var(--nc-surface);
  overflow: hidden;
}
.nlqc-cat-panel__search {
  display: block;
  width: 100%;
  box-sizing: border-box;
  padding: 10px 14px;
  border: none;
  border-bottom: 1px solid var(--nc-edge-soft);
  font-family: inherit;
  font-size: 13.5px;
  color: var(--nc-text);
  background: var(--nc-bar-2);
}
.nlqc-cat-panel__search:focus { outline: none; background: var(--nc-surface); }
.nlqc-cat-panel__list { max-height: 280px; overflow-y: auto; }
.nlqc-cat-panel__group {
  padding: 8px 14px 4px;
  font-family: var(--nc-mono);
  font-size: 10px;
  font-weight: 500;
  letter-spacing: .1em;
  text-transform: uppercase;
  color: var(--nc-text-soft);
  background: var(--nc-bar-2);
}
.nlqc-cat-panel__option {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 10px;
  padding: 9px 14px;
  font-size: 13px;
  color: var(--nc-text);
  cursor: pointer;
}
.nlqc-cat-panel__option:hover,
.nlqc-cat-panel__option.is-active { background: var(--nc-blue-50); }
.nlqc-cat-panel__option-sub { color: var(--nc-text-soft); font-size: 12px; margin-left: 6px; }
.nlqc-cat-panel__check { color: var(--nc-blue); font-weight: 700; }
.nlqc-cat-panel__create { color: var(--nc-blue); font-weight: 600; border-top: 1px solid var(--nc-edge-soft); }
.nlqc-cat-panel__empty { padding: 12px 14px; color: var(--nc-text-soft); font-size: 12.5px; font-style: italic; }

/* ── Casilla dentro del formulario inline (p.ej. "sin número de serie") ── */
.nlqc-cat-checkbox {
  display: flex;
  align-items: center;
  gap: 6px;
  margin-top: 6px;
  font-size: 12.5px;
  font-weight: 500;
  color: var(--nc-text-mid);
  cursor: pointer;
}
.nlqc-cat-checkbox input { width: auto; }
.nlqc-cat-field input:disabled { background: var(--nc-bar); color: var(--nc-text-soft); cursor: not-allowed; }

/* ── Duplicado detectado al crear (§4.2) ── */
.nlqc-cat-dup {
  margin: 4px 0 12px;
  padding: 10px 14px;
  border-radius: var(--nc-r-md);
  border: 1px solid var(--nc-amber-200);
  background: var(--nc-amber-50);
  color: var(--nc-amber-700);
  font-size: 12.5px;
}
.nlqc-cat-dup .nlqc-btn { margin-left: 8px; }

/* ── Pie del selector: hint de catálogo vacío, error diferido, Gestionar catálogo.
   #nlqc-cat-error se referencia por ID a propósito: la clase .nlqc-cat-error ya la usan
   los mensajes de campo dentro de .nlqc-cat-field (línea ~256) y no deben heredar este
   estilo de bloque. ── */
.nlqc-cat-hint {
  margin: 0;
  padding: 12px 18px;
  border-top: 1px solid var(--nc-edge-soft);
  background: var(--nc-bar-2);
  color: var(--nc-text-mid);
  font-size: 12.5px;
  line-height: 1.55;
}
.nlqc-cat-hint:empty { display: none; }
#nlqc-cat-error {
  margin: 0;
  padding: 10px 18px;
  border-top: 1px solid var(--nc-amber-200);
  background: var(--nc-amber-50);
  color: var(--nc-amber-700);
  font-size: 12.5px;
  font-weight: 500;
}
#nlqc-cat-error[hidden] { display: none; }
.nlqc-cat-foot {
  padding: 12px 18px;
  border-top: 1px solid var(--nc-edge-soft);
  display: flex;
  justify-content: flex-end;
}

/* ── Notas ── */
.nlqc-cat-note {
  padding: 10px 14px;
  border-radius: var(--nc-r-md);
  border: 1px solid var(--nc-edge);
  background: var(--nc-gray-50);
  font-size: 12.5px;
  line-height: 1.55;
  color: var(--nc-text-mid);
}
.nlqc-cat-note--warn {
  background: var(--nc-amber-50);
  border-color: var(--nc-amber-200);
  color: var(--nc-amber-700);
}
.nlqc-cat-note--warn a { color: var(--nc-amber-700); font-weight: 600; }
.nlqc-cat-note strong { font-weight: 700; }
.nlqc-cat-note .mono { font-family: var(--nc-mono); font-size: 12px; }

/* Las notas sueltas del selector necesitan margen lateral propio. */
#nlqc-cat-selector > .nlqc-cat-note,
[data-nlqc-cat-selector-extra] > .nlqc-cat-note { margin: 0 18px 16px; }

/* ── Fila secundaria "Quitar" (bloques de lista) y fila "+ Añadir otro" ──
   La tabla-resumen que vivía acá se retiró: cada fila de producto ya muestra su
   nombre + lote + vencimiento, así que la tabla quedaba duplicando la misma
   información (ver nlqc-cat-selector.js, renderFila/renderFilaAgregar). */
.nlqc-cat-row__quitar {
  flex: 0 0 auto;
  background: none;
  border: none;
  padding: 4px 2px;
  font-size: 12px;
  font-weight: 600;
  color: var(--nc-text-soft);
  cursor: pointer;
}
.nlqc-cat-row__quitar:hover { color: var(--nc-red-600); text-decoration: underline; }

.nlqc-cat-row--agregar { padding: 10px 18px; }
.nlqc-cat-row__add {
  width: 100%;
  padding: 8px 12px;
  border: 1px dashed var(--nc-edge);
  border-radius: var(--nc-r-md);
  background: transparent;
  color: var(--nc-text-mid);
  font-size: 12.5px;
  font-weight: 600;
  cursor: pointer;
  transition: background .12s, border-color .12s, color .12s;
}
.nlqc-cat-row__add:hover { background: var(--nc-bar); border-color: var(--nc-blue); color: var(--nc-blue); }

/* ============================================================
   ESTADOS DE PÁGINA
   ============================================================ */
/* El bloque de mensaje en línea se sustituyó por la pila flotante. Se oculta
   en lugar de borrarse del marcado: el shortcode puede seguir imprimiéndolo. */
.nlqc-cat-msg { display: none !important; }

/* ============================================================
   AVISOS FLOTANTES
   El aviso en línea empujaba la lista al aparecer y la devolvía al
   desaparecer: guardar un lote movía la tarjeta que se estaba mirando.
   Flotando no toca el flujo.

   Cromo oscuro como las cabeceras de ficha y las pestañas: el aviso se
   apoya sobre contenido claro y tiene que leerse como una capa por
   encima, no como una tarjeta más que se coló en la página.
   ============================================================ */
.nlqc-cat-toasts {
  position: fixed;
  right: 20px;
  bottom: 20px;
  /* Por encima de la barra de administración de WordPress (99999). */
  z-index: 100000;
  display: flex;
  flex-direction: column;
  gap: 10px;
  width: min(390px, calc(100vw - 40px));
  /* La pila no intercepta clics; cada aviso sí. */
  pointer-events: none;
}

.nlqc-cat-toast {
  pointer-events: auto;
  position: relative;
  display: grid;
  grid-template-columns: auto 1fr auto;
  align-items: start;
  gap: 10px;
  padding: 12px 12px 14px 13px;
  background: #1C2130;
  border: 1px solid #2C3446;
  border-radius: var(--nc-r-md);
  box-shadow: 0 12px 28px -10px rgba(12,17,29,.55), 0 2px 6px rgba(12,17,29,.25);
  overflow: hidden;
  font-size: 13px;
  line-height: 1.5;
  color: #E8ECF3;
  /* Entra desde la derecha; la transición se declara aquí para que el nodo
     recién insertado ya la tenga cuando se le añade .is-in. */
  opacity: 0;
  transform: translateX(12px);
  transition: opacity .18s ease, transform .18s ease;
}
.nlqc-cat-toast.is-in  { opacity: 1; transform: none; }
.nlqc-cat-toast.is-out { opacity: 0; transform: translateX(12px); }

.nlqc-cat-toast__ico {
  flex: 0 0 auto;
  display: grid;
  place-items: center;
  width: 19px;
  height: 19px;
  margin-top: 1px;
  border-radius: var(--nc-r-sm);
  font-family: var(--nc-mono);
  font-size: 12px;
  font-weight: 700;
  color: #fff;
}
.nlqc-cat-toast__txt { min-width: 0; overflow-wrap: anywhere; }
.nlqc-cat-toast__txt strong { font-weight: 700; }

.nlqc-cat-toast__x {
  flex: 0 0 auto;
  width: 22px;
  height: 22px;
  margin: -1px -2px 0 0;
  padding: 0;
  display: grid;
  place-items: center;
  background: transparent;
  border: none;
  border-radius: var(--nc-r-sm);
  font-family: inherit;
  font-size: 16px;
  line-height: 1;
  color: rgba(255,255,255,.45);
  cursor: pointer;
  transition: background .14s, color .14s;
}
.nlqc-cat-toast__x:hover { background: rgba(255,255,255,.12); color: #fff; }
.nlqc-cat-toast__x:focus-visible {
  outline: none;
  box-shadow: 0 0 0 2px rgba(127,178,255,.75);
  color: #fff;
}

/* Cuenta atrás visible: el aviso no desaparece de golpe, avisa de que se va.
   Con el puntero encima el temporizador se detiene y la barra con él. */
.nlqc-cat-toast__barra {
  position: absolute;
  left: 0;
  bottom: 0;
  height: 2px;
  width: 100%;
  transform-origin: left center;
  animation: nlqc-cat-toast-vida linear forwards;
}
.nlqc-cat-toast:hover .nlqc-cat-toast__barra,
.nlqc-cat-toast:focus-within .nlqc-cat-toast__barra { animation-play-state: paused; }

@keyframes nlqc-cat-toast-vida {
  from { transform: scaleX(1); }
  to   { transform: scaleX(0); }
}

/* El estado va en el icono y en la barra, no en el fondo: cuatro rellenos de
   color apilados en una esquina se leen como un semáforo averiado. */
.nlqc-cat-toast--pass .nlqc-cat-toast__ico   { background: var(--nc-green-600); }
.nlqc-cat-toast--pass .nlqc-cat-toast__barra { background: var(--nc-green-600); }
.nlqc-cat-toast--fail .nlqc-cat-toast__ico   { background: var(--nc-red-600); }
.nlqc-cat-toast--fail .nlqc-cat-toast__barra { background: var(--nc-red-600); }
.nlqc-cat-toast--fail { border-color: #6E2020; }
.nlqc-cat-toast--warn .nlqc-cat-toast__ico   { background: #D97706; }
.nlqc-cat-toast--warn .nlqc-cat-toast__barra { background: #D97706; }
.nlqc-cat-toast--info .nlqc-cat-toast__ico   { background: var(--nc-gray-400); }
.nlqc-cat-toast--info .nlqc-cat-toast__barra { background: var(--nc-gray-400); }

@media (max-width: 700px) {
  .nlqc-cat-toasts {
    right: 10px;
    left: 10px;
    bottom: 10px;
    width: auto;
  }
}

/* Quien pide menos movimiento sigue necesitando el aviso: se queda el
   desvanecido y se va el desplazamiento. */
@media (prefers-reduced-motion: reduce) {
  .nlqc-cat-toast { transition: opacity .18s ease; transform: none; }
  .nlqc-cat-toast.is-out { transform: none; }
}
.nlqc-cat-loading { text-align: center; color: var(--nc-text-soft); font-size: 14px; padding: 48px 0; }

.nlqc-cat-empty {
  text-align: center;
  padding: 56px 24px;
  color: var(--nc-text-soft);
  background: var(--nc-surface);
  border: 1px dashed var(--nc-gray-200);
  border-radius: var(--nc-r-lg);
}
.nlqc-cat-empty p { font-size: 14px; margin: 0 0 6px; }

/* El fallo de carga es un bloque propio; el error de campo va en un <span>
   dentro del campo y no debe heredar esta caja. */
div.nlqc-cat-error {
  padding: 14px 16px;
  background: var(--nc-red-50);
  border: 1px solid var(--nc-red-200);
  border-radius: var(--nc-r-md);
  font-size: 13px;
  color: var(--nc-red-700);
}

/* ============================================================
   PUERTA — sin sesión, sin laboratorio o sin suscripción
   ============================================================ */
.nlqc-cat-gate {
  max-width: 1000px;
  margin: 0 auto 20px;
  background: var(--nc-surface);
  border: 1px solid var(--nc-edge);
  border-top: 3px solid var(--nc-amber-700);
  border-radius: var(--nc-r-lg);
  box-shadow: var(--nc-shadow);
  padding: 28px 32px;
  text-align: center;
  color: var(--nc-text);
}
.nlqc-cat-gate h3 { margin: 0 0 10px; font-size: 17px; font-weight: 600; color: var(--nc-text); }
.nlqc-cat-gate p  { margin: 0 0 16px; font-size: 13.5px; line-height: 1.65; color: var(--nc-text-mid); }
.nlqc-cat-gate a  { color: var(--nc-blue); font-weight: 600; }

.nlqc-cat-gate--inline {
  text-align: left;
  padding: 12px 16px;
  font-size: 13px;
  line-height: 1.6;
  margin-bottom: 16px;
  border-top-width: 1px;
  border-left: 3px solid var(--nc-amber-700);
  color: var(--nc-text-mid);
}
.nlqc-cat-gate--inline a { margin-left: 4px; white-space: nowrap; }

/* ============================================================
   RESPONSIVE
   ============================================================ */
@media (max-width: 700px) {
  .nlqc-cat-card__datos { gap: 18px; }
  .nlqc-cat-card__bar { align-items: flex-start; }
  .nlqc-cat-card-actions { width: 100%; justify-content: flex-end; }
  .nlqc-cat-picker { flex-direction: column; align-items: stretch; }
  .nlqc-cat-rowactions { justify-content: flex-end; }
  .nlqc-cat-row { align-items: flex-start; }
  .nlqc-cat-row__label { flex-basis: 100%; }
  .nlqc-cat-row__action { margin-left: auto; }
  .nlqc-cat-tabs { overflow-x: auto; flex-wrap: nowrap; }
  .nlqc-cat-buscar { max-width: none; }
}

/* ============================================================
   IMPRESIÓN — el selector es entrada, no informe
   ============================================================ */
@media print {
  #nlqc-cat-selector,
  [data-nlqc-cat-selector-extra] { display: none !important; }
  .nlqc-cat-toasts   { display: none !important; }
}