/* INASOR Oficina Técnica · armazón y componentes comunes.
   Vocabulario de componentes heredado de Centralit.IA, vestido con la marca de ESshipping
   (tarea 11): cabecera en el verde corporativo con el logotipo en blanco, IBM Plex, esquinas
   casi rectas. Nada de colores sueltos: todo por variable de tokens.css, para que el tema
   oscuro funcione sin reglas aparte. Sistema completo en eshipping/DESIGN.md. */

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

/* Controles nativos (select, casillas, barras de desplazamiento) en el tema de la página:
   sin esto, en oscuro el desplegable y la barra de desplazamiento salían en claro. */
:root { color-scheme: light; }
:root[data-bs-theme="dark"] { color-scheme: dark; }

/* Alto de la cabecera pegada arriba: una fila de 60 px; dos filas (112 px) a 900 px o menos.
   El scroll-padding deja por debajo de ella todo lo que se trae a la vista (el foco al tabular,
   las anclas #…, scrollIntoView), en cualquier pantalla (WCAG 2.4.11). Se suma al
   scroll-margin de cada elemento: ese margen es solo el aire, nunca el alto de la cabecera. */
:root { --cabecera-fija: 60px; }
html { scroll-padding-top: calc(var(--cabecera-fija) + var(--c-esp-4)); }

.c-cuerpo {
  margin: 0; min-height: 100vh; background: var(--c-fondo); color: var(--c-texto);
  font-family: var(--c-fuente); font-size: var(--c-tipo-cuerpo); line-height: 1.5;
  -webkit-font-smoothing: antialiased; -moz-osx-font-smoothing: grayscale;
}
.c-cuerpo [hidden] { display: none !important; }
.c-visualmente-oculto {
  position: absolute; width: 1px; height: 1px; padding: 0; margin: -1px; overflow: hidden;
  clip-path: inset(50%); white-space: nowrap; border: 0;
}
/* El salto «Ir al contenido» aparece al llegar a él con el teclado. */
a.c-visualmente-oculto:focus-visible {
  position: fixed; top: var(--c-esp-2); left: var(--c-esp-2); z-index: 30; width: auto; height: auto; margin: 0;
  padding: var(--c-esp-2) var(--c-esp-3); clip-path: none; background: var(--c-superficie); color: var(--c-texto);
  border-radius: var(--c-radio-campo); box-shadow: var(--c-sombra-alta);
}
/* Enlaces de texto corrido (párrafos, listas, celdas, avisos). Todo el selector va en :where()
   y pesa cero: cualquier regla propia de una pantalla (pestañas, filas, filtros, migas) manda
   sobre esta, y un <a> con clase no entra nunca. Subrayados siempre: el verde contra el texto
   no llega a 3:1 y el color solo no distingue un enlace (WCAG 1.4.1). */
:where(.c-cuerpo) :where(p, li, dd, td, figcaption, .c-ayuda, .c-aviso) :where(a:not([class])) {
  color: var(--c-acento-hover); text-decoration: underline; text-decoration-thickness: 1px; text-underline-offset: 3px;
}
:where(.c-cuerpo) :where(p, li, dd, td, figcaption, .c-ayuda, .c-aviso) :where(a:not([class]):hover) { text-decoration-thickness: 2px; }
.c-cuerpo a:focus-visible, .c-cuerpo button:focus-visible, .c-cuerpo input:focus-visible,
.c-cuerpo select:focus-visible, .c-cuerpo textarea:focus-visible, .c-cuerpo summary:focus-visible {
  outline: 3px solid var(--c-acento); outline-offset: 2px;
}
.c-titulo h1, .c-ficha h2, .c-vacio h2 { text-wrap: balance; }
.c-ayuda, .c-vacio p, .c-aviso { text-wrap: pretty; }
/* Marcador de los campos: el gris por defecto del navegador se quedaba en 3,9:1 sobre la
   superficie oscura. Con --c-texto-2 pasa de 7:1 en los dos temas. */
.c-cuerpo ::placeholder { color: var(--c-texto-2); opacity: 1; }

/* Cabecera: el verde corporativo de la web, con el logotipo en blanco. Es la franja que dice
   «esto es ESshipping» en cada pantalla; el resto del panel queda neutro para los datos. */
.c-cabecera {
  display: flex; align-items: center; gap: var(--c-esp-4); padding: 0 var(--c-esp-6); height: 60px;
  background: var(--c-cabecera); color: var(--c-cabecera-texto); position: sticky; top: 0; z-index: 20;
}
/* Sobre el verde, el anillo de foco verde desaparecería: dentro de la cabecera va en blanco. */
.c-cuerpo .c-cabecera :focus-visible { outline-color: var(--c-cabecera-texto); }
.c-menu-boton {
  display: none; width: 44px; height: 44px; align-items: center; justify-content: center;
  background: transparent; border: 0; border-radius: var(--c-radio-campo); color: inherit;
  font-size: 1.25rem; cursor: pointer; flex: none;
}
.c-menu-boton:hover { background: var(--c-cabecera-2); }
.c-marca {
  display: flex; align-items: center; gap: var(--c-esp-3); color: inherit; text-decoration: none; flex: none;
  min-height: 44px; border-radius: var(--c-radio-campo);
}
/* El logotipo oficial es verde y negro (logo-claro.png, 182×44). Sobre la cabecera verde se
   usa su versión en blanco, que es la de la web: el filtro la saca del mismo fichero sin
   tocar sus proporciones. 30 px de alto → 124 px de ancho, por encima del mínimo de 120. */
.c-marca-logo { display: block; height: 30px; width: auto; filter: brightness(0) invert(1); }
.c-marca-texto { font-weight: var(--c-peso-fuerte); font-size: 1.125rem; letter-spacing: -.01em; }
.c-marca-sep { align-self: stretch; width: 1px; margin: 12px 0; background: var(--c-cabecera-texto-2); opacity: .55; }
.c-marca-sub { color: var(--c-cabecera-texto-2); font-weight: var(--c-peso-medio); font-size: .9375rem; }
.c-buscador-cabecera { flex: 1 1 320px; max-width: 420px; min-width: 0; margin-left: var(--c-esp-2); }
.c-buscador-cabecera input[type=search] {
  width: 100%; min-height: var(--campo-alto); font: inherit; font-size: var(--c-tipo-tabla); color: var(--c-cabecera-texto);
  background: var(--c-cabecera-2); border: 1px solid var(--c-cabecera-borde); border-radius: var(--c-radio-campo);
  padding: 8px 12px; text-overflow: ellipsis; white-space: nowrap; overflow: hidden;
}
.c-buscador-cabecera input[type=search]::placeholder { color: var(--c-cabecera-texto-2); opacity: 1; text-overflow: ellipsis; }
.c-simular:empty { display: none; }
.c-tema {
  width: 44px; height: 44px; display: grid; place-items: center; flex: none; background: transparent;
  border: 0; border-radius: var(--c-radio-campo); color: inherit; font-size: 1.1rem; cursor: pointer;
  margin-left: auto;
}
.c-tema:hover { background: var(--c-cabecera-2); }
/* Luna en claro (lleva al oscuro), sol en oscuro. Los dos iconos viven en el botón y se
   cruzan con escala, opacidad y desenfoque: el cambio se entiende sin que salte el icono.
   El tema se aplica antes de pintar (script del <head>), así que al cargar no hay animación. */
