/* ============================================================================
   FnF Analytics — capa de estilo propia
   Implementa fnfanalytics-relanzamiento/14-direccion-visual-v1.md (pasos 1-2).
   Specimen de referencia: demos/v1-componentes.html

   Se carga DESPUÉS de style.blue.css, así que lo cubre por orden de cascada.
   Reglas de la casa:
     · Ni un !important. Si algo no gana, se sube la especificidad y se
       comenta por qué.
     · No se toca style.blue.css. Se neutraliza desde aquí y el día que esta
       capa lo cubra entero, aquel fichero se borra.
     · Tema claro únicamente: el campo se opera al sol (brandbook §1).
   ========================================================================= */

:root {
  /* --- marca -------------------------------------------------------- */
  --brand:        #00c896;  /* SOLO como relleno. Como texto da 2,17:1 */
  --brand-deep:   #077a5c;  /* el verde cuando es texto: 5,33:1 sobre blanco */
  --brand-bright: #2fe0b0;  /* hover sobre relleno */
  --brand-press:  #00a87e;  /* activo */
  --on-brand:     #052018;  /* tinta sobre el verde: 7,90:1 */

  /* --- tinta y superficie ------------------------------------------- */
  --ink:        #131d18;    /* 17,26:1 */
  --ink-soft:   #4f5f58;    /*  6,75:1 */
  --bg:         #fbfdfc;
  --bg-alt:     #f2f7f4;
  --paper:      #ffffff;
  --line:       #d9e4de;
  --line-strong:#b9c9c1;
  --carbon:     #0c1210;
  --ink-on-dark:#e6f0ea;
  --ink-soft-on-dark:#8ea59b;
  --line-dark:  #223029;

  /* --- semánticos ---------------------------------------------------
     Corregidos respecto a tokens.css de v2: los originales no llegaban a
     AA sobre su propia pastilla (--warn 3,64:1 y --ok 4,33:1).           */
  --ok:   #066b50;  --ok-bg:   rgba(0,200,150,.14);
  --warn: #8a4f08;  --warn-bg: rgba(212,144,32,.15);
  --bad:  #bd3d3d;  --bad-bg:  rgba(214,69,69,.12);
  --disabled-bg: #c8d8d1;
  --disabled-ink:#7d8d86;

  /* --- tipografía ---------------------------------------------------- */
  --font:      'Poppins', ui-sans-serif, system-ui, sans-serif;
  --font-mono: 'JetBrains Mono', ui-monospace, 'SF Mono', monospace;

  /* --- espacio, radios, foco ----------------------------------------- */
  --s-2:8px; --s-3:12px; --s-4:16px; --s-5:20px; --s-6:24px; --s-8:32px;
  --r-s:6px; --r-m:10px; --r-l:14px;
  --glow: 0 0 0 2px rgba(0,200,150,.55);
  --shadow: 0 16px 40px -20px rgba(6,20,15,.35);
  --t-fast:120ms; --ease: cubic-bezier(.2,.7,.2,1);
}

/* ============================================================================
   1 · TIPOGRAFÍA
   El peso 300 desaparece: al sol un texto fino se borra.
   ========================================================================= */
body {
  font-family: var(--font);
  color: var(--ink);
  font-weight: 400;
}
h1, h2, h3, h4, h5, h6, .h1, .h2, .h3, .h4, .h5, .h6 {
  font-weight: 600;
  letter-spacing: -.02em;
  color: var(--ink);
}

/* Números, fechas, unidades e identificadores: mono tabular.
   Es lo que permite comparar magnitudes de un vistazo en una columna. */
.data, .fnf-data {
  font-family: var(--font-mono);
  font-variant-numeric: tabular-nums;
  white-space: nowrap;
}
.fnf-label {
  font-family: var(--font-mono);
  font-size: 11px;
  letter-spacing: .12em;
  text-transform: uppercase;
  color: var(--ink-soft);
}

/* 16px mínimo en los campos: por debajo, iOS hace zoom al enfocar y
   descoloca la página en medio de un alta. */
input, select, textarea,
.form-control, .custom-select {
  font-family: var(--font);
  font-size: 16px;
  color: var(--ink);
}

/* ============================================================================
   2 · EL VERDE COMO TEXTO
   Este bloque es el que más se nota: afecta a todos los enlaces de las 17
   pantallas. #00c896 sobre blanco da 2,17:1; --brand-deep da 5,33:1.
   ========================================================================= */
a,
a:not([class]),
.page-link,
.text-primary {
  color: var(--brand-deep);
}
a:hover, a:focus, .page-link:hover {
  color: #05604a;
}

/* El foco se ve. El tema no define ningún anillo propio. */
a:focus-visible,
button:focus-visible,
input:focus-visible,
select:focus-visible,
textarea:focus-visible,
.btn:focus-visible {
  outline: none;
  box-shadow: var(--glow);
}
.form-control:focus, .custom-select:focus {
  border-color: var(--brand);
  box-shadow: var(--glow);
}

/* ============================================================================
   3 · BOTONES
   El tema declara el MISMO background-color en .btn-primary, :hover,
   :active y :disabled — los botones de la app no responden al dedo.
   Aquí recuperan sus estados y la altura mínima con guante (48px).
   ========================================================================= */
.btn {
  font-family: var(--font);
  font-weight: 600;
  min-height: 48px;
  padding: 12px 20px;
  border-radius: var(--r-s);
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 8px;
  transition: background-color var(--t-fast) var(--ease),
              border-color var(--t-fast) var(--ease),
              color var(--t-fast) var(--ease);
}
.btn-sm { min-height: 40px; padding: 8px 14px; font-size: 14px; }
.btn-lg { min-height: 56px; padding: 16px 24px; font-size: 16px; }

/* --- el peso, contra el tema -------------------------------------------------
   `style.blue.css:1760` mete un `font-weight: 300 !important` a TODO <button>
   e <input type=submit>. Ese `!important` le gana a lo de aqui, asi que los 99
   botones escritos con <button> --los de enviar, y los selectpicker, que son
   <button>-- salian en 300 mientras los 123 escritos con <a class="btn">
   salian en 600: el mismo boton con dos pesos segun como estuviera hecho.
   Ademas va contra la primera regla de esta hoja ("el peso 300 desaparece").
   Se responde con su misma arma, que es lo que ya se hace con el menu lateral. */
button,
input[type="submit"] {
  font-weight: 400 !important;
}

button.btn,
input[type="submit"].btn {
  font-weight: 600 !important;
}

/* --- primaria --- */
.btn-primary,
.btn-success {
  background-color: var(--brand);
  border-color: var(--brand);
  color: var(--on-brand);
}
.btn-primary:hover, .btn-success:hover {
  background-color: var(--brand-bright);
  border-color: var(--brand-bright);
  color: var(--on-brand);
}
/* :not(:disabled):not(.disabled) replica la especificidad del tema, que es
   como consigue pintar el activo. Sin esto no ganaríamos sin !important. */
.btn-primary:not(:disabled):not(.disabled):active,
.btn-primary:not(:disabled):not(.disabled).active,
.btn-success:not(:disabled):not(.disabled):active,
.btn-success:not(:disabled):not(.disabled).active {
  background-color: var(--brand-press);
  border-color: var(--brand-press);
  color: var(--on-brand);
}
.btn-primary.disabled, .btn-primary:disabled,
.btn-success.disabled, .btn-success:disabled {
  background-color: var(--disabled-bg);
  border-color: var(--disabled-bg);
  color: var(--disabled-ink);
  opacity: 1;              /* el tema lo resolvía con opacity y se leía peor */
}

/* --- secundaria --- */
.btn-secondary, .btn-outline-secondary {
  background-color: transparent;
  border-color: var(--line-strong);
  color: var(--ink);
}
.btn-secondary:hover, .btn-outline-secondary:hover {
  background-color: var(--bg-alt);
  border-color: var(--ink-soft);
  color: var(--ink);
}

/* --- terciaria (enlaces con aspecto de botón) --- */
.btn-link {
  color: var(--brand-deep);
  font-weight: 600;
}
.btn-link:hover { color: #05604a; background-color: var(--bg-alt); }

/* --- destructiva ---
   Sólida SOLO dentro de una confirmación. En una fila de tabla va en
   contorno y callada: hoy está ahí y hasta el paso 3 de la guía (el menú
   ⋯) seguirá estando, así que al menos que no grite más que "Editar". */
.btn-danger {
  background-color: var(--bad);
  border-color: var(--bad);
  color: #fff;
}
.btn-danger:hover {
  background-color: #a83434;
  border-color: #a83434;
  color: #fff;
}
.btn-outline-danger {
  background-color: transparent;
  border-color: var(--line-strong);
  color: var(--bad);
}
.btn-outline-danger:hover {
  background-color: var(--bad-bg);
  border-color: var(--bad);
  color: #8f2e2e;
}

/* El amarillo de "Editar" da 1,63:1 sobre blanco: ilegible. Mientras el
   par Editar/Borrar siga en la fila (paso 3 de la guía), al menos que se
   lea: pasa a secundaria con tinta normal. */
.btn-warning, .btn-outline-warning {
  background-color: transparent;
  border-color: var(--line-strong);
  color: var(--ink);
}
.btn-warning:hover, .btn-outline-warning:hover {
  background-color: var(--bg-alt);
  border-color: var(--ink-soft);
  color: var(--ink);
}

/* El "+ Parte" de la cabecera: con etiqueta en pantallas anchas. */
.fnf-newpart__t { display: none; }
@media (min-width: 768px) {
  .fnf-newpart__t {
    display: inline;
    font-size: 13px;
    margin-left: 6px;
  }
}

/* ============================================================================
   4 · PASTILLAS DE ESTADO
   Siempre icono + texto: al sol el color se lava antes que la forma.
   ========================================================================= */
.fnf-pill {
  display: inline-flex;
  align-items: center;
  gap: 5px;
  border-radius: var(--r-s);
  padding: 3px 8px;
  font-family: var(--font-mono);
  font-size: 11px;
  font-weight: 600;
  white-space: nowrap;
}
.fnf-pill--ok   { background: var(--ok-bg);   color: var(--ok); }
.fnf-pill--warn { background: var(--warn-bg); color: var(--warn); }
.fnf-pill--bad  { background: var(--bad-bg);  color: var(--bad); }

/* Chips: atajos de filtro y filtros puestos. Copiados del documento de
   componentes (fnf-componentes-v1.html, `.fnf-chip`), con los tokens de aqui.
   Son accion secundaria: 32px, no los 44 del objetivo tactil de los botones. */
.fnf-chip {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  height: 32px;
  padding: 0 10px;
  background: var(--paper);
  border: 1px solid var(--line);
  border-radius: var(--r-s);
  font-family: var(--font-mono);
  font-size: 12px;
  color: var(--ink);
  text-decoration: none;
  white-space: nowrap;
}

.fnf-chip:hover {
  background: var(--bg-alt);
  color: var(--ink);
  text-decoration: none;
}

.fnf-chip:focus-visible {
  outline: none;
  box-shadow: var(--glow);
}

/* ============================================================================
   5 · TABLAS
   La retícula actual está bien —hairlines de 1px, sin zebra, densidad
   correcta— y se conserva. Aquí solo el contenido de las celdas.
   ========================================================================= */
.table {
  color: var(--ink);
  font-size: 14px;
}
.table thead th {
  font-family: var(--font-mono);
  font-size: 11px;
  font-weight: 400;
  letter-spacing: .12em;
  text-transform: uppercase;
  color: var(--ink-soft);
  border-bottom: 1px solid var(--line-strong);
  border-top: 0;
  white-space: nowrap;
  vertical-align: middle;
}
.table td {
  border-top: 1px solid var(--line);
  vertical-align: middle;
  height: 52px;             /* fila cómoda con el dedo */
}
.table tbody tr:hover { background-color: var(--bg-alt); }

/* Acciones de fila: compactas y en línea.
   Con el tamaño por defecto (48px de alto y 20px de padding) los dos
   botones no caben en la celda y se apilan, duplicando la altura de la
   fila. 40px sigue por encima del mínimo cómodo y no rompe la tabla.
   El objetivo de 48px llega en el paso 3, cuando los dos botones se
   sustituyan por un único ⋯ de 48x48. */
.table td .btn {
  min-height: 40px;
  padding: 7px 14px;
  font-size: 13px;
  white-space: nowrap;
}
.table td .btn + .btn { margin-left: 6px; }
.table td { white-space: normal; }

/* Pista de que la tabla sigue a la derecha: hoy en móvil el último botón
   queda cortado por el borde y nada lo indica. (§11-A de la guía) */
.table-responsive { position: relative; }

/* Notas y observaciones largas: dos líneas con elipsis. El texto completo
   sigue disponible en el title. Acotar el ancho es lo que fuerza el corte;
   sin él, la celda crecería con el contenido y no habría nada que truncar. */
.fnf-c-notas {
  display: -webkit-box;
  -webkit-line-clamp: 2;
  -webkit-box-orient: vertical;
  overflow: hidden;
  max-width: 34ch;
}

/* Celda de acción visible que no es el menú ⋯ (p. ej. "Añadir" del
   catálogo). Tiene que quedar por encima del enlace estirado de la fila,
   o el botón deja de ser pulsable. No se oculta en móvil como fnf-c-act. */
.table td.fnf-c-accion { position: relative; z-index: 2; }

/* ============================================================================
   6 · BARRA SUPERIOR Y NAVEGACIÓN
   ========================================================================= */
.navbar, .page-holder .navbar { background-color: var(--carbon); }

/* Logo y cierre de sesión visibles también en móvil: por debajo de 576px
   no había forma de salir de la sesión, justo en el móvil compartido de
   una cuadrilla. */
.navbar-brand { display: inline-block; }

/* ============================================================================
   6b · MENÚ LATERAL — COLOR Y ESTADO

   El tema (style.blue.css:483-513) gana a los selectores cortos: su
   `nav.side-navbar ul li.active > a` es (0,2,4) y el que había aquí era
   (0,2,2). Por eso el item activo salia en BLANCO sobre --brand: 2,16:1
   medido, que no pasa ni AA ni el 3:1 de texto grande. Se replica la
   especificidad del tema, sin subirla mas de lo necesario y sin !important.
   ========================================================================= */

/* El fondo lo pinta `.page`, no `body` (body es #fff y .page-content,
   .content-inner y .container-fluid son transparentes). #f6f6f6 es gris
   puro y el brandbook lo prohibe: los neutros llevan sesgo verde. */
.page { background-color: var(--bg); }

/* Sidebar en --paper con hairline, no el manchon difuso del box-shadow
   del tema. La nav oscura del sistema es la barra superior, que ya lo es;
   el lateral va claro porque esto se opera en campo, al sol. */
nav.side-navbar {
  background-color: var(--paper);
  color: var(--ink);
  box-shadow: none;
  border-right: 1px solid var(--line);
}

nav.side-navbar span.heading {
  color: var(--ink-soft);          /* era #ccc sobre blanco: 1,61:1 */
  font-family: var(--font-mono);
  font-size: 11px;
  font-weight: 400;
  letter-spacing: .12em;
}

nav.side-navbar .title p {
  color: var(--ink-soft);          /* era #aaa: 2,32:1 */
  font-weight: 400;
}

/* REGLA DURA: ninguna barra de acento lateral. El tema pone
   `border-left: 4px solid transparent` a todos los enlaces y la colorea de
   verde en hover y activo. Se anula en los cinco selectores y los 4px se
   devuelven como padding, para que el texto no se desplace. */
nav.side-navbar ul li a,
nav.side-navbar ul li a:hover,
nav.side-navbar ul li.active > a,
nav.side-navbar ul li.active > a:hover,
nav.side-navbar ul li li.active > a {
  border-left: 0;
  box-shadow: none;
}

nav.side-navbar ul li a {
  padding: 10px 15px 10px 19px;    /* 15 + los 4 del borde suprimido */
  color: var(--ink);
  font-weight: 400;                /* el 300 del tema se borra al sol */
  min-height: 44px;                /* objetivo tactil */
  display: flex;
  align-items: center;
  gap: 10px;
}

/* El tema vuelve a poner #aaa (2,32:1) en los dos estados comprimidos:
   `nav.side-navbar.shrinked ul li a` (style.blue.css:530) y la media query
   de :602. Justo los dos que se ven en un movil en el campo, que es donde
   mas falta hace leerlo. Se replica su especificidad. */
nav.side-navbar.shrinked ul li a,
nav.side-navbar.shrinked ul li a i {
  color: var(--ink);
}

@media (max-width: 1199px) {
  nav.side-navbar ul li a { color: var(--ink); }
  nav.side-navbar ul li a i { color: var(--ink); }
}

nav.side-navbar ul li li a {
  padding-left: 54px;              /* 50 + 4, mismo criterio */
  background: transparent;
}

/* Hover distinto del activo. Antes eran el mismo pixel (--brand + blanco)
   y al mover el raton se perdia "donde estoy". Ademas baja de 4 a 2 los
   bloques verdes grandes simultaneos en pantalla. */
nav.side-navbar ul li a:hover,
nav.side-navbar ul li a:focus-visible {
  background-color: var(--bg-alt);
  color: var(--ink);
}

/* Activo: relleno de marca con tinta --on-brand = 7,91:1 (AAA). La senal
   es relleno mas peso, nunca una barra lateral. */
nav.side-navbar ul li.active > a,
nav.side-navbar ul li li.active > a {
  background-color: var(--brand);
  color: var(--on-brand);
  font-weight: 600;
}

nav.side-navbar ul li.active > a:hover {
  background-color: var(--brand-press);
  color: var(--on-brand);
}

/* Seccion que contiene la hoja activa (“Campo” cuando estas en el cuaderno).
   Se marca con tinta de marca y peso, nunca con relleno: el relleno queda
   para la hoja, y dos bloques verdes grandes a la vez rompen la proporcion
   del 5% de acento del brandbook. Lo pone el servidor (agridashboard/nav.py),
   asi que sale igual en las 110 vistas. */
nav.side-navbar ul li.activa > a,
nav.side-navbar ul li.activa > a i {
  color: var(--brand-deep);
  font-weight: 600;
}

/* La seccion abierta no lleva el fondo de hover: el hover es para el raton,
   no para “estas aqui”. */
nav.side-navbar ul li.activa > a:hover {
  background-color: transparent;
  color: var(--brand-deep);
}

/* El menu comprimido (el hamburguesa de la barra superior; front.js:49
   hace toggleClass('shrinked')) tiene su propio juego de reglas en el tema,
   una especificidad por encima: `nav.side-navbar.shrinked ul li.active > a`
   es (0,3,4) y volvia a poner blanco sobre verde, 2,16:1. Se iguala. */
nav.side-navbar.shrinked ul li.active > a,
nav.side-navbar.shrinked ul li.active > a i {
  color: var(--on-brand);
}

nav.side-navbar.shrinked ul li a:hover,
nav.side-navbar.shrinked ul li a:hover i {
  background-color: var(--bg-alt);
  color: var(--ink);
}

/* Mismo caso que el activo: el tema pinta `--ink` en el menu comprimido y
   (0,3,4) le gana a la regla de seccion activa. Se iguala la especificidad. */
nav.side-navbar.shrinked ul li.activa > a,
nav.side-navbar.shrinked ul li.activa > a i {
  color: var(--brand-deep);
}

/* Al aclarar el fondo de .page, los paneles blancos dejan de separarse por
   contraste de fondo (1,05:1 -> 1,02:1). El tema los apoya en una sombra y
   les pone `border: 0`; el sistema los separa con hairline. */
.card {
  background-color: var(--paper);
  border: 1px solid var(--line);
  border-radius: var(--r-m);
  box-shadow: none;
}

/* ============================================================================
   7 · FORMULARIOS
   Las etiquetas dejan de ser gris claro: al sol es lo primero que
   desaparece, y es lo que dice qué hay que escribir.
   ========================================================================= */
label, .form-group > label {
  color: var(--ink);
  font-weight: 600;
  font-size: 14px;
  margin-bottom: 6px;
}
.form-control, .custom-select {
  min-height: 48px;
  border: 1px solid var(--line-strong);
  border-radius: var(--r-s);
  padding: 12px;
}
.form-text, .help-block { color: var(--ink-soft); font-size: 13px; }
.invalid-feedback, .errorlist { color: var(--bad); font-size: 13px; }

/* ============================================================================
   8 · ESTADOS VACÍO / CARGA / ERROR
   Hoy no existe ninguno: en Palés se dibujan las cabeceras y debajo un
   rectángulo blanco de 30px, sin distinguir "vacío" de "ha fallado".
   ========================================================================= */
.fnf-empty { text-align: center; padding: 48px 24px; }
.fnf-empty__ico { font-size: 32px; color: var(--line-strong); line-height: 1; }
.fnf-empty h3 { font-size: 16px; font-weight: 600; margin: 14px 0 6px; }
.fnf-empty p { margin: 0 0 18px; color: var(--ink-soft); font-size: 14px; }

.fnf-banner {
  display: flex;
  gap: 12px;
  padding: 14px 16px;
  border-radius: var(--r-s);
  font-size: 14px;
  align-items: flex-start;
  /* El estado lo dicen el fondo y el icono, no una barra de acento a la
     izquierda: ese recurso está descartado en todo el diseño. El borde
     completo separa el aviso de lo que tiene alrededor sin señalar un lado. */
  border: 1px solid transparent;
  color: var(--ink);
}
.fnf-banner--ok   { background: var(--ok-bg);   border-color: var(--ok); }
.fnf-banner--warn { background: var(--warn-bg); border-color: var(--warn); }
.fnf-banner--bad  { background: var(--bad-bg);  border-color: var(--bad); }

/* El icono del aviso lleva el color del estado. El comentario de arriba dice
   que el estado lo dicen el fondo y el icono, y hasta ahora el icono era un
   glifo de aviso heredado de la tinta: la clase `ico` que llevaba no existe en
   ninguna hoja de estilos. */
.fnf-banner__ico { flex: none; }
.fnf-banner--ok   .fnf-banner__ico { color: var(--ok); }
.fnf-banner--warn .fnf-banner__ico { color: var(--warn); }
.fnf-banner--bad  .fnf-banner__ico { color: var(--bad); }

/* ============================================================================
   9 · PAGINACIÓN
   ========================================================================= */
.pagination .page-link {
  color: var(--brand-deep);
  min-height: 44px;
  display: inline-flex;
  align-items: center;
}
.pagination .page-item.active .page-link {
  background-color: var(--brand);
  border-color: var(--brand);
  color: var(--on-brand);
}


/* ============================================================================
   10 · ACCIONES DE FILA  (14-direccion-visual-v1.md §7bis)
   La lista sirve para encontrar; el destino, para hacer. La fila no lleva
   botones: es un enlace. El ⋯ es un atajo de escritorio que solo aparece
   cuando el ratón o el teclado lo piden.
   ========================================================================= */

/* Enlace estirado sobre toda la fila. Es el `stretched-link` de Bootstrap,
   que no existe en la 4.1.1 (llegó en la 4.3), así que va aquí.
   Al ser un <a> real funcionan el clic central, ctrl+clic y "abrir en
   pestaña nueva", y el lector de pantalla lo anuncia una sola vez. */
.table tbody tr { position: relative; }
.fnf-row-link { color: var(--ink); text-decoration: none; font-weight: 600; }
.fnf-row-link:hover { color: var(--ink); }
.fnf-row-link::after {
  content: "";
  position: absolute;
  inset: 0;
  z-index: 1;
}
/* La celda de acciones va por encima del enlace estirado. */
.table td.fnf-c-act { position: relative; z-index: 2; width: 56px; text-align: right; }

/* El ⋯ */
.fnf-rowact { position: relative; display: inline-block; }
.fnf-rowact__btn {
  width: 48px; height: 48px;
  display: inline-flex; align-items: center; justify-content: center;
  border: 1px solid transparent; border-radius: var(--r-s);
  background: transparent; color: var(--ink-soft);
  cursor: pointer; font-size: 18px; line-height: 1;
}
.fnf-rowact__btn:hover { background: var(--bg-alt); color: var(--ink); }
.fnf-rowact__btn:focus-visible { outline: none; box-shadow: var(--glow); }
.fnf-rowact__menu {
  position: absolute; right: 0; top: 52px; z-index: 30; min-width: 190px;
  background: var(--paper); border: 1px solid var(--line);
  border-radius: var(--r-m); box-shadow: var(--shadow);
  padding: 6px; display: none; text-align: left;
}
.fnf-rowact.is-open .fnf-rowact__menu { display: block; }
.fnf-rowact__menu a {
  display: flex; align-items: center; min-height: 44px; padding: 0 12px;
  border-radius: var(--r-s); text-decoration: none; color: var(--ink);
  font-size: 14px; font-weight: 400;
}
.fnf-rowact__menu a:hover { background: var(--bg-alt); color: var(--ink); }

/* Móvil: ningún control en la fila. La tabla hace scroll horizontal, así que
   la última columna no está garantizada en pantalla; un ⋯ recortado por el
   borde es el mismo problema que la "E" roja que quitamos. */
@media (max-width: 991.98px) {
  .table td.fnf-c-act, .table th.fnf-c-act { display: none; }
}

/* Escritorio: revelado. Vale como hover porque NO es la única vía — la fila
   entera lleva al mismo sitio. Es un atajo, no un requisito. */
@media (min-width: 992px) {
  .table td.fnf-c-act .fnf-rowact__btn { opacity: 0; transition: opacity var(--t-fast) var(--ease); }
  .table tbody tr:hover .fnf-rowact__btn,
  .table tbody tr:focus-within .fnf-rowact__btn,
  .fnf-rowact.is-open .fnf-rowact__btn { opacity: 1; }
}

/* Eliminar, al pie del formulario de edición: separado y en terciaria. */
.fnf-danger-zone {
  margin-top: var(--s-8);
  padding-top: var(--s-5);
  border-top: 1px solid var(--line);
}
.fnf-danger-zone .btn { min-height: 44px; }


/* ============================================================================
   11 · FILTROS  (14-direccion-visual-v1.md §8)
   El buscador existía en 14 secciones, colapsado tras un embudo de 40x40 sin
   etiqueta. En un catálogo de 2.730 productos eso equivale a no tenerlo.
   ========================================================================= */

/* Los filtros arrancan abiertos en escritorio y cerrados en móvil, pero eso
   NO se hace desde aquí: forzar `display:block` cuando Bootstrap quita la
   clase `.show` deja el panel abierto para siempre y el botón muerto (pasó).
   Se resuelve añadiendo la clase `show` al cargar; ver el script en
   templates/index.html. */
#collapseFilter .card-body {
  background: var(--bg-alt);
  border: 1px solid var(--line);
  border-radius: var(--r-m);
}
#collapseFilter label {
  font-family: var(--font-mono);
  font-size: 11px;
  letter-spacing: .12em;
  text-transform: uppercase;
  color: var(--ink-soft);
  font-weight: 400;
}
/* El botón "Filtros" ya no es un icono mudo. */
a[href="#collapseFilter"] { font-weight: 600; }