.c-tema-icono {
  grid-area: 1 / 1; line-height: 1;
  transition: opacity var(--c-normal) var(--c-ease-icono), transform var(--c-normal) var(--c-ease-icono), filter var(--c-normal) var(--c-ease-icono);
}
.c-tema-icono-sol, :root[data-bs-theme="dark"] .c-tema-icono-luna { opacity: 0; transform: scale(.25); filter: blur(4px); }
:root[data-bs-theme="dark"] .c-tema-icono-sol { opacity: 1; transform: none; filter: none; }
/* Pulsación de los botones de icono de la cabecera, como la del resto de botones. */
.c-menu-boton, .c-tema, .c-salir { transition: background-color var(--c-rapido) var(--c-ease), transform var(--c-rapido) var(--c-ease); }
.c-menu-boton:active, .c-tema:active, .c-salir:active, .c-campana > summary:active { transform: scale(var(--c-mov-pulsar)); }
.c-usuario { display: flex; align-items: center; gap: 10px; font-size: var(--c-tipo-tabla); color: var(--c-cabecera-texto-2); flex: none; }
.c-usuario-nombre { color: var(--c-cabecera-texto); }
.c-usuario form { margin: 0; }
.c-salir {
  display: grid; place-items: center; width: 44px; height: 44px; border: 0; border-radius: var(--c-radio-campo);
  background: transparent; color: inherit; font-size: 1.1rem; cursor: pointer;
}
.c-salir:hover { background: var(--c-cabecera-2); color: var(--c-cabecera-texto); }

/* Pastilla «Datos a fecha» sobre la cabecera verde */
.c-cabecera .c-pastilla { background: var(--c-cabecera-2); color: var(--c-cabecera-texto-2); flex: none; }

/* Cuerpo: menú lateral + contenido */
.c-cuerpo-interior { display: grid; grid-template-columns: var(--nav-ancho) minmax(0, 1fr); min-height: calc(100vh - 60px); }
/* El menú se queda a la vista al desplazar una página larga (Bandeja, la ficha): pegado bajo
   la cabecera y a toda la altura de la ventana, con su propio desplazamiento si no cabe. */
.c-nav {
  position: sticky; top: 60px; align-self: start; height: calc(100vh - 60px); height: calc(100dvh - 60px);
  background: var(--c-lateral); border-right: 1px solid var(--c-borde); padding: var(--c-esp-4) var(--c-esp-3); overflow-y: auto;
}
.c-nav-grupo + .c-nav-grupo { margin-top: var(--c-esp-4); }
/* Las mayúsculas espaciadas de la web de ESshipping, solo en estos rótulos cortos. */
.c-nav-grupo-titulo {
  margin: 0 0 4px; padding: 0 12px; font-size: var(--c-tipo-meta); font-weight: var(--c-peso-fuerte);
  color: var(--c-texto-2); text-transform: uppercase; letter-spacing: .08em;
}
.c-nav a {
  position: relative; display: flex; align-items: center; gap: 12px; padding: 10px 12px; border-radius: var(--c-radio-campo);
  color: var(--c-texto-2); text-decoration: none; font-size: var(--c-tipo-tabla); font-weight: var(--c-peso-medio);
  min-height: 44px; transition: background-color var(--c-rapido) var(--c-ease), color var(--c-rapido) var(--c-ease);
}
/* Icono decorativo (aria-hidden en el HTML): el mínimo AA para elementos no textuales es 3:1
   (SC 1.4.11), no 4,5:1, así que --c-texto-3 sí basta aquí. */
.c-nav a .bi { font-size: 1.1rem; width: 20px; text-align: center; color: var(--c-texto-3); }
.c-nav a:hover { background: var(--c-superficie); color: var(--c-texto); }
.c-nav a[aria-current="page"] { background: var(--nav-activo-fondo); color: var(--nav-activo-texto); font-weight: var(--c-peso-fuerte); }
.c-nav a[aria-current="page"] .bi { color: var(--nav-activo-texto); }
/* Contenido centrado en el hueco que deja el menú, hasta --contenido-max (1600 px): en
   pantalla ancha ya no queda pegado a la izquierda con media pantalla vacía a la derecha. */
.c-principal {
  width: 100%; max-width: var(--contenido-max); margin-inline: auto; min-width: 0;
  padding: var(--c-esp-8) var(--c-esp-8) var(--c-esp-12);
}

/* Pie: el proveedor, discreto */
.c-pie { text-align: center; padding: var(--c-esp-6); color: var(--c-texto-2); font-size: var(--c-tipo-meta); }

/* Títulos y texto */
.c-titulo { display: flex; align-items: flex-end; justify-content: space-between; gap: var(--c-esp-4); margin: 0 0 var(--c-esp-6); flex-wrap: wrap; }
.c-titulo h1 { font-size: var(--c-tipo-pagina); font-weight: var(--c-peso-fuerte); letter-spacing: -.015em; margin: 0; line-height: 1.15; }
/* Un solo patrón de título en todas las pantallas: la descripción, debajo del h1 y pegada a él.
   Unas vistas la envuelven con el h1 en un <div> (y a la derecha van sus acciones); otras la
   dejan como hermana directa del h1, y sin esto quedaba flotando a la derecha, lejos del título. */
.c-titulo:has(> h1 + p) { flex-direction: column; align-items: flex-start; justify-content: flex-start; gap: 0; }
.c-titulo > h1 + p { margin: 4px 0 0; text-wrap: pretty; }
.c-meta { color: var(--c-texto-2); font-size: var(--c-tipo-meta); }
.c-mono { font-family: var(--c-mono); font-variant-numeric: tabular-nums; }
.c-ayuda { color: var(--c-texto-2); font-size: var(--c-tipo-meta); margin: 4px 0 0; }

/* Botones. En caja normal, no en las mayúsculas de la web: en un panel denso las etiquetas
   son largas («Aprobar y enviar») y en mayúsculas se leen peor. La marca la ponen el verde
   y la esquina recta. */
.c-boton, .c-boton-secundario, .c-boton-peligro {
  min-height: var(--boton-alto); padding: 0 18px; border-radius: var(--c-radio-campo); font: inherit;
  font-weight: var(--c-peso-fuerte); font-size: var(--c-tipo-tabla); cursor: pointer; display: inline-flex;
  align-items: center; gap: 8px; text-decoration: none; border: 1px solid transparent;
  transition: background-color var(--c-rapido) var(--c-ease), border-color var(--c-rapido) var(--c-ease), transform var(--c-rapido) var(--c-ease);
}
.c-boton { background: var(--boton-fondo); color: var(--boton-texto); }
.c-boton:hover { background: var(--boton-fondo-hover); }
.c-boton-secundario { background: var(--c-superficie); color: var(--c-texto); border-color: var(--campo-borde); }
.c-boton-secundario:hover { background: var(--c-superficie-2); }
.c-boton-peligro { background: var(--c-error-suave); color: var(--c-error); }
.c-boton:active, .c-boton-secundario:active, .c-boton-peligro:active, .c-boton-enlace:active { transform: scale(var(--c-mov-pulsar)); transition-duration: var(--c-mov-instante); }
.c-boton:disabled, .c-boton-secundario:disabled { opacity: .55; cursor: not-allowed; }
.c-boton-enlace {
  background: transparent; border: 1px solid transparent; border-radius: var(--c-radio-campo); color: var(--c-acento-hover);
  font: inherit; font-size: var(--c-tipo-tabla); font-weight: var(--c-peso-medio); cursor: pointer; padding: 0 10px;
  min-height: var(--boton-alto-compacto); display: inline-flex; align-items: center; text-decoration: none;
  transition: background-color var(--c-rapido) var(--c-ease), transform var(--c-rapido) var(--c-ease);
}
.c-boton-enlace:hover { background: var(--c-acento-suave); }
@media (pointer: coarse) { .c-cuerpo { --boton-alto-compacto: 44px; } }

/* Campos y formularios */
.c-cuerpo label { text-transform: none; letter-spacing: normal; }
.c-campo { display: flex; flex-direction: column; gap: 6px; min-width: 0; margin: 0 0 var(--c-esp-4); }
.c-campo label { font-size: var(--c-tipo-tabla); font-weight: var(--c-peso-medio); color: var(--c-texto-2); }
.c-campo input:not([type=checkbox]):not([type=radio]), .c-campo select, .c-campo textarea {
  width: 100%; min-height: var(--campo-alto); font: inherit; padding: 10px 12px; border: 1px solid var(--campo-borde);
  border-radius: var(--c-radio-campo); background: var(--campo-fondo); color: var(--c-texto);
  transition: border-color var(--c-rapido) var(--c-ease);
}
.c-campo input:not([type=checkbox]):not([type=radio]):focus, .c-campo select:focus, .c-campo textarea:focus { border-color: var(--campo-borde-foco); }
.c-campo textarea { min-height: 7rem; resize: vertical; line-height: 1.5; }
/* Campo con error: borde en la tinta de error (el mensaje en texto va aparte, con aria-describedby). */
.c-campo input[aria-invalid="true"]:not(:focus), .c-campo textarea[aria-invalid="true"]:not(:focus) { border-color: var(--c-error); }
.c-acciones { display: flex; gap: 12px; align-items: center; flex-wrap: wrap; margin-top: var(--c-esp-6); }

/* Fichas, listas, avisos, pastillas */
.c-ficha { background: var(--ficha-fondo); border: 1px solid var(--ficha-borde); border-radius: var(--ficha-radio); padding: var(--c-esp-6); margin: 0 0 var(--c-esp-4); box-shadow: var(--c-sombra); }
.c-ficha h2 { font-size: var(--c-tipo-seccion); font-weight: var(--c-peso-fuerte); margin: 0 0 var(--c-esp-3); letter-spacing: -.01em; }
.c-lista { list-style: none; margin: 0; padding: 0; border: 1px solid var(--c-borde); border-radius: var(--ficha-radio); background: var(--c-superficie); overflow: hidden; }
.c-lista li + li { border-top: 1px solid var(--c-borde); }
.c-lista a, .c-lista .c-fila { display: flex; align-items: center; gap: 14px; min-height: var(--lista-fila-alto); padding: 10px 18px; color: inherit; text-decoration: none; }
.c-lista a { transition: background-color var(--c-rapido) var(--c-ease); }
/* Hover solo con ratón: en táctil el hover se queda pegado a la última fila tocada. La
   pulsación sí se ve en los dos. */
@media (hover: hover) { .c-lista a:hover { background: var(--lista-fila-hover); } }
.c-lista a:active { background: var(--lista-fila-hover); }
/* La lista recorta lo que sale de sus bordes (overflow: hidden): el anillo de foco de una
   fila va por dentro para que se vea entero en la primera y la última. */