/* ============================================================================
   12 · FICHA DEL PARTE, Y SU HOJA DE IMPRESIÓN
   Los partes de tratamiento fitosanitario y de abonado forman parte del
   cuaderno de explotación y hay que poder enseñarlos impresos en una
   inspección (RD 1311/2012). La ficha se diseña como documento, no como
   pantalla: por eso repite empresa y nº de parte en la cabecera y lleva
   pie con firmas.
   ========================================================================= */

.fnf-parte { max-width: 900px; padding-top: var(--s-6); }

.fnf-parte__acciones {
  display: flex; align-items: center; gap: var(--s-2);
  margin-bottom: var(--s-5);
}

.fnf-parte__cab {
  display: flex; flex-wrap: wrap; gap: var(--s-5);
  justify-content: space-between; align-items: flex-start;
  padding-bottom: var(--s-5);
  border-bottom: 2px solid var(--ink);
}
.fnf-parte__titulo { font-size: 26px; font-weight: 700; margin: 4px 0 0; }
.fnf-parte__sub { margin: 4px 0 0; color: var(--ink-soft); font-size: 14px; }
.fnf-parte__fechas { display: flex; gap: var(--s-6); }
.fnf-parte__fechas > div { display: flex; flex-direction: column; gap: 3px; }

.fnf-bloque { padding: var(--s-6) 0; border-bottom: 1px solid var(--line); }
.fnf-bloque__t {
  font-size: 13px; font-weight: 600; text-transform: uppercase;
  letter-spacing: .08em; color: var(--ink-soft); margin: 0 0 var(--s-4);
}

/* Pares etiqueta/valor. Cinco tablas de una sola fila era lo que había. */
.fnf-datos { display: grid; grid-template-columns: repeat(auto-fit, minmax(190px, 1fr));
             gap: var(--s-4) var(--s-6); margin: 0; }
.fnf-datos dt { font-family: var(--font-mono); font-size: 11px; font-weight: 400;
                letter-spacing: .1em; text-transform: uppercase; color: var(--ink-soft); }
.fnf-datos dd { margin: 3px 0 0; font-size: 15px; }
.fnf-obs { margin: var(--s-5) 0 0; font-size: 14px; }

.fnf-tabla-doc { margin-bottom: 0; }
.fnf-tabla-doc td { height: auto; padding: 10px 12px; }
.fnf-nota-legal { margin: var(--s-3) 0 0; font-size: 12px; color: var(--ink-soft); }

.solo-imprimir { display: none; }

/* --------------------------------------------------------------------------
   Impresión
   -------------------------------------------------------------------------- */