.c-cuerpo .c-lista a:focus-visible { outline-offset: -3px; }
.c-fila-principal { flex: 1; min-width: 0; }
.c-fila-principal strong { display: block; font-weight: var(--c-peso-fuerte); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.c-fila-principal small { color: var(--c-texto-2); font-size: var(--c-tipo-meta); }

/* Pastillas: tinta oscura de la familia del color sobre su propio tinte (≥ 5,4:1 en los dos
   temas; cifras en DESIGN.md). Rectangulares, como una etiqueta de bulto. */
.c-pastilla { display: inline-flex; align-items: center; gap: 6px; padding: 3px 8px; border-radius: var(--c-radio-pastilla); font-size: var(--c-tipo-meta); font-weight: var(--c-peso-medio); line-height: 1.35; background: var(--c-superficie-2); color: var(--c-texto-2); white-space: nowrap; }
.c-pastilla-acento { background: var(--c-acento-suave); color: var(--c-acento-hover); }
.c-pastilla-ok { background: var(--c-ok-suave); color: var(--c-ok); }
.c-pastilla-aviso { background: var(--c-aviso-suave); color: var(--c-aviso); }
.c-pastilla-atencion { background: var(--c-atencion-suave); color: var(--c-atencion); }
.c-pastilla-error { background: var(--c-error-suave); color: var(--c-error); }

.c-aviso { padding: 12px 16px; border-radius: var(--c-radio-campo); margin: 0 0 var(--c-esp-4); font-size: var(--c-tipo-tabla); border: 1px solid transparent; }
.c-aviso-ok { background: var(--c-ok-suave); color: var(--c-ok); }
.c-aviso-error { background: var(--c-error-suave); color: var(--c-error); }
.c-aviso-info { background: var(--c-acento-suave); color: var(--c-acento-hover); }
.c-aviso-atencion { background: var(--c-aviso-suave); color: var(--c-aviso); }

/* Avisos flotantes (app.js, avisoMostrar): abajo a la derecha, fijos, para que se vean
   aunque la persona esté a mitad de página (aprobar una propuesta, cambiar una regla).
   Entran con un desplazamiento corto y salen antes de lo que tardan en entrar. */
.c-avisos {
  position: fixed; z-index: 25; right: var(--c-esp-6); bottom: var(--c-esp-6);
  width: min(420px, calc(100vw - 2 * var(--c-esp-4))); display: flex; flex-direction: column-reverse;
  gap: var(--c-esp-2); pointer-events: none;
}
.c-avisos .c-aviso {
  margin: 0; pointer-events: auto; border-color: var(--c-borde-fuerte); box-shadow: var(--c-sombra-alta);
  transition: opacity var(--c-abrir) var(--c-ease), transform var(--c-abrir) var(--c-ease);
}
@starting-style { .c-avisos .c-aviso { opacity: 0; transform: translateY(8px); } }
.c-avisos .c-aviso[data-saliendo] { opacity: 0; transform: translateY(4px); transition-duration: var(--c-cerrar); }

.c-vacio { padding: var(--c-esp-12) var(--c-esp-8); background: var(--c-superficie-2); border-radius: var(--ficha-radio); text-align: left; max-width: 60ch; }
.c-vacio h2 { margin: 0 0 8px; font-size: var(--c-tipo-ficha); font-weight: var(--c-peso-fuerte); }
.c-vacio p { color: var(--c-texto-2); margin: 0 0 var(--c-esp-4); }
.c-vacio .c-acciones { margin-top: 0; }

/* Tablas. Bordes separados (con espacio 0) en vez de `collapse` + `overflow: hidden`: el radio
   funciona sin recortar, y las columnas fijas (position: sticky) de las pantallas pueden
   pegarse al desplazar el envoltorio. Las celdas de las esquinas llevan el radio de dentro. */
.c-tabla { width: 100%; border-collapse: separate; border-spacing: 0; font-size: var(--c-tipo-tabla); background: var(--c-superficie); border: 1px solid var(--c-borde); border-radius: var(--ficha-radio); }
.c-tabla > :first-child > tr:first-child > :first-child { border-start-start-radius: calc(var(--ficha-radio) - 1px); }
.c-tabla > :first-child > tr:first-child > :last-child { border-start-end-radius: calc(var(--ficha-radio) - 1px); }
.c-tabla > :last-child > tr:last-child > :first-child { border-end-start-radius: calc(var(--ficha-radio) - 1px); }
.c-tabla > :last-child > tr:last-child > :last-child { border-end-end-radius: calc(var(--ficha-radio) - 1px); }
.c-tabla th, .c-tabla td { text-align: left; padding: 10px 14px; border-bottom: 1px solid var(--c-borde); vertical-align: top; }
.c-tabla th { font-size: var(--c-tipo-meta); color: var(--c-texto-2); font-weight: var(--c-peso-fuerte); background: var(--c-superficie-2); }
.c-tabla tr:last-child td { border-bottom: 0; }
/* position: relative hace del envoltorio el bloque contenedor de lo que va posicionado dentro
   (el texto oculto para lectores de pantalla va en absolute): sin él, ese texto escapaba del
   desplazamiento propio y ensanchaba la página entera cuando la tabla no cabía. */
.c-tabla-envoltorio { position: relative; overflow-x: auto; border-radius: var(--ficha-radio); }
/* Chrome hace tabulable un contenedor con desplazamiento que no tiene nada enfocable dentro,
   para moverlo con las flechas: su foco se ve como el del resto, en todas las pantallas (WCAG 2.4.7). */
.c-cuerpo .c-tabla-envoltorio:focus-visible { outline: 3px solid var(--c-acento); outline-offset: 2px; }

.c-buscador { display: flex; gap: 8px; align-items: center; flex-wrap: wrap; margin: 0 0 var(--c-esp-4); }
.c-buscador input[type=search], .c-buscador select { min-height: 44px; font: inherit; font-size: var(--c-tipo-tabla); padding: 6px 10px; border: 1px solid var(--campo-borde); border-radius: var(--c-radio-campo); background: var(--campo-fondo); color: var(--c-texto); }

.c-kpis { display: grid; grid-template-columns: repeat(auto-fit, minmax(180px, 1fr)); gap: var(--c-esp-4); margin: 0 0 var(--c-esp-6); }
.c-kpi { background: var(--c-superficie); border: 1px solid var(--c-borde); border-radius: var(--ficha-radio); padding: 16px 18px; }
/* Solo el rótulo (hijo directo): un .c-contador dentro del <strong> no debe heredar este estilo. */
.c-kpi > span { display: block; color: var(--c-texto-2); font-size: var(--c-tipo-meta); }
.c-kpi strong { display: block; margin-top: 2px; line-height: 1.2; font-size: 1.5rem; font-weight: var(--c-peso-fuerte); letter-spacing: -.02em; font-variant-numeric: tabular-nums; }

.c-pestanas { display: flex; gap: 4px; border-bottom: 1px solid var(--c-borde); margin: 0 0 var(--c-esp-6); flex-wrap: wrap; }
.c-pestanas a { display: inline-flex; align-items: center; gap: 6px; min-height: 44px; padding: 10px 14px; color: var(--c-texto-2); text-decoration: none; font-size: var(--c-tipo-tabla); font-weight: var(--c-peso-medio); border-bottom: 2px solid transparent; margin-bottom: -1px; transition: color var(--c-rapido) var(--c-ease); }
.c-pestanas a:hover { color: var(--c-texto); }
.c-pestanas a[aria-current] { color: var(--c-acento-hover); border-bottom-color: var(--c-acento); }

.c-semaforo { display: inline-flex; align-items: center; gap: 8px; font-size: var(--c-tipo-tabla); }
.c-semaforo::before { content: ''; width: 8px; height: 8px; border-radius: 50%; background: var(--semaforo-neutro); flex: none; }
.c-semaforo[data-estado="ok"]::before { background: var(--semaforo-ok); }
.c-semaforo[data-estado="aviso"]::before { background: var(--semaforo-aviso); }
.c-semaforo[data-estado="error"]::before { background: var(--semaforo-error); }

/* Pantalla de acceso: dos paños. A la izquierda la marca (verde corporativo, logotipo con
   lema y el lema en grande, enmarcado por los corchetes del logotipo); a la derecha, el
   formulario sobre el fondo neutro. En móvil los paños se apilan. */
.c-cuerpo-minimal { display: flex; flex-direction: column; min-height: 100vh; min-height: 100dvh; }
.c-acceso-marco { flex: 1; display: grid; grid-template-columns: minmax(0, 5fr) minmax(0, 6fr); }
.c-acceso-marca {
  display: flex; flex-direction: column; justify-content: space-between; gap: var(--c-esp-12);
  padding: var(--c-esp-12); color: var(--c-cabecera-texto);
  position: relative; overflow: hidden; isolation: isolate;
  /* Debajo, el paño verde; encima, el plano técnico en línea (layout_plano_acceso, se dibuja
     al cargar); y por encima de los dos, el oscurecido de abajo para que se lea el lema. */
  background: radial-gradient(ellipse at 60% 40%, #0a6b3f 0%, var(--c-cabecera) 70%);
  background-color: var(--c-cabecera);
}
.c-acceso-marca::after {
  content: ''; position: absolute; inset: 0; z-index: -1; pointer-events: none;
  background:
    linear-gradient(to top, var(--c-cabecera) 0%, color-mix(in srgb, var(--c-cabecera) 82%, transparent) 22%, transparent 52%),
    radial-gradient(ellipse at 30% 0%, color-mix(in srgb, var(--c-cabecera) 55%, transparent) 0%, transparent 40%);
}
.c-acceso-marca > :not(.c-acceso-plano) { position: relative; }
/* Tamaño nativo (182×53): el PNG no se escala hacia arriba, que lo emborronaría. */
.c-acceso-logo { display: block; width: 220px; height: auto; filter: brightness(0) invert(1); }
.c-acceso-lema-bloque { position: relative; width: fit-content; max-width: min(100%, 34rem); padding: var(--c-esp-6) var(--c-esp-8); }
/* Los corchetes del logotipo, en grande y en el menta de la web: solo decoración. */
.c-acceso-lema-bloque::before, .c-acceso-lema-bloque::after {
  content: ''; position: absolute; top: 0; bottom: 0; width: 14px;
  border: 2px solid var(--marca-corchete); pointer-events: none;
}
.c-acceso-lema-bloque::before { left: 0; border-right: 0; }
.c-acceso-lema-bloque::after { right: 0; border-left: 0; }
.c-acceso-lema { margin: 0; font-size: clamp(1.75rem, 1.1rem + 2.2vw, 2.75rem); font-weight: var(--c-peso-fuerte); line-height: 1.1; letter-spacing: -.02em; text-wrap: balance; }
.c-acceso-bajada { max-width: 38ch; margin: var(--c-esp-3) 0 0; color: var(--c-cabecera-texto-2); font-size: var(--c-tipo-cuerpo); line-height: 1.45; text-wrap: pretty; }
.c-acceso-zona { display: flex; flex-direction: column; align-items: center; justify-content: center; gap: var(--c-esp-6); padding: var(--c-esp-12) var(--c-esp-6) var(--c-esp-6); }
.c-acceso { width: 100%; max-width: 380px; margin: auto 0; background: var(--c-superficie); border: 1px solid var(--c-borde); border-radius: var(--c-radio-ficha-alta); padding: var(--c-esp-8); box-shadow: var(--c-sombra-alta); }
.c-acceso-titulo { font-size: var(--c-tipo-ficha); font-weight: var(--c-peso-fuerte); margin: 0 0 4px; letter-spacing: -.01em; }
.c-acceso-formulario { margin-top: var(--c-esp-4); }
.c-acceso-formulario .c-acciones { margin-top: var(--c-esp-2); }
.c-acceso-formulario .c-boton { width: 100%; justify-content: center; }
.c-acceso-formulario .c-boton[aria-disabled="true"] { opacity: .75; cursor: progress; }
.c-acceso-error { display: flex; align-items: flex-start; gap: var(--c-esp-2); margin: var(--c-esp-4) 0 0; }
.c-acceso-error .bi { flex: none; margin-top: 2px; }
.c-acceso-pie { color: var(--c-texto-2); font-size: var(--c-tipo-meta); text-align: center; }

/* Animaciones comunes: lo que se despliega (el contenido de un <details> al abrir) entra con un
   desplazamiento corto; lo que está en curso gira. Las pantallas las usan por nombre. */
@keyframes c-aparecer { from { opacity: 0; transform: translateY(-4px); } to { opacity: 1; transform: none; } }
@keyframes c-giro { to { transform: rotate(360deg); } }

/* Movimiento reducido */
@media (prefers-reduced-motion: reduce) {
  .c-cuerpo * { transition: none !important; animation: none !important; }
  .c-cuerpo *:active { transform: none !important; }
}

/* Cabecera en una fila entre 901 y 1180 px: sin el nombre de la persona (Salir sigue a la
   vista), para que el buscador no se quede en nada (a 901 px medía 26 px). */
@media (max-width: 1180px) {
  .c-usuario-nombre { display: none; }
}

/* Menú lateral plegable y cabecera en dos filas (≤900 px, comun.md) */
@media (max-width: 900px) {
  /* Dos filas: menú, marca, Simular, tema y salir arriba; buscador y fecha de los datos debajo.
     En una sola fila no cabía todo por debajo de 900 px: el buscador se quedaba en nada y el
     tema y «Salir» salían de la pantalla. El alto de las dos filas va en --cabecera-fija. */
  :root { --cabecera-fija: 112px; }
  .c-cabecera { flex-wrap: wrap; height: auto; min-height: 60px; padding: 8px var(--c-esp-3); gap: 0 8px; }
  /* Salto de fila: una pieza vacía a todo el ancho entre lo de arriba (order 0) y lo de abajo
     (order 5 y 6). Sin ella, a partir de unos 700 px el buscador subía a la primera fila y la
     fecha se quedaba sola en la segunda. */
  .c-cabecera::after { content: ''; order: 4; flex-basis: 100%; height: 0; }
  .c-buscador-cabecera { order: 5; flex: 1 1 180px; max-width: none; margin: 8px 0 0; }
  .c-cabecera .c-pastilla { order: 6; margin-top: 8px; }

  /* El menú desplegado se abre justo debajo de la cabecera, sea cual sea su alto. */
  .c-cuerpo-interior { grid-template-columns: 1fr; position: relative; }
  .c-menu-boton { display: inline-flex; }
  /* Fijo bajo la cabecera (app.js mide su alto en --cabecera-alto): así se abre a la vista
     aunque la página esté desplazada. Entra deslizando 8 px desde la cabecera; al cerrar se
     quita sin más. */
  .c-nav {
    display: none; position: fixed; top: var(--cabecera-alto, 60px); left: 0; right: 0; z-index: 15;
    height: auto; max-height: calc(100dvh - var(--cabecera-alto, 60px)); overscroll-behavior: contain;
    border-right: 0; border-bottom: 1px solid var(--c-borde); box-shadow: var(--c-sombra-alta);
    transition: opacity var(--c-abrir) var(--c-ease-cajon), transform var(--c-abrir) var(--c-ease-cajon);
  }
  body.c-nav-abierta .c-nav { display: block; }
  @starting-style { body.c-nav-abierta .c-nav { opacity: 0; transform: translateY(calc(-1 * var(--c-mov-dist-2))); } }
  .c-principal { padding: var(--c-esp-4) var(--c-esp-4) var(--c-esp-12); }

  .c-acceso-marco { grid-template-columns: 1fr; }
  .c-acceso-marca { gap: var(--c-esp-6); padding: var(--c-esp-6) var(--c-esp-4) var(--c-esp-8); }
  .c-acceso-lema-bloque { padding: var(--c-esp-4) var(--c-esp-6); }
  .c-acceso-zona { padding: var(--c-esp-6) var(--c-esp-4); }
}

/* Primera fila de la cabecera por debajo de 560 px: «Operaciones» ya no cabe junto a la marca,
   Simular, el tema y Salir. (A 480 px o menos, Simular se queda en su icono: simulador.css.) */
@media (max-width: 560px) {
  .c-marca-sep, .c-marca-sub { display: none; }
}
/* Teléfono: menú, marca, campanita, tema y Salir en la primera fila. Con 8 px de hueco no cabían
   a 375 px (con barra de desplazamiento) y Salir bajaba solo a otra fila. */
@media (max-width: 420px) {
  .c-cabecera { gap: 0 4px; padding-inline: var(--c-esp-2); }
  .c-marca-logo { height: 26px; }
}

/* Nada desborda a 390 px (comun.md) */
@media (max-width: 480px) {
  /* Dos por fila: una cifra corta no necesita todo el ancho y así la tabla asoma antes. */
  .c-kpis { grid-template-columns: repeat(2, minmax(0, 1fr)); gap: var(--c-esp-2); }
  .c-kpi { padding: 12px 14px; }
  .c-acceso { padding: var(--c-esp-6) var(--c-esp-4); }
  .c-avisos { right: var(--c-esp-4); bottom: var(--c-esp-4); }
}


/* Campanita de avisos por niveles (layout_avisos_campana). Panel que asoma desde la campana
   (origen arriba a la derecha) y se cierra sin animación: cerrar se quita de en medio. Fuera
   del panel o con Escape se cierra (app.js). El nivel va en texto, nunca solo en color. */
.c-campana { position: relative; margin-left: auto; }
.c-campana > summary {
  list-style: none; cursor: pointer; display: grid; place-items: center; position: relative;
  width: 44px; height: 44px; border-radius: var(--c-radio-campo); color: var(--c-cabecera-texto); font-size: 1.1rem;
  transition: background-color var(--c-mov-rapido) var(--c-ease), transform var(--c-mov-instante) var(--c-ease);
}
.c-campana > summary::-webkit-details-marker { display: none; }
.c-campana > summary:hover, .c-campana[open] > summary { background: var(--c-cabecera-2); }
.c-campana-cuenta {
  position: absolute; top: 5px; right: 3px; min-width: 18px; height: 18px; padding: 0 5px; border-radius: 9px;
  background: var(--campana-revisar); color: var(--campana-revisar-texto); box-shadow: 0 0 0 2px var(--c-cabecera);
  font-size: 11px; font-weight: 700; line-height: 18px; text-align: center; font-variant-numeric: tabular-nums;
}
.c-campana-cuenta.c-campana-grave { background: var(--campana-grave); color: var(--campana-grave-texto); }
.c-campana-panel {
  position: absolute; right: 0; top: calc(100% + 8px); z-index: 50; width: min(380px, calc(100vw - 24px));
  background: var(--c-superficie); color: var(--c-texto); border: 1px solid var(--c-borde);
  border-radius: var(--c-radio-ficha-alta); box-shadow: var(--c-sombra-alta); padding: var(--c-esp-3);
  transform-origin: top right;
  transition: opacity var(--c-mov-normal) var(--c-ease), transform var(--c-mov-normal) var(--c-ease);
}
@starting-style {
  .c-campana[open] .c-campana-panel { opacity: 0; transform: translateY(calc(-1 * var(--c-mov-dist-1))) scale(var(--c-mov-asomar)); }
}
:root[data-bs-theme="dark"] .c-campana-panel { border-color: var(--c-borde-fuerte); }
.c-campana-titulo { margin: 0 0 var(--c-esp-2); padding: 0 var(--c-esp-1); font-size: var(--c-tipo-meta); font-weight: var(--c-peso-fuerte); color: var(--c-texto-2); text-transform: uppercase; letter-spacing: .08em; }
.c-campana-panel ul { list-style: none; margin: 0; padding: 0; display: grid; gap: var(--c-esp-1); }
.c-campana-panel li { font-size: var(--c-tipo-tabla); line-height: 1.4; }
.c-campana-panel a {
  display: block; padding: var(--c-esp-2) var(--c-esp-3); border-radius: var(--c-radio-campo);
  color: var(--c-texto); text-decoration: none; transition: background-color var(--c-mov-rapido) var(--c-ease);
}
.c-campana-panel a:hover { background: var(--c-superficie-2); }
.c-cuerpo .c-campana-panel a:focus-visible { outline-offset: -3px; }
.c-campana-panel strong {
  display: inline-block; margin-right: 6px; padding: 1px 6px; border-radius: var(--c-radio-pastilla);
  font-size: 11px; font-weight: var(--c-peso-fuerte); letter-spacing: .04em; text-transform: uppercase;
  background: var(--c-atencion-suave); color: var(--c-atencion);
}
.c-campana-panel li[data-nivel="grave"] strong { background: var(--c-error-suave); color: var(--c-error); }
.c-campana-panel small { display: block; color: var(--c-texto-2); margin: -2px 0 var(--c-esp-1); padding: 0 var(--c-esp-3); font-size: var(--c-tipo-meta); }
.c-campana + .c-tema { margin-left: 0; }
@media (max-width: 560px) {
  .c-campana-panel { position: fixed; left: var(--c-esp-3); right: var(--c-esp-3); top: 64px; width: auto; transform-origin: top center; }
}

/* ======================================================================================
   Movimiento y estilo (COMUN.md). Tokens en tokens.css; JS en app.js (window.inasor.animar).
   ====================================================================================== */

/* Menú lateral: indicador de la sección activa. Es un elemento propio (layout.php) con nombre
   de transición: al cambiar de página se desliza de la sección vieja a la nueva. */
.c-nav-indicador {
  position: absolute; left: 0; top: 50%; width: 3px; height: 20px; margin-top: -10px;
  border-radius: 0 2px 2px 0; background: var(--c-acento); view-transition-name: c-nav-indicador;
}

/* Transiciones entre páginas (View Transitions entre documentos). Sin soporte, nada cambia.
   La cabecera y el menú no cruzan (son iguales en las dos páginas); el contenido sale en 100 ms
   y entra en 220 ms con 4 px de recorrido; el título se desplaza a su sitio. */
/* El permiso (@view-transition) va en un <style> en línea en layout.php: desde aquí llegaba tarde. */
.c-cabecera { view-transition-name: c-cabecera; }
.c-nav { view-transition-name: c-nav; }
.c-titulo h1 { view-transition-name: c-titulo; }
::view-transition-group(*) { animation-duration: var(--c-mov-pagina); animation-timing-function: var(--c-ease-morfar); }
::view-transition-old(root) { animation: c-vt-salir var(--c-mov-instante) var(--c-ease) both; }
::view-transition-new(root) { animation: c-vt-entrar var(--c-mov-pagina) var(--c-ease) both; }
::view-transition-group(c-cabecera), ::view-transition-group(c-nav) { animation: none; }
::view-transition-old(c-cabecera), ::view-transition-old(c-nav) { display: none; }
::view-transition-new(c-cabecera), ::view-transition-new(c-nav) { animation: none; }
/* Lo que cambia de texto (el título, una ficha que pasa a cabecera): las dos capturas guardan
   su tamaño natural (no se estiran) y cruzan mientras el grupo se desplaza. */
::view-transition-old(*), ::view-transition-new(*) { width: auto; height: auto; }
::view-transition-old(root), ::view-transition-new(root) { width: 100%; height: auto; }
@keyframes c-vt-salir { to { opacity: 0; } }
@keyframes c-vt-entrar { from { opacity: 0; transform: translateY(var(--c-mov-dist-1)); } }

/* Entradas. Relleno «backwards»: durante el retraso se ve el primer fotograma y al acabar no
   queda nada aplicado (un transform que se quedara fijo rompería los position: fixed/sticky de
   dentro). El retraso es --i pasos de --c-mov-paso, con tope de 10. */
@keyframes c-entrada { from { opacity: 0; transform: translateY(var(--c-mov-dist-2)); } }
@keyframes c-entrada-fundido { from { opacity: 0; } }
@keyframes c-entrada-asomar { from { opacity: 0; transform: scale(var(--c-mov-asomar)); } }
:is([data-entrada], [data-escalonado]:not(table) > *, .c-tabla[data-escalonado] > tbody > tr, .c-kpis > *) {
  animation: c-entrada var(--c-mov-entrada) var(--c-ease) backwards;
  animation-delay: calc(min(var(--i, 0), 10) * var(--c-mov-paso));
}
[data-entrada="fundido"] { animation-name: c-entrada-fundido; }
[data-entrada="asomar"] { animation-name: c-entrada-asomar; }
:is([data-escalonado]:not(table) > *, .c-tabla[data-escalonado] > tbody > tr, .c-kpis > *):nth-child(2) { --i: 1; }
:is([data-escalonado]:not(table) > *, .c-tabla[data-escalonado] > tbody > tr, .c-kpis > *):nth-child(3) { --i: 2; }
:is([data-escalonado]:not(table) > *, .c-tabla[data-escalonado] > tbody > tr, .c-kpis > *):nth-child(4) { --i: 3; }
:is([data-escalonado]:not(table) > *, .c-tabla[data-escalonado] > tbody > tr, .c-kpis > *):nth-child(5) { --i: 4; }
:is([data-escalonado]:not(table) > *, .c-tabla[data-escalonado] > tbody > tr, .c-kpis > *):nth-child(6) { --i: 5; }
:is([data-escalonado]:not(table) > *, .c-tabla[data-escalonado] > tbody > tr, .c-kpis > *):nth-child(7) { --i: 6; }
:is([data-escalonado]:not(table) > *, .c-tabla[data-escalonado] > tbody > tr, .c-kpis > *):nth-child(8) { --i: 7; }
:is([data-escalonado]:not(table) > *, .c-tabla[data-escalonado] > tbody > tr, .c-kpis > *):nth-child(9) { --i: 8; }
:is([data-escalonado]:not(table) > *, .c-tabla[data-escalonado] > tbody > tr, .c-kpis > *):nth-child(10) { --i: 9; }
:is([data-escalonado]:not(table) > *, .c-tabla[data-escalonado] > tbody > tr, .c-kpis > *):nth-child(n+11) { --i: 10; }

/* Revelar al desplazarse: app.js marca [data-revelado] al entrar en la vista. Solo se oculta
   con JS en marcha (:root.c-js); lo que ya se veía al cargar se marca antes de ocultar nada. */
[data-revelar] {
  transition: opacity var(--c-mov-entrada) var(--c-ease), transform var(--c-mov-entrada) var(--c-ease);
  transition-delay: calc(min(var(--i, 0), 10) * var(--c-mov-paso));
}
:root.c-js [data-revelar]:not([data-revelado]) { opacity: 0; transform: translateY(var(--c-mov-dist-2)); }

/* Contadores: cifras de ancho fijo, para que al subir no baile lo de alrededor. */
.c-contador, .c-kpi strong { font-variant-numeric: tabular-nums; }

/* Fichas y filas clicables: borde al pasar (solo ratón) y respuesta al pulsar. */
[data-pulsable] {
  cursor: pointer;
  transition: transform var(--c-mov-instante) var(--c-ease), border-color var(--c-mov-rapido) var(--c-ease), background-color var(--c-mov-rapido) var(--c-ease);
}
@media (hover: hover) and (pointer: fine) {
  [data-pulsable]:hover { border-color: var(--c-borde-fuerte); }
}
[data-pulsable]:active { transform: scale(var(--c-mov-pulsar-grande)); }

/* Lo que acaba de cambiar tras una acción: el fondo se tiñe y se apaga solo. */
@keyframes c-realce { from { background-color: var(--c-acento-suave); box-shadow: inset 0 0 0 1px var(--c-acento); } }
.c-realce { animation: c-realce var(--c-mov-realce) var(--c-ease) backwards; }

/* Cargas: esqueleto con un brillo que lo recorre (transform, sin repintar) y ruedecita. */
.c-esqueleto, .c-esqueleto-linea { position: relative; overflow: hidden; background: var(--esqueleto-fondo); border-radius: var(--c-radio-campo); }
.c-esqueleto { min-height: 96px; }
.c-esqueleto-linea { display: block; height: .75em; margin: .5em 0; width: var(--ancho, 100%); }
.c-esqueleto-linea:last-child { width: var(--ancho, 62%); }
.c-esqueleto::after, .c-esqueleto-linea::after {
  content: ''; position: absolute; inset: 0; transform: translateX(-100%);
  background: linear-gradient(90deg, transparent, var(--esqueleto-brillo), transparent);
  animation: c-brillo 1.4s linear infinite;
}
@keyframes c-brillo { to { transform: translateX(100%); } }
.c-cargando, :is(.c-boton, .c-boton-secundario, .c-boton-peligro, .c-boton-enlace)[aria-busy="true"]::before {
  display: inline-block; width: 14px; height: 14px; flex: none; border-radius: 50%;
  border: 2px solid currentColor; border-right-color: transparent; vertical-align: -2px;
  animation: c-giro .7s linear infinite;
}
:is(.c-boton, .c-boton-secundario, .c-boton-peligro, .c-boton-enlace)[aria-busy="true"] { pointer-events: none; cursor: progress; opacity: .85; }
:is(.c-boton, .c-boton-secundario, .c-boton-peligro, .c-boton-enlace)[aria-busy="true"]::before { content: ''; }

/* Avisos flotantes: además del desplazamiento, asoman desde abajo a la derecha. */
.c-avisos .c-aviso { transform-origin: bottom right; display: flex; align-items: flex-start; gap: var(--c-esp-2); }
.c-avisos .c-aviso .bi { flex: none; margin-top: 2px; }
@starting-style { .c-avisos .c-aviso { opacity: 0; transform: translateY(var(--c-mov-dist-2)) scale(var(--c-mov-asomar)); } }

/* Tablas: cifras alineadas y fila bajo el ratón, sin transición (se recorre muy a menudo).
   Con peso cero (:where) para que cualquier pantalla mande sobre esto. */
:where(.c-tabla td) { font-variant-numeric: tabular-nums; }
@media (hover: hover) and (pointer: fine) {
  :where(.c-tabla > tbody > tr:hover > td) { background: var(--lista-fila-hover); }
}

/* Pantalla de acceso: el plano se dibuja una vez. Primero la cuadrícula, luego los contornos
   (escalonados por --i, que pone layout_plano_acceso), después ejes y rayados, y al final las
   cotas (--j). Unos 2,4 s: es la primera pantalla y el formulario se puede usar desde el primer
   instante. Encima, un paralaje leve con el ratón (app.js). */
.c-acceso-plano {
  position: absolute; left: -16px; top: -16px; width: calc(100% + 32px); height: calc(100% + 32px);
  z-index: -2; pointer-events: none;
}
.c-acceso-plano .g1 { stroke: var(--plano-trazo); stroke-opacity: .045; stroke-width: 1; }
.c-acceso-plano .g2 { stroke: var(--plano-trazo); stroke-opacity: .08; stroke-width: 1; }
.c-acceso-plano .m { fill: none; stroke: var(--plano-trazo); stroke-opacity: .62; stroke-width: 1.7; stroke-linejoin: round; }
.c-acceso-plano .f { fill: none; stroke: var(--plano-trazo); stroke-opacity: .38; stroke-width: 1; }
.c-acceso-plano .c { fill: none; stroke: var(--plano-cota); stroke-opacity: .55; stroke-width: 1; stroke-dasharray: 22 5 3 5; }
.c-acceso-plano .h { fill: none; stroke: var(--plano-trazo); stroke-opacity: .35; stroke-width: 1.1; stroke-dasharray: 7 5; }
.c-acceso-plano .d { fill: none; stroke: var(--plano-cota); stroke-opacity: .6; stroke-width: 1; }
.c-acceso-plano .r { fill: var(--plano-cota); fill-opacity: .7; }
.c-acceso-plano .t { fill: var(--plano-trazo); fill-opacity: .7; font: 500 15px var(--c-mono); letter-spacing: .04em; }
.c-acceso-plano .ts { fill: var(--plano-trazo); fill-opacity: .5; font: 500 12px var(--c-mono); letter-spacing: .08em; }
.c-acceso-plano .tb { fill: var(--plano-trazo); fill-opacity: .82; font: 600 17px var(--c-mono); letter-spacing: .12em; }
.c-acceso-plano .x { stroke: var(--plano-trazo); stroke-opacity: .22; stroke-width: 1; }
@keyframes c-trazar { from { stroke-dashoffset: 1; } to { stroke-dashoffset: 0; } }
@keyframes c-plano-aparecer { from { opacity: 0; } }
@keyframes c-cota-aparecer { from { opacity: 0; transform: translateY(3px); } }
.c-acceso-plano :is(.g1, .g2) { animation: c-plano-aparecer 900ms var(--c-ease) backwards; }
.c-acceso-plano [pathLength] {
  stroke-dasharray: 1; animation: c-trazar 1100ms var(--c-ease-trazo) backwards;
  animation-delay: calc(150ms + var(--i, 0) * 16ms);
}
.c-acceso-plano :is(.c, .h, rect:not([class])) { animation: c-plano-aparecer 700ms var(--c-ease) 900ms backwards; }
.c-acceso-plano :is(.d, .r, .t) {
  transform-box: fill-box; animation: c-cota-aparecer 500ms var(--c-ease) backwards;
  animation-delay: calc(1300ms + var(--j, 0) * 14ms);
}
.c-acceso-plano :is(.ts, .tb) { animation: c-plano-aparecer 800ms var(--c-ease) 1100ms backwards; }
/* Los corchetes del lema se cierran sobre él y el formulario asoma, ya utilizable. */
@keyframes c-corchete-izq { from { opacity: 0; transform: translateX(-10px); } }
@keyframes c-corchete-der { from { opacity: 0; transform: translateX(10px); } }
.c-acceso-lema-bloque::before { animation: c-corchete-izq 700ms var(--c-ease) 250ms backwards; }
.c-acceso-lema-bloque::after { animation: c-corchete-der 700ms var(--c-ease) 250ms backwards; }
.c-acceso-lema-bloque > * { animation: c-entrada 600ms var(--c-ease) 350ms backwards; }
.c-acceso-lema-bloque > * + * { animation-delay: 430ms; }
.c-acceso { animation: c-entrada-asomar var(--c-mov-entrada) var(--c-ease) backwards; }
.c-acceso-error { animation: c-entrada var(--c-mov-normal) var(--c-ease) backwards; }

/* Movimiento reducido (además de la regla general de arriba; la transición de página solo se
   pide con «no-preference», en layout.php). La ruedecita sigue girando, despacio: es la única señal de que algo está en curso. */
@media (prefers-reduced-motion: reduce) {
  .c-cuerpo .c-cargando, .c-cuerpo [aria-busy="true"]::before { animation: c-giro 1.6s linear infinite !important; }
}