@media print {
  @page { size: A4; margin: 14mm 12mm; }

  /* Fuera todo lo que no es el documento. */
  .navbar, .side-navbar, .no-imprimir,
  .fnf-danger-zone, .fnf-rowact, footer.no-imprimir { display: none !important; }
  .page, .page-content, .container, .fnf-parte { margin: 0 !important; padding: 0 !important; max-width: none !important; }
  /* `.content-inner` reserva 250 px para el menu lateral. Sin el menu, esa
     franja quedaba en blanco en el papel y el documento salia estrecho y
     descentrado. */
  .content-inner, .content-inner.active {
    width: 100% !important;
    min-height: 0 !important;
    padding: 0 !important;
  }

  body { background: #fff; color: #000; font-size: 11pt; }
  a { color: #000; text-decoration: none; }

  .solo-imprimir { display: block; }

  /* Tinta: los grises claros no se ven impresos. */
  .fnf-datos dt, .fnf-bloque__t, .muted, .fnf-nota-legal { color: #333; }
  .fnf-tabla-doc th { color: #000; border-bottom: 1px solid #000; }
  .fnf-tabla-doc td { border-top: 1px solid #bbb; }
  .fnf-pill { border: 1px solid #000; background: none !important; color: #000 !important; }

  /* Que una sección no se parta a la mitad. */
  .fnf-bloque { break-inside: avoid; page-break-inside: avoid; }
  thead { display: table-header-group; }   /* cabecera repetida en cada hoja */
  tr { break-inside: avoid; page-break-inside: avoid; }

  .fnf-parte__pie {
    margin-top: 16mm; padding-top: 4mm; border-top: 1px solid #000;
    font-size: 9pt; color: #333;
  }
  .fnf-firma { display: flex; gap: 20mm; margin-top: 14mm; }
  .fnf-firma span {
    flex: 1; border-top: 1px solid #000; padding-top: 2mm;
    font-size: 9pt; text-align: center;
  }
}

/* ============================================================================
   13 · FORMULARIOS  (14-direccion-visual-v1.md §12)
   ========================================================================= */

/* Las pestañas del alta de parte son cinco y en móvil las dos últimas
   —Producto y Servicio externo— quedaban fuera de pantalla sin ninguna
   pista. Ahí es justo donde se registra el fitosanitario. */
.nav-tabs {
  flex-wrap: nowrap;
  overflow-x: auto;
  scroll-snap-type: x mandatory;
  -webkit-overflow-scrolling: touch;
  scrollbar-width: none;
  border-bottom: 1px solid var(--line);
}
.nav-tabs::-webkit-scrollbar { display: none; }
.nav-tabs .nav-item { flex: none; scroll-snap-align: start; }
.nav-tabs .nav-link {
  min-height: 48px;
  display: flex;
  align-items: center;
  gap: 7px;
  white-space: nowrap;
  border: 0;
  border-bottom: 2px solid transparent;
  border-radius: 0;
  color: var(--ink-soft);
  font-size: 14px;
}
.nav-tabs .nav-link:hover { border-color: transparent transparent var(--line-strong); color: var(--ink); }
.nav-tabs .nav-link.active {
  color: var(--ink);
  font-weight: 600;
  background: transparent;
  border-bottom-color: var(--brand);
}
/* Degradado a la derecha: dice "hay más" sin ocupar sitio. */
.nav-tabs-responsive { position: relative; }
.nav-tabs-responsive::after {
  content: "";
  position: absolute; right: 0; top: 0; height: 48px; width: 28px;
  pointer-events: none;
  background: linear-gradient(90deg, rgba(251,253,252,0), var(--bg));
}

/* Barra de acción fija en móvil: el botón de guardar deja de estar al
   final de un formulario de cinco pestañas. */
@media (max-width: 767.98px) {
  form .btn-block.mt-5,
  form .btn-block.mt-4 {
    position: sticky;
    bottom: 0;
    z-index: 20;
    margin-top: var(--s-6) !important;   /* gana al .mt-5 de Bootstrap */
    min-height: 56px;
    box-shadow: 0 -8px 24px -18px rgba(6, 20, 15, .4);
  }
}

/* Los desplegables nativos y los selectpicker convivían con dos aspectos
   distintos en el mismo formulario. Igualar el alto es lo que se puede
   hacer sin tocar el JavaScript de bootstrap-select. */
.bootstrap-select > .dropdown-toggle,
.bootstrap-select .btn {
  min-height: 48px;
  border: 1px solid var(--line-strong);
  border-radius: var(--r-s);
  background: var(--paper);
  color: var(--ink);
  /* Con `!important` porque el boton del selectpicker es un <button> y arrastra
     el 300 !important del tema: enseña un VALOR, no una accion, asi que va a
     400 como el texto de un input. Gana a `button.btn` por especificidad. */
  font-weight: 400 !important;
}
.bootstrap-select > .dropdown-toggle:focus { box-shadow: var(--glow); }

/* El resumen de errores, con sus enlaces. */
.fnf-banner ul { margin: 6px 0 0; padding-left: 18px; }
.fnf-banner li { margin-top: 2px; }


/* En los formsets, el botón de quitar la fila va con `float-right` y el
   <hr> que lo sigue NO limpia el flotado, así que la línea se dibuja por
   encima del botón. Se veía poco con los 38px del tema; con los 48px de
   objetivo táctil lo cruza entero. */
form hr {
  clear: both;
  margin-top: var(--s-5);
  margin-bottom: var(--s-5);
  border-top-color: var(--line);
}

/* ============================================================================
   14 · ZONA DE ACCIONES DE UN FORMULARIO LARGO  (§12bis)
   El problema no era el botón: en el alta de parte hay TRES niveles de
   acción —fila, bloque y documento— y los tres se veían igual. Peor: el
   más llamativo, el rojo, era el de MENOR alcance.
   El alcance se comunica con encuadre, no con color.
   ========================================================================= */

/* Nivel 1 · fila del formset. No borra nada guardado: quita una fila de un
   borrador. Por eso ni rojo ni papelera. */
.formset_delete {
  color: var(--ink-soft);
  border-color: var(--line);
  font-weight: 400;
}
.formset_delete:hover {
  background: var(--bg-alt);
  border-color: var(--ink-soft);
  color: var(--ink);
}
.formset_delete span { font-size: 16px; line-height: 1; }
@media (max-width: 767.98px) {
  /* En móvil solo el aspa; el nombre lo lleva el aria-label. */
  .formset_delete { font-size: 0; padding: 8px 12px; }
  .formset_delete span { font-size: 18px; }
}

/* Nivel 3 · el documento. Vive FUERA del panel de pestañas: dentro, la
   barra parecería pertenecer solo a la pestaña abierta. */
.fnf-form-actions {
  display: flex;
  align-items: center;
  justify-content: flex-end;
  gap: var(--s-3);
  margin-top: var(--s-8);
  padding: var(--s-4) 0;
  border-top: 1px solid var(--line);
  position: sticky;
  bottom: 0;
  background: var(--bg);
  z-index: 15;
}
/* Cancelar en terciaria: las dos opciones no son equivalentes, y con borde
   parecerían dos botones compitiendo. */
.fnf-form-actions__cancel { color: var(--ink-soft); font-weight: 400; }
.fnf-form-actions__cancel:hover { color: var(--ink); }
.fnf-form-actions__save { min-width: 170px; }

@media (max-width: 767.98px) {
  /* Aquí el ancho completo SÍ es correcto: son 358px, no 1790. */
  .fnf-form-actions {
    flex-direction: column-reverse;
    gap: var(--s-2);
    background: var(--paper);
    padding: var(--s-3) var(--s-4) calc(var(--s-3) + env(safe-area-inset-bottom));
    margin-left: calc(var(--s-4) * -1);
    margin-right: calc(var(--s-4) * -1);
    box-shadow: 0 -8px 24px -18px rgba(6, 20, 15, .4);
  }
  .fnf-form-actions__save,
  .fnf-form-actions__cancel { width: 100%; }
  .fnf-form-actions__save { min-height: 56px; }
}

/* Estado "guardando": el texto se queda y el ancho no cambia, para que el
   dedo que ya iba en camino no pulse otra cosa. */
.btn.is-loading { pointer-events: none; opacity: .85; }
.btn.is-loading::before {
  content: "";
  width: 14px; height: 14px; border-radius: 50%;
  border: 2px solid currentColor; border-right-color: transparent;
  animation: fnf-spin .7s linear infinite;
  flex: none; margin-right: 8px;
}
@keyframes fnf-spin { to { transform: rotate(1turn); } }

/* ============================================================================
   15 · CABECERA Y DATOS DEL USUARIO  (§9)
   La barra era blanca y se confundía con el contenido; el brandbook la
   quiere carbon, «el techo de la sala de control». Y la identidad del
   usuario vivía en el menú lateral sin ninguna acción asociada.
   ========================================================================= */

.header .navbar,
header.header {
  background-color: var(--carbon);
  border-bottom: 0;
}
.header .navbar-holder { min-height: 56px; }


/* La hamburguesa tenía tres rayas sin nombre accesible. */
#toggle-btn span { background-color: var(--ink-on-dark); }

/* "+ Parte", la acción principal. */
.fnf-newpart {
  display: inline-flex;
  align-items: center;
  min-height: 40px;
  padding: 0 14px;
  border-radius: var(--r-s);
  background: var(--brand);
  color: var(--on-brand);
  font-weight: 600;
  font-size: 14px;
}
.fnf-newpart:hover { background: var(--brand-bright); color: var(--on-brand); }

/* --- Chip de usuario --------------------------------------------------- */
.fnf-user { margin-left: var(--s-3); }
.fnf-user__chip {
  display: inline-flex;
  align-items: center;
  gap: 7px;
  min-height: 40px;
  padding: 0 14px;
  border: 1px solid var(--line-dark);
  border-radius: 99px;
  color: var(--ink-on-dark);
  font-family: var(--font-mono);
  font-size: 12px;
  text-decoration: none;
}
.nav-menu .fnf-user__chip,
.fnf-user__chip { color: var(--ink-on-dark); }   /* el tema pintaba el nav en oscuro */
.fnf-user__nombre { color: var(--ink-on-dark); }
.fnf-user__chip:hover,
.fnf-user__chip:focus { border-color: var(--brand); color: #fff; text-decoration: none; }
.fnf-user__chip:hover .fnf-user__nombre { color: #fff; }
.fnf-user__caret { font-size: 10px; opacity: .7; }
.fnf-user__menu { min-width: 220px; padding: 6px; border: 1px solid var(--line); border-radius: var(--r-m); }
.fnf-user__quien {
  display: block;
  padding: 8px 12px 10px;
  border-bottom: 1px solid var(--line);
  margin-bottom: 6px;
  font-size: 14px;
  font-weight: 600;
  color: var(--ink);
}
.fnf-user__quien em {
  display: block;
  font-style: normal;
  font-weight: 400;
  font-size: 12px;
  color: var(--ink-soft);
  margin-top: 2px;
}
.fnf-user__menu .dropdown-item {
  min-height: 44px;
  display: flex;
  align-items: center;
  border-radius: var(--r-s);
  font-size: 14px;
}
.fnf-user__menu .dropdown-item:hover { background: var(--bg-alt); color: var(--ink); }
.fnf-user__salir { border: 0; background: none; width: 100%; text-align: left; cursor: pointer; }

/* En móvil el chip no cabe: queda el nombre fuera y el bloque completo
   vive al pie del menú lateral, que es donde llega el pulgar. */
@media (max-width: 575.98px) {
  .fnf-user__nombre { display: none; }
  .fnf-user__chip { padding: 0 10px; }
  .fnf-user__chip::before { content: "\f007"; font-family: "Font Awesome 5 Free"; font-weight: 900; }
}

/* --- Bloque de usuario del menú lateral -------------------------------- */
.sidebar-header .title h1 a { color: var(--ink); font-weight: 600; }
.sidebar-header .title p { margin: 2px 0 0; font-size: 13px; color: var(--ink-soft); }
/* A qué explotación perteneces: en una app multiempresa es contexto, no
   adorno. Antes no aparecía en ninguna parte de la interfaz. */
.fnf-empresas {
  font-family: var(--font-mono);
  font-size: 11px;
  letter-spacing: .04em;
  color: var(--brand-deep) !important;   /* gana al `p` del tema */
  margin-top: 4px !important;
}

/* ============================================================================
   16 · BARRA DE HERRAMIENTAS DEL LISTADO
   ========================================================================= */

/* El botón de filtros es un <a> y heredaba el subrayado de enlace. */
a[href="#collapseFilter"] { text-decoration: none; }
a[href="#collapseFilter"]:hover { text-decoration: none; }

/* Filtros y el botón de alta, en la misma fila. Antes iban en dos filas
   separadas con un hueco vacío enorme entre medias. */
.fnf-toolbar-nuevo { float: right; }

/* Fechas y códigos: sin partirse en dos líneas. "21 Feb / 2026" era lo
   que rompía la alineación de la tabla de partes. */
.table td.data, .table td .data { white-space: nowrap; }

/* El Id deja de ir primero: al final, en gris y pequeño. No es un dato
   del agricultor, es una referencia. */
.table td.fnf-c-id, .table th.fnf-c-id {
  font-size: 12px;
  color: var(--ink-soft);
  text-align: right;
  width: 1%;
}


/* --- Logo compuesto, como en fnfanalytics.com -------------------------- */
.fnf-logo { display: inline-flex; align-items: center; gap: 10px; text-decoration: none; }
.fnf-logo:hover { text-decoration: none; }
.fnf-logo__mark { height: 34px; width: auto; }
.fnf-logo__txt { display: inline-block; line-height: 1; }
.fnf-logo__txt b {
  display: block;
  font-size: 19px;
  font-weight: 700;
  letter-spacing: -.02em;
  color: #fff;
}
/* «ANALYTICS» como en la web (fnfanalytics-web/assets/site.css, .logo i):
   mayúsculas, espaciado .42em y el verde de la marca. */
.fnf-logo__txt i {
  display: block;
  font-style: normal;
  font-family: var(--font-mono);
  font-size: 9px;
  letter-spacing: .42em;
  text-transform: uppercase;
  color: var(--brand);
  margin-top: 3px;
}
@media (max-width: 575.98px) { .fnf-logo__txt { display: none; } }

/* --- Migas de pan (§9) ------------------------------------------------- */
/* Mono 11px, mayúsculas y el nivel actual en verde de marca. En móvil no
   caben junto al logo, así que se ocultan por debajo de 768px. */
.fnf-migas {
  display: inline-flex;
  align-items: center;
  gap: 10px;
  margin-left: 14px;
  padding-left: 14px;
  border-left: 1px solid var(--line-dark);
  /* El botón de menú viene justo detrás en el flujo y quedaba a 4 px del
     texto en cualquier ancho. Separarlo aquí y no con un margen en el
     botón, que también se usa cuando no hay migas. */
  margin-right: 18px;
  font-family: var(--font-mono);
  font-size: 11px;
  letter-spacing: .12em;
  text-transform: uppercase;
  color: var(--ink-soft-on-dark);
}
.fnf-migas__actual { color: var(--brand); }
/* En pantallas que no declaran su miga (posts, perfil…) el bloque llega
   vacío: se oculta la barra entera para no dejar un "Inicio /" colgando. */
.fnf-migas__actual:empty { display: none; }
.fnf-migas:has(.fnf-migas__actual:empty) { display: none; }
@media (max-width: 767.98px) {
  .fnf-migas { display: none; }
}

/* --- Aire alrededor de la barra de herramientas del listado ------------ */
/* El botón de alta quedaba pegado al panel de filtros, y con los filtros
   plegados, pegado a la tabla. */
.fnf-toolbar-nuevo { margin-bottom: var(--s-4); }
#collapseFilter { margin-top: var(--s-4); }
#collapseFilter + * { margin-top: var(--s-5); }
.container > .row:first-child { margin-bottom: var(--s-4); }


/* ============================================================================
   13 · CAMPOS OBLIGATORIOS
   El formulario no distinguia obligatorios de opcionales. Se marcan los
   obligatorios, que en el parte son minoria (5 de 11). El asterisco va con
   aria-hidden porque quien use lector de pantalla ya lo oye del atributo
   `required` o del error del servidor; repetirlo seria ruido.
   ========================================================================= */
.fnf-req {
  color: var(--bad);
  font-weight: 600;
  margin-left: 2px;
}

.fnf-leyenda-req {
  font-family: var(--font-mono);
  font-size: 11px;
  color: var(--ink-soft);
  margin-bottom: var(--s-4);
}


/* ============================================================================
   14 · AVISO DE BORRADOR
   Aparece arriba del formulario cuando hay trabajo sin enviar guardado en
   este mismo telefono. No es un error ni una alerta: es una oferta.
   ========================================================================= */
.fnf-borrador {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--s-3);
  background-color: var(--bg-alt);
  border: 1px solid var(--line);
  border-radius: var(--r-m);
  padding: var(--s-3) var(--s-4);
  margin-bottom: var(--s-4);
  font-size: var(--fs-small);
  color: var(--ink);
}

.fnf-borrador span { flex: 1 1 auto; }


/* ============================================================================
   15 · SECCIONES DEL PARTE
   Sustituyen a las 5 pestanas. Una pestana promete contenido y obliga a
   entrar para saber si hay algo; una seccion plegada con su recuento lo dice
   desde fuera.
   ========================================================================= */
.fnf-seccion + .fnf-seccion { margin-top: var(--s-3); }

.fnf-seccion__cabecera {
  display: flex;
  align-items: center;
  gap: var(--s-3);
  width: 100%;
  min-height: 52px;              /* objetivo tactil holgado, con guantes */
  padding: var(--s-3) var(--s-4);
  background-color: var(--bg-alt);
  border: 1px solid var(--line);
  border-radius: var(--r-m);
  color: var(--ink);
  font-family: var(--font);
  font-size: var(--fs-body);
  font-weight: 600;
  text-align: left;
}

.fnf-seccion__cabecera:hover { background-color: var(--paper); }

.fnf-seccion__cabecera:focus-visible {
  outline: 2px solid var(--brand);
  outline-offset: -2px;
}

.fnf-seccion__titulo { flex: 1 1 auto; }

/* El recuento solo aparece cuando hay algo que contar: una seccion vacia no
   necesita un "0" que la haga parecer un error. */
.fnf-seccion__cuenta {
  font-family: var(--font-mono);
  font-size: var(--fs-label);
  color: var(--on-brand);
  background-color: var(--brand);
  border-radius: var(--r-pill);
  padding: 2px 9px;
}

.fnf-seccion__cuenta:empty { display: none; }

/* La flecha la pone el ::after, para no depender de iconos externos. */
.fnf-seccion__cabecera::after {
  content: "";
  width: 9px;
  height: 9px;
  border-right: 2px solid var(--ink-soft);
  border-bottom: 2px solid var(--ink-soft);
  transform: rotate(45deg);
  transition: transform var(--t-fast) var(--ease);
  flex: 0 0 auto;
}

.fnf-seccion__cabecera[aria-expanded="true"]::after { transform: rotate(-135deg); }

.fnf-seccion__cuerpo { padding: var(--s-4) 0 var(--s-2); }


/* ============================================================================
   16 · DIAS SUELTOS
   Tabla que solo aparece al marcar el modo. Para el 93% de los partes, que
   son de un dia, esto no existe.
   ========================================================================= */
.fnf-dias__interruptor { margin-bottom: var(--s-3); }

.fnf-dias {
  background-color: var(--bg-alt);
  border: 1px solid var(--line);
  border-radius: var(--r-m);
  padding: var(--s-4);
  margin-bottom: var(--s-4);
}

.fnf-dias__alta {
  display: flex;
  flex-wrap: wrap;
  align-items: flex-end;
  gap: var(--s-3);
  margin-bottom: var(--s-4);
}

.fnf-dias__alta label {
  flex: 1 0 100%;
  margin-bottom: 0;
}

.fnf-dias__alta input[type="date"] { flex: 1 1 160px; }

.fnf-dias__tabla {
  width: 100%;
  border-collapse: collapse;
  font-size: var(--fs-small);
}

.fnf-dias__tabla th,
.fnf-dias__tabla td {
  padding: var(--s-2) var(--s-2);
  border-bottom: 1px solid var(--line);
  text-align: left;
  vertical-align: middle;
}

.fnf-dias__tabla thead th {
  font-family: var(--font-mono);
  font-size: var(--fs-label);
  letter-spacing: var(--ls-label);
  text-transform: uppercase;
  color: var(--ink-soft);
  font-weight: 400;
}

.fnf-dias__tabla tfoot th,
.fnf-dias__tabla tfoot td {
  font-weight: 600;
  border-bottom: 0;
  border-top: 1px solid var(--line-strong);
}

/* Las cifras derivadas se alinean a la derecha y en mono: se comparan de un
   vistazo y se ve que no son un campo que se teclee. */
.fnf-dias__num {
  text-align: right;
  font-family: var(--font-mono);
  font-variant-numeric: tabular-nums;
}

.fnf-dias__horario {
  display: flex;
  gap: var(--s-2);
  min-width: 190px;
}

.fnf-dias__aviso {
  margin: var(--s-3) 0 0;
  padding: var(--s-3);
  border-radius: var(--r-s);
  background-color: var(--bad-bg);
  color: var(--bad);
  font-size: var(--fs-small);
}

.fnf-dias__nota {
  margin: var(--s-3) 0 0;
  font-size: var(--fs-caption);
  color: var(--ink-soft);
}

@media (max-width: 575px) {
  /* En movil la tabla se lee mal en 5 columnas: cada dia pasa a ser un
     bloque con su etiqueta delante. */
  .fnf-dias__tabla thead { display: none; }
  .fnf-dias__tabla tr { display: block; padding: var(--s-3) 0; border-bottom: 1px solid var(--line); }
  .fnf-dias__tabla td, .fnf-dias__tabla th { display: flex; align-items: center; gap: var(--s-3); border: 0; padding: var(--s-1) 0; }
  .fnf-dias__tabla td::before { content: attr(data-etiqueta); font-family: var(--font-mono); font-size: var(--fs-label); text-transform: uppercase; color: var(--ink-soft); min-width: 86px; }
  .fnf-dias__num { text-align: left; }
}


/* ============================================================================
   17 · CAMPOS DEL CUADERNO (FICHA 6)
   Se agrupan y se marcan como bloque para que se lea que pertenecen al
   registro oficial y no a la gestion interna del parte.
   ========================================================================= */
.fnf-ficha6 { margin-top: var(--s-3); }

.fnf-ayuda {
  display: block;
  margin-top: 2px;
  font-size: var(--fs-caption);
  color: var(--ink-soft);
}

/* Bloque de la ficha 1.3 (equipos de aplicación), igual que el de la 6. */
.fnf-ficha13 { margin-top: var(--s-3); }

/* "opcional" junto al título de una sección que no se espera rellenar en
   esta actividad, pero que sigue ahí: una poda gasta cinta y hay que poder
   apuntarla. */
.fnf-seccion__pista {
  font-family: var(--font-mono);
  font-size: var(--fs-label);
  color: var(--ink-soft);
  font-weight: 400;
}

.fnf-seccion__pista:empty { display: none; }

/* Los datos del cuaderno en el detalle del parte. Se apilan como pares
   etiqueta/valor en una sola columna: una tabla de once columnas no se lee,
   y cada parte solo usa las de su tipo de producto. */
.fnf-aplicacion { max-width: 280px; }

.fnf-dato {
  display: block;
  font-size: var(--fs-caption);
  line-height: 1.5;
}

.fnf-dato b {
  font-family: var(--font-mono);
  font-size: var(--fs-label);
  text-transform: uppercase;
  letter-spacing: .08em;
  color: var(--ink-soft);
  font-weight: 400;
  margin-right: 4px;
}

.fnf-unidades {
  font-family: var(--font-mono);
  font-size: var(--fs-small);
  color: var(--ink);
  margin: 0;
  padding-top: 8px;
}

/* ============================================================================
   18 · EL BOTÓN DE PLEGAR EL MENÚ, Y AIRE BAJO LA CABECERA

   Lo que venía en la plantilla no era una hamburguesa: tres barras de anchos
   distintos (20, 35 y 20 px) y la del medio con dos pseudo-elementos girados
   que dibujaban una especie de flecha. Al plegar el menú las de fuera se
   separaban 12 px y quedaba un garabato.

   Tampoco es una equis, que es lo que se probó primero: la equis promete
   CERRAR, y esta barra no se cierra, se pliega a un lado y deja los iconos.
   Un chevron dice eso, y al plegarla gira 180° para decir que se vuelve a
   abrir. La promesa del icono y lo que hace el botón coinciden.

   Sobre los selectores: el tema usa `nav.navbar .menu-btn span:nth-of-type(2)`
   (0,3,2) y un `.menu-btn` a secas no le gana. Aquí se repite la misma forma
   para empatar en especificidad y ganar por orden, que es lo único que decide
   cuando se empata.
   ========================================================================= */
nav.navbar .menu-btn {
  /* Área de toque de 44 px: el mínimo cómodo en un móvil con guantes, y en el
     campo se usa con guantes. El icono dentro mide 16. */
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 44px;
  height: 44px;
  /* Sin margen izquierdo: la separación con las migas la pone
     `.fnf-migas { margin-right }`, y allí está explicado por qué vive ahí. */
  margin-right: var(--s-5);
  border-radius: var(--r-s);
  position: relative;
  color: var(--ink-on-dark);
  transition: background-color .15s ease;
}

nav.navbar .menu-btn:hover,
nav.navbar .menu-btn:focus-visible {
  background-color: rgba(255, 255, 255, .10);
}

/* Las tres barras del tema se apagan: el chevron se dibuja con las dos
   primeras y la tercera sobra. Se dejan en el HTML porque el javascript del
   tema no las toca y quitarlas de la plantilla no aporta nada. */
nav.navbar .menu-btn span:nth-of-type(1),
nav.navbar .menu-btn span:nth-of-type(2),
nav.navbar .menu-btn span:nth-of-type(3) {
  position: absolute;
  left: 50%;
  top: 50%;
  width: 11px;
  height: 2px;
  margin: 0;
  border-radius: 2px;
  background: currentColor;
  transform-origin: 0 50%;
  transition: transform .22s ease, opacity .15s ease;
}

/* OJO con el estado: `active` en este boton significa menu DESPLEGADO, no
   plegado. El javascript del tema quita la clase y pone `.side-navbar.shrinked`
   a la vez, asi que el sin-clase es el estado plegado. Se comprobo al reves la
   primera vez y el chevron apuntaba justo al contrario de lo que hacia.

   Plegado (sin `.active`): apunta a la DERECHA, hacia donde se va a abrir.
   Los desplazamientos de 4 px centran el dibujo en el boton: el brazo nace en
   el origen y se extiende 7,8 px, asi que sin ellos el chevron queda pegado a
   un lado. */
nav.navbar .menu-btn span:nth-of-type(1) { transform: translate(-4px, -1px) rotate(-45deg); }
nav.navbar .menu-btn span:nth-of-type(2) { transform: translate(-4px, -1px) rotate(45deg); }
nav.navbar .menu-btn span:nth-of-type(3) { opacity: 0; }

/* Fuera la flecha que dibujaba la barra del medio en el tema. */
nav.navbar .menu-btn span:nth-of-type(2)::before,
nav.navbar .menu-btn span:nth-of-type(2)::after { content: none; }

/* Desplegado (`.active`): apunta a la IZQUIERDA, hacia donde se pliega. */
nav.navbar .menu-btn.active span:nth-of-type(1) { transform: translate(4px, -1px) rotate(-135deg); }
nav.navbar .menu-btn.active span:nth-of-type(2) { transform: translate(4px, -1px) rotate(135deg); }
nav.navbar .menu-btn.active span:nth-of-type(3) { opacity: 0; }

/* Quien no quiere animaciones no las tiene. */
@media (prefers-reduced-motion: reduce) {
  nav.navbar .menu-btn,
  nav.navbar .menu-btn span:nth-of-type(1),
  nav.navbar .menu-btn span:nth-of-type(2),
  nav.navbar .menu-btn span:nth-of-type(3) { transition: none; }
}

/* El contenido empezaba pegado a la barra negra: el título de la página y el
   borde de la cabecera se tocaban. */
.content-inner { padding-top: var(--s-6); }

@media (max-width: 767.98px) {
  .content-inner { padding-top: var(--s-5); }
  nav.navbar .menu-btn { margin-right: var(--s-2); }
}

/* ============================================================================
   19 · PAGINADOR (.fnf-pager)
   Segun `fnf-componentes-v1.html` (linea 230). Antes era el `pagination` de
   Bootstrap y decia "1 of 1", en ingles, en una aplicacion en español.
   ========================================================================= */
.fnf-pager {
  display: flex;
  align-items: center;
  justify-content: flex-end;
  gap: var(--s-2);
  padding: var(--s-3) var(--s-4);
  border-top: 1px solid var(--line);
}

.fnf-pager .page-of {
  font-family: var(--font-mono);
  font-size: 12px;
  color: var(--ink-soft);
  padding: 0 var(--s-2);
}

/* Los extremos no desaparecen al llegar a la primera o la ultima pagina: se
   apagan. Que un boton cambie de sitio bajo el dedo es peor que uno inactivo. */
.fnf-pager .is-disabled {
  opacity: .45;
  pointer-events: none;
}

@media (max-width: 600px) {
  .fnf-pager { justify-content: space-between; }
  .fnf-pager .fnf-btn { flex: 1; }
}

/* Los botones de la referencia, lo justo para que el paginador se sostenga.
   El resto de `.fnf-btn` llegara con la barra de herramientas. */
.fnf-btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: var(--s-2);
  font-weight: 600;
  font-size: 15px;
  line-height: 1;
  min-height: 48px;
  padding: 12px 20px;
  border-radius: var(--r-s);
  border: 1px solid transparent;
  background: transparent;
  color: var(--ink);
  text-decoration: none;
  cursor: pointer;
  white-space: nowrap;
}
.fnf-btn--secondary { border-color: var(--line-strong); color: var(--ink); }
.fnf-btn--sm { min-height: 40px; padding: 8px 14px; font-size: 14px; }
.fnf-btn:hover { text-decoration: none; }


/* ============================================================================
   20 · RECUENTO DE ALMACÉN
   Se hace de pie delante de la estantería, con una mano y a veces con guante.
   Por eso no es una tabla: una tabla en un móvil hace scroll horizontal y la
   columna del campo numérico se queda fuera de la pantalla.
   ========================================================================= */
.fnf-recuento__fila {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--s-3);
  padding: var(--s-4) 0;
  border-bottom: 1px solid var(--line);
}
.fnf-recuento__que { flex: 1 1 220px; min-width: 0; }
.fnf-recuento__que b { display: block; font-size: 16px; }
.fnf-recuento__teorico {
  font-family: var(--font-mono);
  font-size: 13px;
  color: var(--ink-soft);
}
.fnf-recuento__cuenta {
  display: flex;
  align-items: center;
  gap: var(--s-2);
  flex: 0 0 auto;
}
/* 7ch cabe "1234,56" y no más: una cifra más larga en un recuento es un
   error de tecleo, y el campo estrecho lo hace evidente. */
.fnf-recuento__cuenta input {
  width: 7.5ch;
  min-width: 96px;
  min-height: 48px;
  font-family: var(--font-mono);
  font-size: 18px;
  text-align: right;
}
.fnf-recuento__cuenta .btn { min-height: 48px; }

/* El descuadre se marca con el fondo del número, no con una barra lateral. */
.fnf-recuento__fila.tiene-descuadre .fnf-recuento__cuenta input {
  background: var(--warn-bg);
  border-color: var(--warn);
}

@media (max-width: 575.98px) {
  /* A ancho de teléfono, el campo baja y ocupa lo que le hace falta: el
     nombre del producto no puede quedarse en dos letras. */
  .fnf-recuento__que { flex: 1 1 100%; }
  .fnf-recuento__cuenta { flex: 1 1 100%; }
  .fnf-recuento__cuenta input { flex: 1 1 auto; width: auto; }
}


/* ============================================================================
   21 · AVISOS DE LA APLICACIÓN
   Van arriba del contenido, no flotando: un aviso que se va solo a los tres
   segundos no sirve cuando dice "de KUSABI salieron 30 y llegaron 25".
   ========================================================================= */
.fnf-mensajes { margin: 0 0 var(--s-5); text-align: left; }
.fnf-mensajes .fnf-banner { margin-bottom: var(--s-3); }
.fnf-mensajes .fnf-banner > div { flex: 1 1 auto; }
.fnf-mensajes__x {
  background: none;
  border: 0;
  font-size: 20px;
  line-height: 1;
  color: var(--ink-soft);
  cursor: pointer;
  /* 44px de area de toque sin agrandar el aspecto del boton. */
  min-width: 44px;
  min-height: 44px;
  margin: -12px -8px -12px 0;
}
.fnf-mensajes__x:hover { color: var(--ink); }

/* ---- Partes por voz (voz/, BACKLOG §9quinquies) ----
   Solo tokens, ni un !important (14 §15; 22-auditoria-ux §2.11). */
.fnf-dictar-panel { margin: var(--s-3) 0; max-width: 640px; }
.fnf-dictar-tiempo { font-family: var(--font-mono); font-variant-numeric: tabular-nums; font-size: 20px; }
.fnf-dictado { border: 1px solid var(--line); border-radius: var(--r-m); padding: var(--s-3) var(--s-4); background: var(--bg-alt); }
.fnf-dictado__dicho { margin-bottom: var(--s-3); }
.fnf-dictado--parte { margin: var(--s-6) 0; }
.fnf-dictar-nivel { height: 6px; margin-top: var(--s-3); background: var(--line); border-radius: var(--r-s); overflow: hidden; max-width: 320px; }
.fnf-dictar-nivel span { display: block; height: 100%; background: var(--brand-deep); transform-origin: left; transform: scaleX(0); transition: transform 80ms linear; }

/* ============================================================================
   22-auditoria-ux (26-sep-2026), fase 0
   ========================================================================= */

/* Botón de contorno: era verde sobre blanco, 2,12:1, en 39 sitios. Pasa a
   secundaria neutra (borde --line-strong, texto --ink: 17:1). Misma
   especificidad que style.blue.css y va después, así que gana sin !important. */
.btn-outline-primary {
  color: var(--ink);
  background-color: var(--paper);
  border-color: var(--line-strong);
}
.btn-outline-primary:hover,
.btn-outline-primary:focus {
  color: var(--ink);
  background-color: var(--bg-alt);
  border-color: var(--ink-soft);
}
.btn-outline-primary:not(:disabled):not(.disabled):active,
.btn-outline-primary:not(:disabled):not(.disabled).active,
.show > .btn-outline-primary.dropdown-toggle,
.btn-outline-primary[aria-expanded="true"] {
  color: var(--ink);
  background-color: var(--bg-alt);
  border-color: var(--ink);
}

/* Cabecera: "+ Parte" y el chip de usuario a 48 px de alto (área táctil de
   14 §2; eran 40). */
.fnf-newpart,
.fnf-user__chip { min-height: 48px; }
@media (max-width: 575.98px) {
  .fnf-newpart { min-width: 48px; justify-content: center; }
}

/* ---- Confirmación de un dictado en resumen legible (22-auditoria-ux §4.2) ----
   Tema claro de alto contraste (es un flujo de campo). Estados con texto y
   borde completo, nunca con barra lateral de acento. */
.fnf-rev { max-width: 720px; margin: var(--s-4) auto calc(var(--s-8) * 3); padding: 0 var(--s-2); }
.fnf-rev__volver { display: inline-flex; align-items: center; min-height: 48px; color: var(--ink); font-weight: 600; }
.fnf-rev__titulo { font-size: 20px; font-weight: 700; margin: var(--s-2) 0 var(--s-4); }
.fnf-rev__dicho { background: var(--bg-alt); border: 1px solid var(--line); border-radius: var(--r-m); padding: var(--s-3) var(--s-4); margin-bottom: var(--s-3); }
.fnf-rev__dicho .label { margin: 0 0 6px; }
.fnf-rev__texto { margin: 0; font-size: 16px; line-height: 1.5; color: var(--ink); }
.fnf-rev__pendiente { background: var(--warn-bg); border: 1px solid var(--warn); border-radius: var(--r-m); padding: var(--s-3) var(--s-4); margin-bottom: var(--s-3); color: var(--ink); }
.fnf-rev__pendiente-t { font-weight: 600; margin: 0 0 6px; color: var(--warn); }
.fnf-rev__pendiente ul, .fnf-rev__aviso ul { margin: 0; padding-left: 20px; }
.fnf-rev__aviso { border: 1px solid var(--line-strong); border-radius: var(--r-m); padding: var(--s-3) var(--s-4); margin-bottom: var(--s-3); color: var(--ink-soft); }
.fnf-rev__aviso ul { list-style: none; padding: 0; }
.fnf-rev__form { border-top: 1px solid var(--line); }
.fnf-rev__fila { border-bottom: 1px solid var(--line); }
.fnf-rev__fila > summary {
  display: flex; flex-wrap: wrap; align-items: baseline; gap: 4px var(--s-3);
  min-height: 56px; padding: var(--s-3) 36px var(--s-3) 0; position: relative;
  cursor: pointer; list-style: none;
}
.fnf-rev__fila > summary::-webkit-details-marker { display: none; }
.fnf-rev__fila > summary::after { content: "›"; position: absolute; right: 8px; top: 14px; font-size: 22px; color: var(--ink-soft); transition: transform var(--t-fast) var(--ease); }
.fnf-rev__fila[open] > summary::after { transform: rotate(90deg); }
.fnf-rev__fila > summary .label { flex: 0 0 104px; margin: 0; }
.fnf-rev__valor { flex: 1 1 180px; font-size: 16px; color: var(--ink); font-weight: 600; }
.fnf-rev__oido { font-family: var(--font-mono); font-size: 13px; color: var(--ink-soft); }
.fnf-rev__estado { font-family: var(--font-mono); font-size: 12px; color: var(--ink-soft); border: 1px solid var(--line-strong); border-radius: 99px; padding: 1px 8px; }
.fnf-rev__estado--falta { color: var(--warn); border-color: var(--warn); background: var(--warn-bg); }
.fnf-rev__fila.is-error > summary .fnf-rev__valor { color: var(--bad); }
.fnf-rev__editor { padding: 0 0 var(--s-4); display: grid; gap: var(--s-3); }
.fnf-rev__editor label { display: grid; gap: 4px; font-size: 14px; color: var(--ink-soft); margin: 0; }
.fnf-rev__editor .form-control { min-height: 48px; font-size: 16px; }
.fnf-rev__dos { display: grid; grid-template-columns: repeat(auto-fit, minmax(140px, 1fr)); gap: var(--s-3); }
.fnf-rev__opciones { display: grid; gap: 2px; max-height: 320px; overflow-y: auto; border: 1px solid var(--line); border-radius: var(--r-s); padding: 4px; }
.fnf-rev__editor label.fnf-rev__opcion { display: flex; align-items: center; gap: var(--s-3); min-height: 48px; padding: 0 var(--s-2); border-radius: var(--r-s); color: var(--ink); font-size: 15px; }
.fnf-rev__opcion:hover { background: var(--bg-alt); }
.fnf-rev__opcion input { width: 22px; height: 22px; flex: none; }
.fnf-rev__opcion small { color: var(--ink-soft); font-family: var(--font-mono); font-size: 12px; }
.fnf-rev__linea { display: grid; gap: var(--s-2); padding: var(--s-3); border: 1px solid var(--line); border-radius: var(--r-m); }
.fnf-rev__corto { max-width: 160px; }
.fnf-rev__vacio { border-color: var(--warn); }
.fnf-rev__nota { margin: 0; font-family: var(--font-mono); font-size: 13px; color: var(--ink-soft); }
.fnf-rev__mas { justify-self: start; min-height: 48px; }
.fnf-rev__completo { margin: var(--s-4) 0; font-size: 14px; }
.fnf-rev__completo a { color: var(--ink-soft); text-decoration: underline; }
.fnf-rev__pie {
  position: fixed; left: 0; right: 0; bottom: 0; z-index: 30;
  display: flex; align-items: center; justify-content: space-between; gap: var(--s-3);
  padding: var(--s-2) var(--s-4) calc(var(--s-2) + env(safe-area-inset-bottom));
  background: var(--paper); border-top: 1px solid var(--line); box-shadow: var(--shadow);
}
.fnf-rev__guardar { flex: 1; max-width: 420px; min-height: 56px; font-size: 16px; font-weight: 600; }
.fnf-rev__descartar { color: var(--ink-soft); min-height: 48px; }
@media (min-width: 992px) {
  .fnf-rev__pie { position: sticky; bottom: 0; margin: 0 calc(var(--s-2) * -1); border-radius: var(--r-m) var(--r-m) 0 0; }
}

/* ============================================================================
   22-auditoria-ux, fase 2 · Dictar a un toque, barra inferior y cajón
   ========================================================================= */

/* --- Dictar en la cabecera: neutro (el verde es para la acción principal). */
.fnf-cab-dictar {
  display: inline-flex; align-items: center; justify-content: center; gap: 6px;
  min-height: 48px; min-width: 48px; padding: 0 14px; margin-right: var(--s-2);
  border: 1px solid var(--line-dark); border-radius: var(--r-s);
  background: transparent; color: var(--ink-on-dark); font-weight: 600; font-size: 14px; cursor: pointer;
}
.fnf-cab-dictar:hover, .fnf-cab-dictar:focus-visible { border-color: var(--brand); color: #fff; outline: none; }
@media (max-width: 767.98px) {
  /* En el móvil la cabecera deja el «+» (escribir); dictar y la foto van en la
     barra inferior. */
  .fnf-cab-papel { display: none; }
  .fnf-dictar { display: none; }                /* dictar: botón central de la barra */
}

/* --- Barra inferior (19 §3.4.1 + 22 §4.1). */
.fnf-barra { display: none; }
@media (max-width: 767.98px) {
  .fnf-barra {
    position: fixed; left: 0; right: 0; bottom: 0; z-index: 1040;
    display: grid; grid-template-columns: repeat(5, 1fr); align-items: end;
    min-height: 56px; padding: 0 4px env(safe-area-inset-bottom);
    background: var(--paper); border-top: 1px solid var(--line); box-shadow: var(--shadow);
  }
  .content-inner { padding-bottom: calc(88px + env(safe-area-inset-bottom)); }
  /* Donde hay barra de guardar propia, la de navegación sobra. */
  body:has(.fnf-form-actions) .fnf-barra,
  body:has(.fnf-rev__pie) .fnf-barra,
  body.fnf-hoja-abierta .fnf-barra { display: none; }
}
@media (max-width: 767.98px) and (orientation: landscape) and (max-height: 480px) {
  .fnf-barra { display: none; }
}
.fnf-barra__item, .fnf-barra__dictar {
  display: flex; flex-direction: column; align-items: center; justify-content: center; gap: 2px;
  min-height: 56px; padding: 6px 0; border: 0; background: none; cursor: pointer;
  color: var(--ink-soft); font-size: 11px; font-weight: 400; text-decoration: none; position: relative;
}
.fnf-barra__item i { font-size: 20px; }
.fnf-barra__item:hover, .fnf-barra__item:focus-visible { color: var(--ink); text-decoration: none; outline: none; }
.fnf-barra__item.is-activo { color: var(--ink); font-weight: 600; }
.fnf-barra__item.is-activo i { color: var(--brand-deep); }
.fnf-barra__item.is-activo::after {
  content: ""; position: absolute; bottom: 4px; left: 50%; width: 4px; height: 4px;
  margin-left: -2px; border-radius: 50%; background: var(--brand-deep);
}
.fnf-barra__dictar { color: var(--ink); font-weight: 600; }
.fnf-barra__circulo {
  display: flex; align-items: center; justify-content: center;
  width: 56px; height: 56px; margin-top: -20px; border-radius: 50%;
  background: var(--brand); color: var(--on-brand); font-size: 22px;
  box-shadow: 0 0 0 4px var(--paper), var(--shadow);
}
.fnf-barra__dictar:hover .fnf-barra__circulo { background: var(--brand-bright); }
.fnf-barra__dictar:focus-visible .fnf-barra__circulo { box-shadow: 0 0 0 4px var(--paper), var(--glow); }

/* --- Hoja de grabación (22 §4.1). Tema claro, pantalla completa. */
.fnf-hoja {
  position: fixed; inset: 0; z-index: 1070; display: flex; flex-direction: column;
  background: var(--paper); color: var(--ink);
}
.fnf-hoja[hidden] { display: none; }
body.fnf-hoja-abierta { overflow: hidden; }
.fnf-hoja__cab {
  display: flex; align-items: center; justify-content: space-between;
  min-height: 56px; padding: 0 var(--s-2) 0 var(--s-4); border-bottom: 1px solid var(--line);
}
.fnf-hoja__t { font-size: 18px; font-weight: 700; margin: 0; }
.fnf-hoja__x { width: 48px; height: 48px; border: 0; background: none; font-size: 28px; line-height: 1; color: var(--ink-soft); cursor: pointer; }
.fnf-hoja__cuerpo { flex: 1; overflow-y: auto; padding: var(--s-4); max-width: 640px; width: 100%; margin: 0 auto; display: flex; flex-direction: column; }
.fnf-hoja__empresa { display: grid; gap: 4px; font-size: 14px; color: var(--ink-soft); margin-bottom: var(--s-3); }
.fnf-hoja__empresa .form-control { min-height: 48px; font-size: 16px; }
.fnf-hoja__ayuda { font-size: 15px; color: var(--ink-soft); line-height: 1.5; }
.fnf-hoja__ayuda em { color: var(--ink); font-style: normal; }
.fnf-hoja__centro { margin-top: auto; text-align: center; padding: var(--s-4) 0; }
.fnf-hoja__nivel { height: 8px; max-width: 280px; margin: 0 auto var(--s-3); background: var(--line); border-radius: var(--r-s); overflow: hidden; }
.fnf-hoja__nivel span { display: block; height: 100%; background: var(--brand-deep); transform-origin: left; transform: scaleX(0); transition: transform 80ms linear; }
.fnf-hoja__reloj { font-family: var(--font-mono); font-size: 20px; font-variant-numeric: tabular-nums; margin: 0 0 4px; }
.fnf-hoja__estado { min-height: 24px; margin: 0; font-size: 15px; color: var(--ink); }
.fnf-hoja__pasos { list-style: none; padding: 0; margin: var(--s-3) auto 0; max-width: 320px; text-align: left; display: grid; gap: 6px; }
.fnf-hoja__pasos li { color: var(--ink-soft); padding-left: 28px; position: relative; font-size: 15px; }
.fnf-hoja__pasos li::before { content: "○"; position: absolute; left: 4px; font-family: var(--font-mono); }
.fnf-hoja__pasos li.is-actual { color: var(--ink); font-weight: 600; }
.fnf-hoja__pasos li.is-actual::before { content: "◌"; animation: fnf-gira 1s linear infinite; display: inline-block; }
.fnf-hoja__pasos li.is-hecho { color: var(--ok); }
.fnf-hoja__pasos li.is-hecho::before { content: "✓"; }
@keyframes fnf-gira { to { transform: rotate(360deg); } }
.fnf-hoja__pie { padding: var(--s-4) var(--s-4) calc(var(--s-6) + env(safe-area-inset-bottom)); text-align: center; }
.fnf-hoja__grabar {
  display: inline-flex; flex-direction: column; align-items: center; justify-content: center; gap: 4px;
  width: 96px; height: 96px; border-radius: 50%; border: 0; cursor: pointer;
  background: var(--brand); color: var(--on-brand); font-size: 13px; font-weight: 600;
  box-shadow: var(--shadow);
}
.fnf-hoja__grabar i { font-size: 30px; }
.fnf-hoja__grabar:hover { background: var(--brand-bright); }
.fnf-hoja__grabar:focus-visible { outline: none; box-shadow: var(--glow), var(--shadow); }
.fnf-hoja__grabar:disabled { background: var(--disabled-bg); color: var(--disabled-ink); cursor: default; }
/* Grabando: carbón, no rojo (el rojo es de borrar, 14 §6), y un punto que late. */
.fnf-hoja__grabar.is-grabando { background: var(--carbon); color: var(--ink-on-dark); }
.fnf-hoja__grabar.is-grabando i { color: #e05252; animation: fnf-late 1.2s ease-in-out infinite; }
@keyframes fnf-late { 50% { opacity: .35; } }
@media (prefers-reduced-motion: reduce) {
  .fnf-hoja__grabar.is-grabando i, .fnf-hoja__pasos li.is-actual::before { animation: none; }
}
.fnf-hoja__cerrar-nota { margin: var(--s-3) 0 0; font-size: 14px; color: var(--ink-soft); }
.fnf-hoja__cerrar-nota a { color: var(--ink); text-decoration: underline; }

/* --- Cajón en vez de raíl (19 §3.4.2), por debajo de 992 px. No empuja. */
.fnf-cajon__x { display: none; }
.fnf-velo { position: fixed; inset: 0; z-index: 1055; background: rgba(12, 18, 16, .55); }
.fnf-velo[hidden] { display: none; }
@media (max-width: 1199.98px) {
  nav.side-navbar,
  nav.side-navbar.shrinked {
    position: fixed; top: 0; bottom: 0; left: 0; z-index: 1060;
    width: 280px; min-width: 280px; max-width: 280px; margin-left: 0;
    overflow-y: auto; text-align: left; background: var(--paper); box-shadow: var(--shadow);
    transform: translateX(-100%); transition: transform 200ms var(--ease);
  }
  nav.side-navbar.shrinked { transform: none; }
  @media (prefers-reduced-motion: reduce) { nav.side-navbar { transition: none; } }
  .content-inner, .content-inner.active { width: 100%; }
  body.fnf-cajon-abierto { overflow: hidden; }
  nav.side-navbar .sidebar-header .title,
  nav.side-navbar.shrinked .sidebar-header .title { display: block; }
  nav.side-navbar ul li a,
  nav.side-navbar.shrinked ul li a {
    display: flex; align-items: center; gap: 12px; min-height: 52px;
    padding: 0 48px 0 20px; font-size: 15px; text-align: left; position: relative;
  }
  nav.side-navbar ul li a i,
  nav.side-navbar.shrinked ul li a i { display: inline-block; margin: 0; font-size: 18px; width: 22px; text-align: center; }
  nav.side-navbar ul li li a,
  nav.side-navbar.shrinked ul li li a { padding-left: 54px; }
  nav.side-navbar ul li a[data-toggle="collapse"]::before,
  nav.side-navbar.shrinked ul li a[data-toggle="collapse"]::before {
    position: absolute; top: 50%; right: 20px; bottom: auto; left: auto; transform: translateY(-50%);
  }
  nav.side-navbar span.heading { margin: var(--s-4) 20px var(--s-2); }
  .fnf-cajon__x {
    display: block; position: absolute; top: 8px; right: 8px; z-index: 2;
    width: 48px; height: 48px; border: 0; background: none; font-size: 28px; line-height: 1; color: var(--ink-soft); cursor: pointer;
  }
  /* La hamburguesa, a 48 × 48 (era 35 × 18). */
  nav.navbar .menu-btn { min-width: 48px; min-height: 48px; }
}
.sidebar-header .title .fnf-menu-nombre { margin: 0; font-size: 16px; }
.sidebar-header .title .fnf-menu-nombre a { color: var(--ink); font-weight: 600; }
@media (max-width: 1199.98px) {
  nav.side-navbar span.heading { display: block; padding: 0 20px; }
}
/* En Partes el alta ya está en la barra inferior: un solo verde por pantalla (19 §3.6). */
@media (max-width: 767.98px) {
  .fnf-toolbar-nuevo { display: none; }
}

/* ============================================================================
   22-auditoria-ux, fase 3 · fichas en el móvil, dictados por revisar, ficha
   ========================================================================= */

/* Marca «Dictado»: información, no alarma. */
.fnf-pill--voz { background: var(--bg-alt); color: var(--ink-soft); border: 1px solid var(--line); }

/* --- Lista de fichas genérica (dictados por revisar, /voz/). Toda la ficha
   es el enlace (.fnf-row-link estirado); separación con hairline. */
.fnf-pantalla { max-width: 900px; margin: var(--s-6) auto; padding: 0 var(--s-2); }
.fnf-pantalla__t { font-size: 22px; font-weight: 700; margin: 0 0 var(--s-3); }
.fnf-pantalla__sub { color: var(--ink-soft); font-size: 14px; }
.fnf-lista { list-style: none; margin: 0; padding: 0; border-top: 1px solid var(--line); background: var(--paper); }
.fnf-lista__item {
  position: relative; display: grid; grid-template-columns: 1fr auto; gap: 4px var(--s-3);
  min-height: 72px; padding: var(--s-3) var(--s-4); border-bottom: 1px solid var(--line);
}
.fnf-lista__item:hover { background: var(--bg-alt); }
.fnf-lista__item .fnf-row-link { grid-column: 1; }
.fnf-lista__titulo { font-size: 16px; font-weight: 600; color: var(--ink); }
.fnf-lista__estado { grid-column: 2; grid-row: 1; align-self: start; }
.fnf-lista__meta { grid-column: 1 / -1; font-family: var(--font-mono); font-size: 13px; color: var(--ink-soft); }
.fnf-lista__accion { grid-column: 1 / -1; position: relative; z-index: 2; margin: 0; }
.fnf-lista__accion .btn-link { padding: 0; min-height: 44px; color: var(--ink); text-decoration: underline; }
.fnf-porrevisar { margin: var(--s-4) 0; }
.fnf-porrevisar .label { margin: 0 0 var(--s-2); color: var(--warn); }
.fnf-porrevisar__todos { display: inline-flex; align-items: center; min-height: 48px; color: var(--ink); font-weight: 600; }

/* --- Partes en fichas por debajo de 768 px (19 §3.7 nivel 2). */
@media (max-width: 767.98px) {
  .fnf-fichas thead { display: none; }
  .fnf-fichas, .fnf-fichas tbody { display: block; width: 100%; }
  .fnf-fichas tbody tr {
    display: grid; grid-template-columns: 1fr auto;
    grid-template-areas: "titulo estado" "meta fecha" "nota nota";
    gap: 2px var(--s-3); min-height: 0; padding: 10px var(--s-4);
    border-bottom: 1px solid var(--line);
  }
  .fnf-fichas tbody td { display: block; padding: 0 !important; border: 0 !important; line-height: 1.35; height: auto !important; min-height: 0 !important; }
  .fnf-fichas tr:not(:has(td)) { display: none; }
  .fnf-fichas td.c-titulo { grid-area: titulo; font-size: 16px; }
  .fnf-fichas td.c-estado { grid-area: estado; text-align: right; display: flex; flex-direction: column; align-items: flex-end; gap: 4px; }
  .fnf-fichas td.c-meta { grid-area: meta; font-size: 14px; color: var(--ink-soft); }
  .fnf-fichas td.c-fecha { grid-area: fecha; font-size: 14px; text-align: right; white-space: nowrap; }
  /* Quién lo apuntó no cabe en la ficha: está en el parte. */
  .fnf-fichas td.c-quien { display: none; }
  .fnf-fichas td.c-nota:has(.fnf-c-notas:only-child) .fnf-c-notas:empty,
  .fnf-fichas td.c-nota.fnf-vacia { display: none; }
  .fnf-fichas td.c-estado { flex-direction: row !important; flex-wrap: wrap; justify-content: flex-end; }
  .fnf-fichas td.c-nota { grid-area: nota; font-size: 14px; color: var(--ink-soft); }
  .fnf-fichas td.c-nota .fnf-c-notas { display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical; overflow: hidden; white-space: normal; max-width: none; }
  .fnf-fichas td.fnf-c-id, .fnf-fichas td.fnf-c-act { display: none; }
  .fnf-fichas tbody tr td[colspan] { grid-column: 1 / -1; }
  /* La tarjeta que la envuelve pierde el marco: la lista usa todo el ancho (19 §3.1). */
  .card:has(> .row > .table-responsive > .fnf-fichas) { border-left: 0; border-right: 0; border-radius: 0; padding-left: 0; padding-right: 0; }
}

/* --- Ficha del parte. */
.fnf-parte__volver { display: inline-flex; align-items: center; min-height: 48px; color: var(--ink); font-weight: 600; }
.fnf-parte__acciones { flex-wrap: wrap; justify-content: flex-end; }
.fnf-parte__secundarias { display: flex; flex-wrap: wrap; gap: var(--s-2); }
.fnf-parte__mas { display: none; position: relative; }
.fnf-parte__mas > summary {
  list-style: none; display: flex; align-items: center; justify-content: center;
  width: 48px; height: 48px; border: 1px solid var(--line-strong); border-radius: var(--r-s);
  font-size: 22px; cursor: pointer; background: var(--paper); color: var(--ink);
}
.fnf-parte__mas > summary::-webkit-details-marker { display: none; }
.fnf-parte__menu {
  position: absolute; left: 0; bottom: 56px; min-width: 240px; padding: 6px;
  background: var(--paper); border: 1px solid var(--line); border-radius: var(--r-m); box-shadow: var(--shadow);
}
.fnf-parte__menu a, .fnf-parte__menu button {
  display: flex; align-items: center; width: 100%; min-height: 48px; padding: 0 var(--s-3);
  border: 0; background: none; color: var(--ink); text-align: left; font-size: 15px; border-radius: var(--r-s);
}
.fnf-parte__menu a:hover, .fnf-parte__menu button:hover { background: var(--bg-alt); text-decoration: none; }
@media (max-width: 767.98px) {
  .fnf-parte__acciones {
    position: fixed; left: 0; right: 0; bottom: 0; z-index: 1040; margin: 0;
    padding: var(--s-2) var(--s-4) calc(var(--s-2) + env(safe-area-inset-bottom));
    background: var(--paper); border-top: 1px solid var(--line); box-shadow: var(--shadow);
    flex-wrap: nowrap;
  }
  .fnf-parte__secundarias { display: none; }
  .fnf-parte__mas { display: block; }
  .fnf-parte__editar { flex: 1; min-height: 48px; display: flex; align-items: center; justify-content: center; }
  body:has(.fnf-parte__acciones) .fnf-barra { display: none; }
  .fnf-parte { padding-bottom: 96px; }
}
/* Tablas del documento en pares etiqueta/valor (19 §4.3). */
@media (max-width: 575.98px) {
  .fnf-tabla-doc thead { display: none; }
  .fnf-tabla-doc, .fnf-tabla-doc tbody, .fnf-tabla-doc tr, .fnf-tabla-doc td { display: block; width: 100%; }
  .fnf-tabla-doc tr { padding: var(--s-2) 0; border-bottom: 1px solid var(--line); }
  .fnf-tabla-doc td { display: flex; justify-content: space-between; gap: var(--s-3); padding: 4px 0; border: 0; text-align: right; }
  .fnf-tabla-doc td[data-etiqueta]::before {
    content: attr(data-etiqueta); font-family: var(--font-mono); font-size: 11px;
    text-transform: uppercase; letter-spacing: .06em; color: var(--ink-soft); text-align: left; flex: none; max-width: 45%;
  }
  .fnf-tabla-doc td:first-child { font-size: 16px; }
}
@media print { .fnf-parte__volver, .fnf-parte__acciones { display: none; } }

/* ---- 22-auditoria-ux, fase 4 · alta rápida: chips de lo más usado ---- */
.fnf-rev__empresa { margin-bottom: var(--s-3); }
.fnf-rev__empresa label { display: grid; gap: 4px; font-size: 14px; color: var(--ink-soft); }
.fnf-rev__empresa .form-control { min-height: 48px; font-size: 16px; }
.fnf-rev__atajos { display: flex; flex-wrap: wrap; gap: var(--s-2); margin-bottom: var(--s-4); }
.fnf-rev__atajos .btn { min-height: 48px; display: inline-flex; align-items: center; gap: 6px; }
.fnf-rev__chips { display: flex; flex-wrap: wrap; gap: var(--s-2); }
.fnf-chip { position: relative; margin: 0; cursor: pointer; }
.fnf-chip input { position: absolute; opacity: 0; width: 1px; height: 1px; }
.fnf-chip span {
  display: inline-flex; align-items: center; gap: 6px; min-height: 48px; padding: 0 var(--s-4);
  border: 1px solid var(--line-strong); border-radius: 99px; background: var(--paper);
  color: var(--ink); font-size: 15px;
}
/* Elegido: marca ✓, peso y borde oscuro. Nunca solo color. */
.fnf-chip input:checked + span { border-color: var(--ink); background: var(--bg-alt); font-weight: 600; }
.fnf-chip input:checked + span::before { content: "✓"; font-family: var(--font-mono); color: var(--brand-deep); }
.fnf-chip input:focus-visible + span { box-shadow: var(--glow); }
.fnf-rev__mas-lista > summary { display: inline-flex; align-items: center; min-height: 44px; cursor: pointer; color: var(--ink); font-weight: 600; font-size: 14px; }
.fnf-rev__mas-lista[open] > summary { margin-bottom: var(--s-2); }

/* ---- Edición del parte: secciones apiladas en vez de pestañas (22 §5.4) ---- */
.fnf-edicion__seccion { padding: var(--s-4) 0; border-bottom: 1px solid var(--line); }
.fnf-edicion__seccion:last-child { border-bottom: 0; }
.fnf-edicion__t { font-size: 16px; font-weight: 600; margin: 0 0 var(--s-3); }
.fnf-rev__editor label.fnf-chip { display: inline-flex; padding: 0; border: 0; background: none; gap: 0; }


/* ---- Bandeja de dictados en escritorio (22 §5.1) ---- */
.fnf-bandeja__panel { display: none; }
@media (min-width: 992px) {
  .fnf-pantalla:has(.fnf-bandeja--con-panel) { max-width: 1280px; }
  .fnf-bandeja--con-panel { display: grid; grid-template-columns: 360px 1fr; gap: var(--s-6); align-items: start; }
  .fnf-bandeja--con-panel .fnf-bandeja__panel { display: block; border: 1px solid var(--line); border-radius: var(--r-m); background: var(--paper); padding: var(--s-2) var(--s-4) 0; }
  .fnf-bandeja--con-panel .fnf-bandeja__panel .fnf-rev { margin: 0; max-width: none; }
  .fnf-bandeja--con-panel .fnf-bandeja__lista { position: sticky; top: var(--s-4); max-height: calc(100vh - 120px); overflow-y: auto; }
  .fnf-lista__item.is-elegido { background: var(--bg-alt); }
  .fnf-lista__item.is-elegido .fnf-lista__titulo { text-decoration: underline; text-underline-offset: 4px; }
}
.fnf-bandeja__atajos { font-family: var(--font-mono); font-size: 12px; color: var(--ink-soft); margin: var(--s-3) 0; }

/* ---- Buscador libre de los listados (14 §8; 22 §5.3) ---- */
.fnf-buscador { display: flex; gap: var(--s-2); max-width: 640px; margin: var(--s-4) auto var(--s-2); padding: 0 var(--s-2); }
.fnf-buscador__campo { flex: 1; min-height: 48px; font-size: 16px; }
.fnf-buscador__boton { min-width: 48px; min-height: 48px; }
.fnf-buscador__res { max-width: 640px; margin: 0 auto var(--s-3); padding: 0 var(--s-2); font-size: 14px; color: var(--ink-soft); }
.fnf-buscador__res a { color: var(--ink); text-decoration: underline; }

/* ============================================================================
   Cajón en el móvil, ahora que la barra inferior navega (26-sep-2026)
   ========================================================================= */
.fnf-cajon__rapidos, .fnf-cajon__pie { display: none; }

@media (max-width: 1199.98px) {
  /* El pie con quién eres, la empresa y salir; arriba ya no hace falta la cabecera. */
  nav.side-navbar .sidebar-header,
  nav.side-navbar.shrinked .sidebar-header { display: none; }
  nav.side-navbar { display: flex; flex-direction: column; padding-top: 56px; }
  .fnf-cajon__pie { display: block; margin-top: auto; padding: var(--s-4) 20px calc(var(--s-4) + env(safe-area-inset-bottom)); border-top: 1px solid var(--line); }
  .fnf-cajon__quien { margin: 0; font-weight: 600; color: var(--ink); }
  .fnf-cajon__empresas { margin: 2px 0 var(--s-2); font-family: var(--font-mono); font-size: 13px; color: var(--brand-deep); }
  .fnf-cajon__enlace {
    display: flex; align-items: center; gap: 12px; width: 100%; min-height: 48px; padding: 0;
    border: 0; background: none; color: var(--ink); font-size: 15px; text-align: left; text-decoration: none; cursor: pointer;
  }
  .fnf-cajon__enlace i { width: 22px; text-align: center; font-size: 18px; }
  .fnf-cajon__enlace:hover { color: var(--ink); text-decoration: underline; }
  /* «Cuenta» ya está en el pie, y los encabezados no dicen nada que no se vea. */
  nav.side-navbar span.heading, nav.side-navbar ul.fnf-grupo-cuenta { display: none; }
  /* Activo sin relleno verde: el verde de la pantalla es el botón de Dictar. */
  nav.side-navbar ul li.active > a,
  nav.side-navbar ul li li.active > a,
  nav.side-navbar.shrinked ul li.active > a,
  nav.side-navbar.shrinked ul li.active > a i {
    background-color: var(--bg-alt); color: var(--ink); font-weight: 600;
  }
  nav.side-navbar ul li.active > a i { color: var(--brand-deep); }
}

@media (max-width: 767.98px) {
  /* Inicio y Partes están en la barra; Mapa y Palés suben a los accesos rápidos. */
  nav.side-navbar #start_li, nav.side-navbar #activity_li,
  nav.side-navbar #sig_li, nav.side-navbar #pallets_li { display: none; }
  .fnf-cajon__rapidos { display: block; border-bottom: 1px solid var(--line); margin-bottom: var(--s-2); }
  /* Donde está la barra, el cajón se abre con su «Menú» y la hamburguesa sobra.
     Donde la barra se esconde (pantallas con su propia barra de guardar), la
     hamburguesa se queda: si no, no habría forma de abrir el menú. */
  body:not(:has(.fnf-form-actions)):not(:has(.fnf-rev__pie)):not(:has(.fnf-parte__acciones)) nav.navbar #toggle-btn { display: none; }
}


/* ============================================================================
   Menú lateral minimizado en escritorio (≥ 1200 px): raíl de iconos (26-sep-2026)
   El tema lo dejaba en 90 px con las reglas del menú completo (icono y texto en
   línea), que ahí no caben: etiquetas partidas o cortadas, flechas colgando,
   foto ovalada y el activo como bloque verde. Icono arriba, etiqueta corta
   debajo; las secciones con submenú abren el menú completo (cajon.js).
   ========================================================================= */
nav.side-navbar .avatar img { width: 48px; height: 48px; object-fit: cover; border-radius: 50%; }
@media (min-width: 1200px) {
  nav.side-navbar.shrinked { min-width: 90px; max-width: 90px; text-align: center; }
  nav.side-navbar.shrinked .sidebar-header { justify-content: center; padding: var(--s-4) 0; }
  nav.side-navbar.shrinked .sidebar-header .title,
  nav.side-navbar.shrinked span.heading { display: none; }
  nav.side-navbar.shrinked .avatar img { width: 40px; height: 40px; }
  nav.side-navbar.shrinked ul li a {
    flex-direction: column; justify-content: center; gap: 4px;
    min-height: 64px; padding: 10px 4px; font-size: 11px; line-height: 1.2;
    text-align: center; overflow-wrap: anywhere;
  }
  nav.side-navbar.shrinked ul li a i { margin: 0; font-size: 20px; width: auto; }
  nav.side-navbar.shrinked ul li a[data-toggle="collapse"]::before { display: none; }
  nav.side-navbar.shrinked ul li ul { display: none; }
  nav.side-navbar.shrinked ul li.active > a,
  nav.side-navbar.shrinked ul li.activa > a {
    background-color: var(--bg-alt); color: var(--ink); font-weight: 600;
  }
  nav.side-navbar.shrinked ul li.active > a i,
  nav.side-navbar.shrinked ul li.activa > a i { color: var(--brand-deep); }
}
/* Sin .d-flex en el marcado: su !important impedía esconderla en el cajón. */
nav.side-navbar .sidebar-header { display: flex; align-items: center; }
nav.side-navbar a.fnf-cajon__enlace { padding: 0; }
@media (max-width: 1199.98px) {
  nav.side-navbar .sidebar-header, nav.side-navbar.shrinked .sidebar-header { display: none; }
}
nav.side-navbar .fnf-cajon__enlace i { margin: 0; }


/* =========================================================================
   Mapa (sig:mapa) con panel de capas propio (§4octies). El mapa ocupa todo
   el hueco bajo la cabecera; el panel flota encima en escritorio y es una
   hoja inferior en el móvil. Tema claro, como el resto de flujos de campo.
   ========================================================================= */
body:has(.fnf-mapa) .content-inner { padding: 0 !important; }
body:has(.fnf-mapa) #container-fluid-body { padding: 0; }
body:has(.fnf-mapa) #container-fluid-body > .row { margin: 0; }
body:has(.fnf-mapa) #container-fluid-body > .row > [class*="col-"] { padding: 0; }
.fnf-mapa { position: relative; height: calc(100dvh - 56px); min-height: 420px; }
.fnf-mapa__lienzo { position: absolute; inset: 0; background: #1b2420; }
.fnf-mapa .leaflet-control-attribution { font-size: 10px; }

.fnf-capas__abrir {
  position: absolute; top: var(--s-3); left: var(--s-3); z-index: 1001;
  display: inline-flex; align-items: center; gap: var(--s-2);
  min-height: 44px; padding: 0 var(--s-4);
  background: var(--paper); color: var(--ink); font: 600 14px var(--font);
  border: 1px solid var(--line); border-radius: var(--r-m); box-shadow: var(--shadow);
}
.fnf-capas__abrir[hidden] { display: none; }
.fnf-capas__abrir:focus-visible, .fnf-capas__x:focus-visible, .fnf-capas__finca:focus-visible { outline: 0; box-shadow: var(--glow); }

.fnf-capas {
  position: absolute; top: var(--s-3); left: var(--s-3); bottom: var(--s-3); z-index: 1002;
  width: 320px; display: none; flex-direction: column;
  background: var(--paper); color: var(--ink);
  border: 1px solid var(--line); border-radius: var(--r-l); box-shadow: var(--shadow);
}
.fnf-capas.is-abierto { display: flex; }
.fnf-capas__cab {
  display: flex; align-items: center; justify-content: space-between;
  padding: var(--s-3) var(--s-3) var(--s-2) var(--s-4); border-bottom: 1px solid var(--line);
}
.fnf-capas__t { margin: 0; font: 600 16px var(--font); color: var(--ink); }
.fnf-capas__x {
  width: 40px; height: 40px; border: 0; border-radius: var(--r-s);
  background: transparent; color: var(--ink-soft); font-size: 24px; line-height: 1;
}
.fnf-capas__x:hover { background: var(--bg-alt); color: var(--ink); }
.fnf-capas__cuerpo { flex: 1; overflow-y: auto; padding: var(--s-2) var(--s-4) var(--s-4); overscroll-behavior: contain; }

.fnf-capas__grupo { margin: 0; padding: var(--s-3) 0; border: 0; border-bottom: 1px solid var(--line); min-width: 0; }
.fnf-capas__grupo:last-child { border-bottom: 0; }
.fnf-capas__grupo legend, .fnf-capas__legend, .fnf-capas__maquina summary {
  display: block; margin: 0 0 var(--s-2); padding: 0; width: 100%;
  font: 600 12px/1.4 var(--font); letter-spacing: .04em; text-transform: uppercase; color: var(--ink-soft);
}
 /* Una legend flotada se comporta como un bloque normal: sin esto el fieldset
    la mete en su borde y suma su padding debajo. */
.fnf-capas__grupo legend { float: left; }
.fnf-capas__grupo legend + * { clear: both; }
.fnf-capas__nota { margin: 0; font-size: 13px; line-height: 1.45; color: var(--ink-soft); list-style: none; }

/* Control segmentado: fondo y satélite. */
.fnf-capas__fondos { display: flex; padding: 3px; gap: 3px; background: var(--bg-alt); border-radius: var(--r-m); }
.fnf-capas__fondos label { flex: 1; margin: 0; }
.fnf-capas__fondos input { position: absolute; opacity: 0; pointer-events: none; }
.fnf-capas__fondos span {
  display: flex; align-items: center; justify-content: center; min-height: 36px; padding: 4px 6px;
  border-radius: var(--r-s); font-size: 13px; line-height: 1.2; text-align: center; color: var(--ink-soft); cursor: pointer;
}
.fnf-capas__fondos input:checked + span { background: var(--paper); color: var(--ink); font-weight: 600; box-shadow: 0 1px 3px rgba(6,20,15,.15); }
.fnf-capas__fondos input:focus-visible + span { box-shadow: var(--glow); }

/* Interruptores de capa, con su muestra de color. */
.fnf-capas__interruptor { display: flex; align-items: center; gap: var(--s-3); min-height: 44px; margin: 0; cursor: pointer; font-size: 14px; }
.fnf-capas__interruptor input { width: 18px; height: 18px; accent-color: var(--brand-deep); flex: none; }
.fnf-capas__interruptor small { display: block; font-size: 12px; color: var(--ink-soft); }
.fnf-capas__muestra { width: 18px; height: 14px; flex: none; border-radius: 3px; }
.fnf-capas__muestra--parcela { border: 2px solid #e0b000; background: rgba(255,210,63,.25); }
.fnf-capas__muestra--sigpac { border: 2px solid #e04bd9; background: transparent; }

.fnf-capas__fecha { display: block; margin: var(--s-3) 0 0; font-size: 13px; color: var(--ink-soft); }
.fnf-capas__fecha select, .fnf-capas__maquina select, .fnf-capas__maquina input { margin-top: 4px; }

/* Leyenda del NDVI: los seis tramos del evalscript (sig/cdse.py). */
.fnf-capas__leyenda { margin-top: var(--s-3); }
.fnf-capas__escala { display: flex; gap: 2px; height: 10px; }
.fnf-capas__escala span { flex: 1; border-radius: 2px; }
.fnf-capas__escala span:nth-child(1) { background: #a65929; }
.fnf-capas__escala span:nth-child(2) { background: #d9b333; }
.fnf-capas__escala span:nth-child(3) { background: #b3d940; }
.fnf-capas__escala span:nth-child(4) { background: #4dbf33; }
.fnf-capas__escala span:nth-child(5) { background: #1a8c26; }
.fnf-capas__escala span:nth-child(6) { background: #054d1a; }
.fnf-capas__escala-t { display: flex; justify-content: space-between; margin-top: 4px; font-size: 12px; color: var(--ink-soft); }
.fnf-capas__leyenda p { margin: 4px 0 0; font-size: 12px; color: var(--ink-soft); }

/* Fincas. */
.fnf-capas__fincas { margin: 0 calc(-1 * var(--s-2)); padding: 0; list-style: none; }
.fnf-capas__finca {
  display: block; width: 100%; min-height: 44px; padding: var(--s-2); text-align: left;
  background: transparent; border: 0; border-radius: var(--r-s); color: var(--ink);
}
.fnf-capas__finca:hover { background: var(--bg-alt); }
.fnf-capas__finca-n { display: block; font-size: 14px; font-weight: 600; }
.fnf-capas__finca-m { display: block; font-size: 12px; color: var(--ink-soft); }
.fnf-capas__fincas .fnf-capas__nota { padding: 0 var(--s-2); }

/* Recorrido de máquina. */
.fnf-capas__maquina summary { cursor: pointer; margin: 0; min-height: 32px; display: flex; align-items: center; }
.fnf-capas__maquina summary::after { content: "▾"; margin-left: auto; font-size: 14px; }
.fnf-capas__maquina[open] summary::after { content: "▴"; }
.fnf-capas__maquina summary::-webkit-details-marker { display: none; }
.fnf-capas__maquina label { display: block; margin: var(--s-2) 0 0; font-size: 13px; color: var(--ink-soft); }
.fnf-capas__maquina .btn { margin-top: var(--s-3); }
.fnf-capas__maquina .fnf-capas__nota, .fnf-capas__maquina form { margin-top: var(--s-2); }

/* Fichas (popups) de parcela y de recinto SIGPAC. */
.fnf-ficha-popup .leaflet-popup-content-wrapper { border-radius: var(--r-m); }
.fnf-ficha-popup .leaflet-popup-content { margin: 12px 16px; max-height: 60vh; overflow-y: auto; }
.fnf-ficha { font: 13px/1.4 var(--font); color: var(--ink); }
.fnf-ficha__t { margin: 0 0 6px; font-weight: 600; font-size: 14px; }
.fnf-ficha table { border-collapse: collapse; width: 100%; }
.fnf-ficha th { padding: 3px 12px 3px 0; color: var(--ink-soft); font-weight: 500; white-space: nowrap; vertical-align: top; text-align: left; }
.fnf-ficha td { padding: 3px 0; vertical-align: top; }

@media (max-width: 767.98px) {
  .fnf-mapa { height: calc(100dvh - 56px - 56px - env(safe-area-inset-bottom)); }
  .fnf-capas {
    position: fixed; top: auto; left: 0; right: 0; bottom: 0; z-index: 1050;
    width: auto; max-height: 72dvh;
    border-radius: var(--r-l) var(--r-l) 0 0; border-bottom: 0;
    padding-bottom: env(safe-area-inset-bottom);
  }
  .fnf-capas__cab::before {
    content: ""; position: absolute; top: 6px; left: 50%; width: 36px; height: 4px;
    margin-left: -18px; border-radius: 2px; background: var(--line-strong);
  }
  .fnf-capas__cab { position: relative; padding-top: var(--s-4); }
}

/* --- Foto de un parte en papel (§9ter): la misma hoja que el dictado, sin
   lo que es de grabar. */
.fnf-hoja__papel { margin: var(--s-2) 0 0; font-size: 15px; color: var(--ink-soft); }
.fnf-hoja__papel .btn-link { padding: 0 0 0 4px; min-height: 44px; font-weight: 600; color: var(--brand-deep); }
.fnf-hoja.is-foto .fnf-hoja__ayuda,
.fnf-hoja.is-foto .fnf-hoja__papel,
.fnf-hoja.is-foto .fnf-hoja__empresa,
.fnf-hoja.is-foto .fnf-hoja__nivel,
.fnf-hoja.is-foto .fnf-hoja__grabar { display: none; }

/* La foto al lado de lo leído, en la revisión. */
.fnf-rev__foto { display: flex; gap: var(--s-3); align-items: flex-start; }
.fnf-rev__foto a { flex: none; }
.fnf-rev__foto img {
  display: block; width: 96px; height: 128px; object-fit: cover;
  border: 1px solid var(--line); border-radius: var(--r-s); background: var(--paper);
}
.fnf-rev__foto .fnf-rev__texto { font-family: var(--font-mono); font-size: 14px; }
@media (min-width: 1200px) {
  .fnf-rev__foto img { width: 140px; height: 186px; }
}

/* Bandeja: validar en bloque y subir papel (§9ter v1b). */
.fnf-bandeja__barra { display: flex; flex-wrap: wrap; align-items: center; gap: var(--s-2) var(--s-3); margin-bottom: var(--s-4); }
.fnf-bandeja__bloque { display: flex; flex-wrap: wrap; align-items: center; gap: var(--s-2) var(--s-3); margin: 0; flex: 1 1 420px; }
.fnf-bandeja__barra .btn { min-height: 44px; display: inline-flex; align-items: center; gap: 8px; font-weight: 600; }
.fnf-bandeja__bloque .fnf-lista__meta { flex: 1 1 220px; }
@media (max-width: 575.98px) { .fnf-bandeja__barra .btn { width: 100%; justify-content: center; } }

/* ============================================================================
   Eliminar con conocimiento de causa (agridashboard/borrado.py)
   La zona al pie de la ficha se despliega ahí mismo; la página de respaldo usa
   el mismo panel. Sin borde lateral de acento: el rojo va en el botón.
   ========================================================================= */
.fnf-borrar { margin-top: var(--s-8); padding-top: var(--s-5); border-top: 1px solid var(--line); }
.fnf-borrar__abrir {
  display: inline-flex; align-items: center; min-height: 44px; cursor: pointer; list-style: none;
  color: var(--bad); font-weight: 600;
}
.fnf-borrar__abrir::-webkit-details-marker { display: none; }
.fnf-borrar__abrir:hover { text-decoration: underline; }
.fnf-borrar__abrir:focus-visible { outline: 0; box-shadow: var(--glow); border-radius: var(--r-s); }
.fnf-borrar[open] .fnf-borrar__abrir { color: var(--ink-soft); }
.fnf-borrar__panel {
  margin-top: var(--s-3); padding: var(--s-4); max-width: 640px;
  background: var(--paper); border: 1px solid var(--line); border-radius: var(--r-m);
}
.fnf-borrar__panel p { margin: 0 0 var(--s-2); line-height: 1.5; }
.fnf-borrar__que { font-weight: 600; color: var(--ink); }
.fnf-borrar__t { color: var(--ink-soft); }
.fnf-borrar__lista { margin: 0 0 var(--s-2); padding-left: 1.2em; }
.fnf-borrar__lista li { margin-bottom: 4px; }
.fnf-borrar__aviso { color: var(--ink-soft); font-size: 14px; }
.fnf-borrar__acciones { display: flex; flex-wrap: wrap; align-items: center; gap: var(--s-2) var(--s-3); margin-top: var(--s-4); }
.fnf-borrar__acciones .btn { min-height: 44px; display: inline-flex; align-items: center; justify-content: center; font-weight: 600; }
.fnf-borrar__cancelar { color: var(--ink-soft); font-weight: 400 !important; }
.fnf-pantalla--estrecha { max-width: 680px; }
.fnf-borrar__panel--pagina { margin-top: 0; }
@media (max-width: 575.98px) {
  .fnf-borrar__acciones .btn:not(.fnf-borrar__cancelar) { width: 100%; }
  .fnf-borrar__acciones { flex-direction: column; align-items: stretch; }
}

/* ============================================================================
   Plantilla común de formulario (agridashboard/formularios.py; 23 §5.2)
   ========================================================================= */
.fnf-formulario { max-width: 880px; }
.fnf-formulario__seccion { margin: 0 0 var(--s-5); padding: 0 0 var(--s-4); border-bottom: 1px solid var(--line); }
.fnf-formulario__seccion:last-of-type { border-bottom: 0; }
.fnf-formulario__seccion-t { font-size: 16px; font-weight: 600; margin: 0 0 var(--s-3); color: var(--ink); }
.fnf-formulario__seccion--plegable > summary { cursor: pointer; list-style: none; display: flex; align-items: center; gap: 6px; min-height: 44px; margin: 0; }
.fnf-formulario__seccion--plegable > summary::-webkit-details-marker { display: none; }
.fnf-formulario__seccion--plegable > summary::after { content: "▾"; margin-left: auto; color: var(--ink-soft); }
.fnf-formulario__seccion--plegable[open] > summary::after { content: "▴"; }
.fnf-formulario__seccion--plegable[open] > summary { margin-bottom: var(--s-3); }
.fnf-formulario__seccion-ayuda { margin: calc(-1 * var(--s-2)) 0 var(--s-3); color: var(--ink-soft); font-size: 14px; }
.fnf-formulario__rejilla { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: var(--s-4) var(--s-5); }
@media (max-width: 767.98px) { .fnf-formulario__rejilla { grid-template-columns: 1fr; } }
.fnf-campo { min-width: 0; }
.fnf-campo--completo { grid-column: 1 / -1; }
.fnf-campo > label { display: block; margin: 0 0 6px; font-weight: 600; font-size: 14px; color: var(--ink); }
.fnf-campo__opcional { font-weight: 400; color: var(--ink-soft); }
.fnf-campo .form-control, .fnf-campo .bootstrap-select > .dropdown-toggle { min-height: 44px; font-size: 16px; }
.fnf-campo .custom-switch { min-height: 44px; display: flex; align-items: center; }
.fnf-campo__ayuda { display: block; margin-top: 6px; color: var(--ink-soft); font-size: 13px; line-height: 1.4; }
.fnf-campo__error { margin: 6px 0 0; color: var(--bad); font-size: 14px; font-weight: 600; }
.fnf-campo--error .form-control, .fnf-campo--error .bootstrap-select > .dropdown-toggle { border-color: var(--bad); }
.fnf-formulario__errores {
  margin: 0 0 var(--s-5); padding: var(--s-3) var(--s-4);
  background: var(--bad-bg); border: 1px solid var(--bad); border-radius: var(--r-m); color: var(--ink);
}
.fnf-formulario__errores:focus { outline: 0; box-shadow: var(--glow); }
.fnf-formulario__errores-t { margin: 0 0 6px; font-weight: 600; }
.fnf-formulario__errores ul { margin: 0; padding-left: 1.2em; }
.fnf-formulario__errores a { color: var(--ink); text-decoration: underline; font-weight: 600; }

/* Subformularios (23 §4.4): tarjeta por línea, «Quitar» en la cabecera,
   «+ Añadir …» al pie. */
.fnf-sub__lineas { display: grid; gap: var(--s-3); }
.fnf-sub__linea { padding: var(--s-3) var(--s-4) var(--s-4); background: var(--paper); border: 1px solid var(--line); border-radius: var(--r-m); }
.fnf-sub__linea--error { border-color: var(--bad); }
.fnf-sub__linea.is-quitada { background: var(--bg-alt); border-style: dashed; padding-bottom: var(--s-3); }
.fnf-sub__cab { display: flex; align-items: center; justify-content: space-between; margin-bottom: var(--s-2); min-height: 44px; }
.fnf-sub__t { font-weight: 600; color: var(--ink); }
.fnf-sub__quitar { display: inline-flex; align-items: center; gap: 6px; min-height: 44px; padding: 0 var(--s-2); margin: 0; color: var(--ink-soft); cursor: pointer; border-radius: var(--r-s); font-size: 14px; }
.fnf-sub__quitar:hover { color: var(--bad); background: var(--bad-bg); }
.fnf-sub__quitar input { position: absolute; opacity: 0; pointer-events: none; }
.fnf-sub__quitar:focus-within { box-shadow: var(--glow); }
.fnf-sub__quitada { margin: 0; color: var(--ink-soft); }
.fnf-sub__quitada .btn-link { padding: 0 4px; min-height: 44px; }
.fnf-sub__anadir { display: inline-flex; align-items: center; gap: 8px; min-height: 44px; margin-top: var(--s-3); padding: 0; font-weight: 600; color: var(--brand-deep); }
@media (max-width: 767.98px) { .fnf-sub__anadir { width: 100%; justify-content: center; border: 1px dashed var(--line-strong); border-radius: var(--r-m); } }
/* El error ya lo dicen el borde y el texto: sin el aspa de Bootstrap, que en
   los desplegables tapaba la flecha. */
.fnf-campo .form-control.is-invalid { background-image: none; padding-right: .75rem; }

/* ============================================================================
   Listados: cabecera común, filtros, orden y fichas en el móvil (23 §3)
   ========================================================================= */
.fnf-listado__cab { display: flex; flex-wrap: wrap; align-items: flex-end; justify-content: space-between; gap: var(--s-3);
  max-width: 1100px; margin: var(--s-2) auto var(--s-4); padding: 0 15px; }
.fnf-listado__cab .fnf-pantalla__t { margin: 0; }
.fnf-listado__n { margin: 4px 0 0; color: var(--ink-soft); font-size: 14px; }
.fnf-listado__n a { color: var(--ink-soft); text-decoration: underline; }
.fnf-listado__nuevo { min-height: 44px; display: inline-flex; align-items: center; gap: 8px; font-weight: 600; }
.fnf-filtros__n { font-weight: 600; }
.fnf-filtros__quitar { color: var(--ink-soft); min-height: 44px; }
.fnf-orden { color: inherit; text-decoration: none; white-space: nowrap; }
.fnf-orden:hover, .fnf-orden.is-activo { color: var(--ink); text-decoration: none; }
.fnf-orden span { color: var(--ink-soft); font-size: 10px; }
@media (max-width: 767.98px) {
  .fnf-listado__cab { padding: 0; margin-top: 0; }
  .fnf-listado__nuevo { width: 100%; justify-content: center; }
  .table-responsive:has(.fnf-tabla-fichas) { overflow: visible; }
  .fnf-tabla-fichas, .fnf-tabla-fichas tbody { display: block; width: 100%; }
  .fnf-tabla-fichas thead { display: none; }
  .fnf-tabla-fichas tr { display: flex; flex-wrap: wrap; align-items: baseline; gap: 2px 14px; position: relative;
    padding: var(--s-3) 0; border-bottom: 1px solid var(--line); }
  .fnf-tabla-fichas td { display: block; padding: 0 !important; border: 0 !important; font-size: 14px; color: var(--ink-soft); }
  .fnf-tabla-fichas td:first-child { flex: 1 1 100%; font-size: 16px; font-weight: 600; color: var(--ink); padding-right: 110px !important; }
  .fnf-tabla-fichas td:not(:first-child):not(.fnf-tabla-fichas__dato)::before { content: attr(data-etiqueta) " "; font-size: 12px; color: var(--ink-soft); opacity: .8; }
  .fnf-tabla-fichas td.fnf-tabla-fichas__dato { position: absolute; top: var(--s-3); right: 0; font-weight: 600; color: var(--ink); font-size: 15px; }
  .fnf-tabla-fichas td.fnf-c-act, .fnf-tabla-fichas td:empty { display: none; }
}
@media (max-width: 767.98px) {
  .fnf-tabla-fichas tr:not(:has(td)) { display: none; }
  .fnf-tabla-fichas td { line-height: 1.35; height: auto !important; min-height: 0 !important; }
  .fnf-tabla-fichas td.fnf-tabla-fichas__vacio { display: none; }
  .fnf-tabla-fichas tr { padding: 12px 0; }
  .card:has(> .table-responsive > .fnf-tabla-fichas), .card:has(.fnf-tabla-fichas) { padding-top: 0; padding-bottom: 0; }
}
/* Parte clásico: «Quitar» como en los subformularios comunes. */
.fnf-quitar-linea { float: right; background: transparent; border: 0; }
.fnf-linea-quitada { padding: var(--s-2) 0; }

/* Cajas de un registro de palés (23 §4.5). */
.fnf-cajas__entrada { display: flex; gap: var(--s-2); max-width: 480px; }
.fnf-cajas__entrada .form-control { min-height: 48px; font-size: 18px; font-family: var(--font-mono); }
.fnf-cajas__entrada .btn { min-height: 48px; }
.fnf-cajas__aviso { min-height: 1.4em; margin: 6px 0 var(--s-2); color: var(--ink-soft); font-size: 14px; }
.fnf-cajas__lista { display: grid; grid-template-columns: repeat(auto-fill, minmax(150px, 1fr)); gap: 6px var(--s-3); margin: 0; padding-left: 2.2em; font-family: var(--font-mono); }
.fnf-cajas__lista li { padding-left: 4px; }
.fnf-cajas__lista li span { display: inline-block; min-width: 9ch; }
.fnf-cajas__quitar { border: 0; background: none; color: var(--ink-soft); min-width: 36px; min-height: 36px; font-size: 18px; line-height: 1; }
.fnf-cajas__quitar:hover { color: var(--bad); }

/* Control segmentado de tres posiciones (Sí · No · Sin declarar). */
.fnf-tres { border: 0; margin: 0; }
.fnf-tres__t { font-size: 14px; font-weight: 600; margin: 0 0 6px; width: auto; }
.fnf-segmentado { display: flex; padding: 3px; gap: 3px; background: var(--bg-alt); border-radius: var(--r-m); }
.fnf-segmentado label { flex: 1; margin: 0; }
.fnf-segmentado input { position: absolute; opacity: 0; pointer-events: none; }
.fnf-segmentado span { display: flex; align-items: center; justify-content: center; min-height: 40px; padding: 4px 6px;
  border-radius: var(--r-s); font-size: 14px; text-align: center; color: var(--ink-soft); cursor: pointer; }
.fnf-segmentado input:checked + span { background: var(--paper); color: var(--ink); font-weight: 600; box-shadow: 0 1px 3px rgba(6,20,15,.15); }
.fnf-segmentado input:focus-visible + span { box-shadow: var(--glow); }
@media (max-width: 767.98px) {
  /* En fichas nada se sale: las celdas parten línea y la tabla no impone ancho. */
  .fnf-tabla-fichas { min-width: 0 !important; table-layout: auto; }
  .fnf-tabla-fichas td { white-space: normal !important; max-width: 100%; overflow-wrap: anywhere; }
}

/* Desplegables nativos: con 12 px de relleno arriba y abajo en una caja de 44,
   a Poppins (que es alta) le quedaban 18 px y se cortaba la «g» de «Elige…». */
select.form-control:not([multiple]) { height: auto; min-height: 44px; padding-top: 8px; padding-bottom: 8px; line-height: 1.5; }

/* ============================================================================
   Precios (costs/tarifas.py): listado por elemento, ficha y grupo
   ========================================================================= */
.fnf-precios { max-width: 1100px; margin: 0 auto; padding: 0 15px; }
.fnf-precios__resumen { margin: 0 0 var(--s-3); padding: var(--s-2) var(--s-3); background: var(--warn-bg); border-radius: var(--r-m); color: var(--ink); }
.fnf-precios__resumen a { color: var(--ink); font-weight: 600; text-decoration: underline; }
.fnf-precios__barra { display: flex; flex-wrap: wrap; align-items: center; gap: var(--s-2) var(--s-4); margin-bottom: var(--s-3); }
.fnf-precios__estados { flex: 0 1 auto; }
.fnf-precios__estados a { flex: 1; text-decoration: none; }
.fnf-precios__estados a[aria-current] span { background: var(--paper); color: var(--ink); font-weight: 600; box-shadow: 0 1px 3px rgba(6,20,15,.15); }
.fnf-precios__dia { display: flex; align-items: center; gap: var(--s-2); margin: 0; }
.fnf-precios__dia label { margin: 0; color: var(--ink-soft); font-size: 14px; white-space: nowrap; }
.fnf-precios__dia .form-control { min-height: 40px; width: auto; }
.fnf-precios__bajas { font-size: 14px; color: var(--ink-soft); text-decoration: underline; }
.fnf-precios__u { color: var(--ink-soft); font-size: 12px; }
.fnf-precios__prox { color: var(--ink-soft); font-size: 12px; }
.fnf-precios__nombre { display: flex; align-items: center; gap: var(--s-2); }
.fnf-precios__elegir { position: relative; z-index: 2; margin: 0; display: inline-flex; align-items: center; min-width: 32px; min-height: 32px; }
.fnf-precios__elegir input { width: 18px; height: 18px; accent-color: var(--brand-deep); }
.fnf-precios__grupo { position: sticky; bottom: var(--s-3); z-index: 5; display: flex; align-items: center; justify-content: space-between; gap: var(--s-3);
  margin: var(--s-3) 0; padding: var(--s-2) var(--s-3); background: var(--paper); border: 1px solid var(--line); border-radius: var(--r-m); box-shadow: var(--shadow); }
.fnf-precios__grupo[hidden] { display: none; }
.fnf-precios__ayuda { color: var(--ink-soft); font-size: 14px; margin-top: var(--s-3); }
@media (max-width: 767.98px) {
  .fnf-precios { padding: 0; }
  .fnf-precios__grupo { bottom: calc(72px + env(safe-area-inset-bottom)); }
  .fnf-precios__estados { width: 100%; }
}

.fnf-precio { max-width: 820px; }
.fnf-precio__cab { display: flex; flex-wrap: wrap; justify-content: space-between; align-items: flex-start; gap: var(--s-3); margin-bottom: var(--s-4); }
.fnf-precio__vigente { margin: 0; font-size: 32px; font-weight: 700; font-family: var(--font-mono); color: var(--ink); line-height: 1.1; }
.fnf-precio__vigente span { font-size: 16px; color: var(--ink-soft); font-weight: 400; }
.fnf-precio__desde, .fnf-precio__uso { margin: 4px 0 0; color: var(--ink-soft); font-size: 14px; }
.fnf-precio__grafica { margin: 0 0 var(--s-5); padding: var(--s-3); background: var(--paper); border: 1px solid var(--line); border-radius: var(--r-m); }
.fnf-precio__grafica svg { display: block; width: 100%; height: auto; overflow: visible; }
.fnf-precio__guia { stroke: var(--line); stroke-width: 1; }
.fnf-precio__eje { fill: var(--ink-soft); font-size: 12px; font-family: var(--font-mono); }
.fnf-precio__linea { fill: none; stroke: var(--brand-deep); stroke-width: 2; stroke-linejoin: round; }
.fnf-precio__punto { fill: var(--brand-deep); stroke: var(--paper); stroke-width: 2; }
.fnf-precio__punto:hover { r: 7; }
.fnf-precio__rotulo { fill: var(--ink); font-size: 13px; font-weight: 600; font-family: var(--font-mono); }
.fnf-precio__nuevo { margin-bottom: var(--s-5); padding-bottom: var(--s-4); border-bottom: 1px solid var(--line); }
.fnf-precio__form { display: flex; flex-wrap: wrap; align-items: flex-start; gap: var(--s-3); }
.fnf-precio__form .fnf-campo { flex: 1 1 200px; }
.fnf-precio__form .btn { min-height: 44px; margin-top: 28px; font-weight: 600; }
.fnf-precio__tabla td, .fnf-precio__tabla th { vertical-align: middle; }
@media (max-width: 575.98px) { .fnf-precio__form .btn { width: 100%; margin-top: 0; } }

.fnf-grupo__atajos { display: flex; flex-wrap: wrap; gap: 0 var(--s-2); margin: 0 0 var(--s-2); }
.fnf-grupo__atajos .btn-link { padding: 0 4px; min-height: 36px; }
.fnf-grupo__personas { list-style: none; margin: 0; padding: 0; display: grid; grid-template-columns: repeat(auto-fill, minmax(260px, 1fr)); gap: 2px var(--s-4); max-height: 420px; overflow: auto; }
.fnf-grupo__personas label { display: flex; align-items: center; gap: var(--s-2); min-height: 40px; margin: 0; cursor: pointer; }
.fnf-grupo__personas input { width: 18px; height: 18px; accent-color: var(--brand-deep); flex: none; }
.fnf-grupo__nombre { flex: 1; font-size: 14px; }
.fnf-grupo__actual { color: var(--ink-soft); font-size: 13px; font-family: var(--font-mono); }
.fnf-grupo__valores { margin-top: var(--s-3); }
.fnf-grupo__nota { color: var(--warn); }
.fnf-precio__svg--estrecha { display: none; }
.fnf-precio__fecha { color: var(--ink); text-decoration: underline; text-decoration-color: var(--line-strong); }
@media (max-width: 575.98px) {
  .fnf-precio__svg--ancha { display: none; }
  .fnf-precio__svg--estrecha { display: block; }
  .fnf-precio__grafica { padding: var(--s-2); }
  .fnf-precio__editar { display: none; }
}
.fnf-precio__empresa { margin: -6px 0 var(--s-3); color: var(--ink-soft); font-size: 15px; }
.fnf-precio__empresa a { color: var(--brand-deep); }
.fnf-grupo__empresa { display: block; color: var(--ink-soft); font-size: 12px; font-weight: 400; }
.fnf-precios__dia select.form-control { width: auto; min-width: 160px; }
@media (max-width: 767.98px) {
  .fnf-precios__dia { flex-wrap: wrap; width: 100%; }
  .fnf-precios__dia label { flex: 0 0 72px; }
  .fnf-precios__dia .form-control, .fnf-precios__dia select.form-control { flex: 1 1 180px; min-width: 0; width: auto; }
}
.fnf-precios__par { display: inline-flex; align-items: center; gap: var(--s-2); }
@media (max-width: 767.98px) {
  .fnf-precios__par { display: flex; width: 100%; }
  .fnf-precios__par label { flex: 0 0 72px; }
}
.fnf-precio__compras { margin: 0 0 var(--s-4); padding: var(--s-3) var(--s-4); background: var(--bg-alt); border-radius: var(--r-m); font-size: 14px; }
.fnf-precio__compras p { margin: 0; }
.fnf-precio__compras p + p { margin-top: 6px; }
.fnf-precio__origen { display: block; margin-top: 2px; font-family: var(--font); font-size: 12px; color: var(--ink-soft); }
.fnf-precio__origen a { color: var(--ink-soft); text-decoration: underline; }

/* Almacén en tres entradas (27-sep-2026): pestañas dentro de Existencias. */
.fnf-subnav { display: flex; flex-wrap: wrap; align-items: center; justify-content: space-between; gap: var(--s-2) var(--s-3);
  max-width: 1100px; margin: 0 auto var(--s-4); padding: 0 15px; }
.fnf-subnav__pestanas { display: flex; flex-wrap: wrap; gap: 2px; border-bottom: 1px solid var(--line); }
.fnf-subnav__pestanas a { display: inline-flex; align-items: center; min-height: 44px; padding: 0 var(--s-3); color: var(--ink-soft);
  border-bottom: 2px solid transparent; margin-bottom: -1px; text-decoration: none; font-weight: 500; }
.fnf-subnav__pestanas a:hover { color: var(--ink); }
.fnf-subnav__pestanas a[aria-current] { color: var(--ink); font-weight: 600; border-bottom-color: var(--brand-deep); }
.fnf-subnav__acciones { display: flex; gap: var(--s-2); }
.fnf-subnav__acciones .btn { min-height: 44px; display: inline-flex; align-items: center; gap: 6px; font-weight: 600; }
.fnf-listado__extra { max-width: 1100px; margin: calc(-1 * var(--s-2)) auto var(--s-3); padding: 0 15px; color: var(--ink-soft); font-size: 14px; }
.fnf-listado__extra a { color: var(--brand-deep); font-weight: 600; }
.fnf-listado__extra--arriba { margin: var(--s-2) auto 0; }
@media (max-width: 767.98px) {
  .fnf-subnav, .fnf-listado__extra { padding: 0; }
  .fnf-subnav__pestanas { width: 100%; overflow-x: auto; flex-wrap: nowrap; }
  .fnf-subnav__pestanas a { white-space: nowrap; padding: 0 var(--s-2); }
  .fnf-subnav__acciones { width: 100%; }
  .fnf-subnav__acciones .btn { flex: 1; justify-content: center; }
}

/* ============================================================================
   Recintos SIGPAC (fields/recintos.html, cultivo_parcelas, recinto_cultivos).
   Una lista de lo que falta y, para resolverlo, filas-casilla de 56 px con
   8 px de aire: se marca con el dedo en el campo. Sin tablas ni scroll lateral
   (auditoría 20-recintos-ux.md §2.4 y §2.5). Lo marcado se ve por el fondo y
   el borde entero, nunca por una barra de acento lateral.
   ========================================================================= */
.fnf-recintos__resumen { margin: 0 0 var(--s-5); }
.fnf-recintos__resumen a { color: var(--ink); font-weight: 600; text-decoration: underline; }
.fnf-recintos__grupo { margin: var(--s-6) 0 0; }
.fnf-recintos__grupo-t { display: flex; align-items: baseline; gap: var(--s-2); font-size: 13px; font-family: var(--font-mono); text-transform: uppercase; letter-spacing: .08em; color: var(--ink-soft); margin: 0 0 var(--s-2); }
.fnf-recintos__grupo-ayuda { color: var(--ink-soft); font-size: 14px; margin: -4px 0 var(--s-3); }
.fnf-recintos .fnf-lista__item { grid-template-columns: 1fr auto; }
.fnf-recintos__acciones { grid-column: 1 / -1; display: flex; flex-wrap: wrap; align-items: center; gap: var(--s-2) var(--s-4); margin-top: var(--s-2); }
.fnf-recintos__acciones form { margin: 0; }
.fnf-recintos__acciones .btn { min-height: 44px; font-weight: 600; }
.fnf-recintos__acciones .btn-link { padding: 0; color: var(--ink); text-decoration: underline; }
.fnf-recintos__sigpac { grid-column: 1 / -1; font-size: 14px; color: var(--ink); }
.fnf-recintos__finca { font-size: 15px; font-weight: 600; margin: var(--s-4) 0 var(--s-2); }
.fnf-recintos__finca small { color: var(--ink-soft); font-weight: 400; }
.fnf-recintos__cultivos { grid-column: 1 / -1; display: flex; flex-wrap: wrap; gap: 6px; }
.fnf-recintos__cultivos .fnf-chip { height: 28px; }
.fnf-recintos__todos > summary { list-style: none; cursor: pointer; display: flex; align-items: center; min-height: 48px; font-weight: 600; }
.fnf-recintos__todos > summary::-webkit-details-marker { display: none; }
.fnf-recintos__todos > summary::before { content: "▸"; margin-right: var(--s-2); color: var(--ink-soft); }
.fnf-recintos__todos[open] > summary::before { content: "▾"; }
@media (max-width: 575.98px) {
  .fnf-recintos__acciones form, .fnf-recintos__acciones form .btn { width: 100%; }
}

.fnf-opciones { list-style: none; margin: 0; padding: 0; display: grid; gap: var(--s-2); }
.fnf-opcion {
  display: grid; grid-template-columns: auto 1fr auto; align-items: center; gap: 2px var(--s-3);
  min-height: 56px; margin: 0; padding: 10px var(--s-3);
  background: var(--paper); border: 1px solid var(--line); border-radius: var(--r-m);
  font-weight: 400; cursor: pointer;
}
.fnf-opcion:hover { border-color: var(--line-strong); }
.fnf-opcion:has(input:checked) { background: var(--ok-bg); border-color: var(--ok); }
.fnf-opcion:has(input:focus-visible) { outline: 2px solid var(--brand); outline-offset: 2px; }
.fnf-opcion input { width: 22px; height: 22px; margin: 0; accent-color: var(--brand-deep); grid-row: 1 / span 2; }
.fnf-opcion__t { font-size: 16px; font-weight: 600; color: var(--ink); }
.fnf-opcion__t .data { font-family: var(--font-mono); }
.fnf-opcion__meta { grid-column: 2 / -1; font-size: 13px; color: var(--ink-soft); }
.fnf-opcion__ha { font-family: var(--font-mono); font-size: 14px; color: var(--ink); white-space: nowrap; }
.fnf-opcion .fnf-pill { vertical-align: 1px; }
.fnf-opciones__mas { margin-top: var(--s-4); }
.fnf-opciones__mas > summary { list-style: none; cursor: pointer; display: flex; align-items: center; min-height: 48px; font-weight: 600; }
.fnf-opciones__mas > summary::-webkit-details-marker { display: none; }
.fnf-opciones__mas > summary::before { content: "▸"; margin-right: var(--s-2); color: var(--ink-soft); }
.fnf-opciones__mas[open] > summary::before { content: "▾"; }
.fnf-opciones__cotejo { margin: var(--s-4) 0 0; font-size: 14px; color: var(--ink-soft); }
.fnf-opciones__cotejo b { font-family: var(--font-mono); color: var(--ink); }
.fnf-opciones__nota { margin: var(--s-3) 0 0; font-size: 13px; color: var(--ink-soft); }

/* ============================================================================
   Ficha de producto: usos autorizados del MAPA (warehouse/product_ficha.html).
   Un bloque por cultivo, plegable; cada uso en dos líneas, sin tabla, para que
   se lea en el teléfono. La fuente, siempre con su fecha.
   ========================================================================= */
.fnf-producto .fnf-pantalla__sub .fnf-pill { margin-top: var(--s-2); }
.fnf-usos__resumen { margin: 0 0 var(--s-3); color: var(--ink-soft); }
.fnf-usos .fnf-banner { margin-bottom: var(--s-3); }
.fnf-usos__buscar { max-width: 420px; margin-bottom: var(--s-4); }
.fnf-usos__cultivo { border-top: 1px solid var(--line); }
.fnf-usos__cultivo:last-of-type { border-bottom: 1px solid var(--line); }
.fnf-usos__cultivo > summary { list-style: none; cursor: pointer; display: flex; align-items: center; gap: var(--s-2); min-height: 52px; padding: var(--s-2) 0; }
.fnf-usos__cultivo > summary::-webkit-details-marker { display: none; }
.fnf-usos__cultivo > summary::before { content: "▸"; color: var(--ink-soft); width: 12px; }
.fnf-usos__cultivo[open] > summary::before { content: "▾"; }
.fnf-usos__cultivo-t { font-weight: 600; font-size: 16px; }
.fnf-usos__n { font-family: var(--font-mono); font-size: 12px; color: var(--ink-soft); }
.fnf-usos__lista { list-style: none; margin: 0 0 var(--s-3); padding: 0 0 0 20px; }
.fnf-usos__uso { padding: var(--s-2) 0; border-top: 1px dashed var(--line); }
.fnf-usos__uso:first-child { border-top: 0; }
.fnf-usos__plaga { margin: 0; font-weight: 600; }
.fnf-usos__datos { margin: 2px 0 0; font-size: 14px; color: var(--ink-soft); display: flex; flex-wrap: wrap; gap: 0 var(--s-3); }
.fnf-usos__datos b { color: var(--ink); font-family: var(--font-mono); font-weight: 600; }
.fnf-usos__cond > summary { cursor: pointer; font-size: 13px; color: var(--ink); text-decoration: underline; min-height: 32px; display: inline-flex; align-items: center; }
.fnf-usos__cond p { font-size: 13px; color: var(--ink-soft); margin: var(--s-1, 4px) 0 0; }
.fnf-usos__fuente { margin: var(--s-4) 0 0; font-size: 13px; color: var(--ink-soft); }
.fnf-usos__fuente a { color: var(--ink); }
.fnf-usos__para { font-size: 13px; color: var(--ink-soft); }
.fnf-usos__cientifico { font-weight: 400; font-size: 13px; color: var(--ink-soft); }

/* Avisos del registro del MAPA en la línea de producto de un parte
   (warehouse/usos.py): avisan, no bloquean. Sin barra lateral: el estado lo
   dicen el icono y el color del texto. */
.fnf-aviso-uso { display: block; margin-top: 6px; font-size: 13px; font-weight: 600; line-height: 1.35; }
.fnf-aviso-uso--bad { color: var(--bad); }
.fnf-aviso-uso--warn { color: var(--warn); }
.fnf-aviso-uso--info { color: var(--ink-soft); font-weight: 400; }

/* Novedades del registro del MAPA (warehouse/novedades.html). Una tarjeta por
   revisión; la que falló, con fondo de aviso, sin barra lateral. */
.fnf-novedad { background: var(--paper); border: 1px solid var(--line); border-radius: var(--r-m); padding: var(--s-4); margin: 0 0 var(--s-4); }
.fnf-novedad--fallo { border-color: var(--warn); }
.fnf-novedad__cab { display: flex; flex-wrap: wrap; align-items: baseline; justify-content: space-between; gap: var(--s-2); margin-bottom: var(--s-2); }
.fnf-novedad__t { font-size: 17px; font-weight: 700; margin: 0; }
.fnf-novedad__fecha { font-family: var(--font-mono); font-size: 13px; color: var(--ink-soft); }
.fnf-novedad__sub { font-size: 14px; font-weight: 600; margin: var(--s-3) 0 var(--s-1, 4px); }
.fnf-novedad__lista { margin: 0; padding-left: 20px; font-size: 15px; }
.fnf-novedad__lista li { margin: 4px 0; }
.fnf-novedad__nota, .fnf-novedad__nada { font-size: 13px; color: var(--ink-soft); margin: var(--s-2) 0 0; }
.fnf-novedad__mas { margin-top: var(--s-3); }
.fnf-novedad__mas > summary { cursor: pointer; min-height: 40px; display: flex; align-items: center; font-size: 14px; color: var(--ink); text-decoration: underline; }
.fnf-novedad .fnf-banner { margin: var(--s-2) 0; }

/* ============================================================================
   Inicio («Hoy»), tras la auditoría del 28-sep-2026 (fnfanalytics-relanzamiento/26).
   «Para hoy»: filas de 56 px, toda la fila es el enlace; el aviso, con fondo y
   borde completo (nunca una barra lateral). Lo que no pide nada, al pie.
   ========================================================================= */
/* La etiqueta del sistema de diseño (design-system/tokens.css): mono,
   mayúsculas, tinta suave. Se usaba en 15 plantillas y no estaba definida. */
.label { font-family: var(--font-mono); font-size: 11px; font-weight: 400; letter-spacing: .12em;
         text-transform: uppercase; color: var(--ink-soft); }
h2.label { margin: 0 0 var(--s-2); line-height: 1.4; }
/* El tema viejo da 50 px arriba y abajo a todo <section>: 124 px de hueco entre bloques. */
.fnf-hoy section { padding: 0; }
.fnf-hoy__cab { display: flex; flex-wrap: wrap; align-items: flex-end; justify-content: space-between; gap: var(--s-2) var(--s-4); }
.fnf-hoy__cab .fnf-pantalla__t { margin-bottom: 2px; }
.fnf-hoy__fecha { font-family: var(--font-mono); font-size: 13px; color: var(--ink-soft); margin: 0 0 var(--s-4); }
.fnf-hoy__empresa { margin: 0 0 var(--s-4); }
.fnf-hoy__empresa select { min-height: 44px; width: auto; max-width: 100%; }
.fnf-hoy__acciones { display: flex; flex-wrap: wrap; gap: var(--s-2); margin: 0 0 var(--s-5); }
.fnf-hoy__acciones .btn { min-height: 48px; display: inline-flex; align-items: center; gap: 8px; font-weight: 600; }
.fnf-hoy__bloque { margin: 0 0 var(--s-6); }
.fnf-hoy__texto { font-size: 15px; color: var(--ink-soft); margin: 0 0 var(--s-3); }
.fnf-parahoy { list-style: none; margin: 0; padding: 0; border-top: 1px solid var(--line); }
.fnf-parahoy li { border-bottom: 1px solid var(--line); }
.fnf-parahoy__fila { display: flex; align-items: center; gap: var(--s-3); min-height: 56px; padding: 10px var(--s-3);
                     color: var(--ink); text-decoration: none; background: var(--paper); }
.fnf-parahoy__fila:hover { background: var(--bg-alt); color: var(--ink); text-decoration: none; }
.fnf-parahoy__fila:focus-visible { outline: 2px solid var(--brand); outline-offset: -2px; }
.fnf-parahoy__fila--aviso { background: var(--warn-bg); border: 1px solid var(--warn); }
.fnf-parahoy__fila--aviso:hover { background: var(--warn-bg); }
.fnf-parahoy__fila--aviso .fnf-parahoy__ico { color: var(--warn); }
.fnf-parahoy__ico { flex: 0 0 24px; font-size: 18px; text-align: center; color: var(--ink-soft); }
.fnf-parahoy__txt { flex: 1; display: flex; flex-direction: column; }
.fnf-parahoy__txt b { font-size: 16px; font-weight: 600; }
.fnf-parahoy__txt small { font-size: 13px; color: var(--ink-soft); }
.fnf-hoy__al-dia { margin: 0; padding: var(--s-3) 0; font-size: 15px; color: var(--ok); font-weight: 600; }
.fnf-hoy__pie { list-style: none; margin: var(--s-2) 0 0; padding: 0; font-family: var(--font-mono); font-size: 13px; color: var(--ink-soft); }
.fnf-hoy__pie li { margin: 6px 0; }
.fnf-hoy__pie a { color: var(--ink-soft); text-decoration: underline; }
.fnf-hoy__pie--aviso, .fnf-hoy__pie--aviso a { color: var(--warn); font-weight: 600; }
.fnf-hoy__enlaces { display: flex; flex-wrap: wrap; justify-content: space-between; gap: 0 var(--s-4); margin: 0; }
.fnf-hoy__escribir { display: inline-flex; align-items: center; min-height: 48px; color: var(--ink); }
.fnf-hoy__cifras { list-style: none; margin: 0 0 var(--s-2); padding: 0; font-size: 15px; }
.fnf-hoy__cifras li { padding: 6px 0; border-bottom: 1px solid var(--line); }
.fnf-hoy__cifras b { font-family: var(--font-mono); }
.fnf-hoy__cifras--aviso, .fnf-hoy__cifras--aviso a { color: var(--warn); }
/* Los que no son enlace (un dictado leyéndose) no prometen un clic al pasar. */
.fnf-lista__item:not(:has(.fnf-row-link)):hover { background: none; }
@media (min-width: 992px) {
  .fnf-pantalla.fnf-hoy { max-width: 1160px; }
  .fnf-hoy__columnas { display: grid; grid-template-columns: minmax(0, 1fr) 320px; gap: var(--s-8); align-items: start; }
}
/* En el móvil Dictar y Foto están en la barra y Escribir en la hoja de Dictar:
   la fila de acciones sobra, y el «+» verde de la cabecera también (un solo verde). */
@media (max-width: 767.98px) {
  .fnf-hoy__acciones { display: none; }
  .fnf-cab-escribir { display: none; }
  .fnf-pill { font-size: 12px; }
}
/* En Inicio, en escritorio, la fila de acciones ya trae Escribir: el «+ Parte» de la cabecera sobra. */
.fnf-en-inicio .fnf-cab-escribir { display: none; }
/* «Saltar al contenido» (19 §3.4.2): solo se ve al llegar con el tabulador. */
.fnf-saltar { position: absolute; left: -9999px; top: 8px; z-index: 2000; padding: 10px 14px;
              background: var(--paper); color: var(--ink); border: 2px solid var(--brand); border-radius: var(--r-s); }
.fnf-saltar:focus { left: 8px; }
/* «Esta semana» también en el móvil, debajo: el dueño entra y revisa precios. */
.fnf-hoy__sub { margin-top: var(--s-4); }
.fnf-hoy__cifras a { color: var(--ink); }
.fnf-hoy__nota { font-size: 13px; color: var(--ink-soft); margin: 0 0 var(--s-3); }

/* ============================================================================
   Acceso: entrar, alta por invitación, recuperar (users/base.html;
   fnfanalytics-relanzamiento/28-auditoria-acceso.md). Una columna de 420 px,
   etiquetas visibles, campos de 48 px y un solo botón verde.
   ========================================================================= */
body.fnf-acceso { background: var(--bg); color: var(--ink); font-family: var(--font); min-height: 100vh;
                  display: flex; flex-direction: column; align-items: center; justify-content: center; padding: var(--s-6) var(--s-4); }
.fnf-acceso__caja { width: 100%; max-width: 420px; background: var(--paper); border: 1px solid var(--line);
                    border-radius: var(--r-l); padding: var(--s-6) var(--s-5); }
.fnf-acceso__logo { margin: 0 0 var(--s-5); }
/* El logotipo de la cabecera va sobre fondo oscuro; aquí, sobre claro, y se ve también en el móvil. */
.fnf-acceso .fnf-logo__txt { display: inline-block; }
.fnf-acceso .fnf-logo__txt b { color: var(--ink); }
.fnf-acceso .fnf-logo__txt i { color: var(--brand-deep); }   /* el verde claro no se lee sobre blanco a 9 px */
.fnf-acceso__t { font-size: 22px; font-weight: 700; margin: 0 0 var(--s-2); }
.fnf-acceso__sub { font-size: 15px; color: var(--ink-soft); margin: 0 0 var(--s-4); }
.fnf-acceso .fnf-banner { margin: 0 0 var(--s-4); }
.fnf-acceso__campo { margin: 0 0 var(--s-4); }
.fnf-acceso__etiqueta { display: flex; justify-content: space-between; align-items: baseline; gap: var(--s-2); }
.fnf-acceso__etiqueta label { font-weight: 600; font-size: 15px; margin: 0 0 6px; }
.fnf-acceso__olvido { font-size: 14px; color: var(--ink); text-decoration: underline; }
.fnf-acceso .form-control { min-height: 48px; font-size: 16px; }
.fnf-acceso .form-control[readonly] { background: var(--bg-alt); }
.fnf-acceso__clave { position: relative; }
.fnf-acceso__clave .form-control { padding-right: 88px; }
.fnf-acceso__mostrar { position: absolute; right: 4px; top: 4px; bottom: 4px; min-width: 76px; border: 0; background: none;
                       font-weight: 600; font-size: 14px; color: var(--ink); text-decoration: underline; cursor: pointer; }
.fnf-acceso__ayuda { display: block; margin-top: 6px; font-size: 13px; color: var(--ink-soft); }
.fnf-acceso__error { display: block; margin-top: 6px; font-size: 14px; color: var(--bad); font-weight: 600; }
.fnf-acceso__campo--error .form-control { border-color: var(--bad); }
.fnf-acceso__recordar { display: flex; align-items: center; gap: 10px; min-height: 44px; margin: 0 0 var(--s-4); font-weight: 400; font-size: 15px; cursor: pointer; }
.fnf-acceso__recordar input { width: 20px; height: 20px; accent-color: var(--brand-deep); flex: none; }
.fnf-acceso__recordar a { color: var(--ink); text-decoration: underline; }
.fnf-acceso__boton { width: 100%; min-height: 52px; font-size: 16px; font-weight: 600; }
.fnf-acceso__otra { margin: var(--s-5) 0 0; font-size: 14px; color: var(--ink-soft); }
.fnf-acceso__otra a { color: var(--ink); text-decoration: underline; }
.fnf-acceso__pie { margin-top: var(--s-4); font-size: 13px; color: var(--ink-soft); text-align: center; }
.fnf-acceso__pie a { color: var(--ink-soft); }
@media (max-width: 480px) {
  body.fnf-acceso { justify-content: flex-start; padding: var(--s-4) var(--s-3); }
  .fnf-acceso__caja { border: 0; padding: var(--s-3) var(--s-1, 4px); background: transparent; }
}
