/* =====================================================================
   clotitec-componentes.css · Clotitec Design OS · componentes de marca

   Los componentes que hoy se copian a mano entre la web, la landing y los
   paneles, escritos una sola vez sobre las variables --ct-*.

   SE CARGA DESPUÉS de css/clotitec.css (variables, temas y utilidades):
     <link rel="stylesheet" href="css/clotitec.css">
     <link rel="stylesheet" href="componentes/marca/clotitec-componentes.css">
     <script src="componentes/marca/clotitec-componentes.js" defer></script>

   REGLAS DE ESTE ARCHIVO
   · Ningún color, radio, sombra, duración ni curva escritos a mano: todo sale
     de --ct-*. Lo que falta está en componentes/FALTAN-TOKENS.md.
   · No redefine las utilidades generadas (.ct-superficie-verde, .ct-pastilla,
     .ct-rotulo, .ct-tarjeta-flotante, .ct-relieve, .ct-destacado): las compone.
   · Botón con texto blanco = --ct-primario-relleno. Nunca amarillo en botón,
     enlace ni párrafo. Sobre la superficie verde el CTA se invierte a blanco.
   · Solo se animan transform y opacity. Todo respeta prefers-reduced-motion.
   · Estado por ARIA (aria-current, aria-selected, aria-pressed, aria-invalid,
     aria-busy, aria-disabled). Las clases .is-hover, .is-foco e .is-activo
     existen solo para enseñar un estado quieto en la galería: las tienen
     botón, enlace, campo, tarjeta, navegación, pestaña, fila y marco de tabla.
   · Variables que empiezan por --_ : internas del componente, no son tokens.

   ÍNDICE
     0. Base y contenedor        8. Etiqueta de estado
     1. Botón                    9. Aviso
     2. Enlace                  10. Pestañas
     3. Campo de formulario     11. Hoja modal
     4. Tarjeta y flotante      12. Toast
     5. Sección                 13. Tabla
     6. Cabecera, pie y logo    14. Estado vacío
     7. Rótulo y pastilla       15. Esqueleto de carga
                                16. Foco y movimiento reducido
   ===================================================================== */

/* ---------------------------------------------------------------------
   0. BASE Y CONTENEDOR
   .ct-base va en <body> (o en un contenedor): fija tipografía, color y fondo.
   --------------------------------------------------------------------- */
.ct-base {
  margin: 0;
  background: var(--ct-fondo);
  color: var(--ct-texto);
  font-family: var(--ct-fuente-texto);
  font-size: var(--ct-tipo-cuerpo-tamano);
  font-weight: var(--ct-tipo-cuerpo-peso);
  line-height: var(--ct-tipo-cuerpo-interlinea);
  -webkit-font-smoothing: antialiased;
  -webkit-text-size-adjust: 100%;
  text-size-adjust: 100%;
}
.ct-base *,
.ct-base *::before,
.ct-base *::after { box-sizing: border-box; }

/* Los estilos de etiqueta (titulares, párrafos, imágenes) van dentro de :where() para que
   pesen cero: cualquier clase los gana. Así .ct-base no pisa al kit .g3- ni a otro
   componente cuando conviven en la misma página (una hoja de G3UI cuelga de <body>). */
:where(.ct-base) :where(h1, h2, h3, h4) {
  margin: 0;
  font-family: var(--ct-fuente-titular);
  font-weight: var(--ct-peso-titular);
  line-height: var(--ct-tipo-web-titular-interlinea);
  letter-spacing: var(--ct-tipo-web-titular-tracking);
  text-wrap: balance;
}
:where(.ct-base) :where(h1) {
  font-size: var(--ct-tipo-web-h1-tamano);
  letter-spacing: var(--ct-tipo-web-h1-tracking);
  line-height: var(--ct-tipo-web-h1-interlinea);
}
:where(.ct-base) :where(h2) { font-size: var(--ct-tipo-web-h2-tamano); letter-spacing: var(--ct-tipo-web-h2-tracking); }
:where(.ct-base) :where(h3) { font-size: var(--ct-tipo-web-h3-tamano); font-weight: var(--ct-tipo-web-h3-peso); letter-spacing: var(--ct-tipo-web-h3-tracking); }
:where(.ct-base) :where(h4) { font-size: var(--ct-tipo-web-h4-tamano); font-weight: var(--ct-tipo-web-h4-peso); letter-spacing: var(--ct-tipo-web-h4-tracking); }
:where(.ct-base) :where(p) { margin: 0; text-wrap: pretty; }
:where(.ct-base) :where(img) { max-width: 100%; height: auto; }
/* el atributo hidden manda siempre, también sobre un componente con display propio */
.ct-base [hidden] { display: none !important; }

/* Texto secundario y entradilla */
.ct-texto-suave { color: var(--ct-texto-suave); }
.ct-entradilla { font-size: var(--ct-tipo-interfaz-linea); color: var(--ct-texto-suave); max-width: 62ch; }

/* Contenedor de página. El ancho máximo es --ct-medida-contenedor (el --container-width de la web). */
.ct-contenedor {
  --_ancho-maximo: var(--ct-medida-contenedor);
  width: min(100% - (var(--ct-espacio-2) * 2), var(--_ancho-maximo));
  margin-inline: auto;
}

/* Solo para lectores de pantalla */
.ct-sr {
  position: absolute !important;
  width: 1px; height: 1px;
  margin: -1px; padding: 0;
  overflow: hidden;
  clip: rect(0 0 0 0);
  white-space: nowrap;
  border: 0;
}

/* Enlace «saltar al contenido»: fuera de la vista hasta que recibe el foco */
.ct-salto {
  position: absolute;
  inset-inline-start: var(--ct-espacio-2);
  top: var(--ct-espacio-1);
  z-index: var(--ct-z-toast);
  display: inline-flex;
  align-items: center;
  min-height: var(--ct-toque-minimo);
  padding: var(--ct-espacio-interfaz-3) var(--ct-espacio-interfaz-5);
  border-radius: var(--ct-radio-boton);
  background: var(--ct-primario-relleno);
  color: var(--ct-sobre-primario);
  font-weight: var(--ct-peso-texto-fuerte);
  text-decoration: none;
  transform: translateY(-200%);
}
.ct-salto:focus { transform: none; outline: var(--ct-foco-grosor) solid var(--ct-foco); outline-offset: var(--ct-foco-separacion); }

/* Iconos de trazo (estilo Lucide, 2 px). El color lo hereda del texto. */
.ct-icono {
  width: 1.25em; height: 1.25em;
  flex: 0 0 auto;
  fill: none;
  stroke: currentColor;
  stroke-width: 2;
  stroke-linecap: round;
  stroke-linejoin: round;
}

/* ---------------------------------------------------------------------
   1. BOTÓN
   .ct-boton + una variante: --primario · --secundario · --fantasma · --invertido
   Tamaños: --pequeno (44 px) · sin modificador (48 px) · --grande (62 px)
   Estados: hover · foco · pulsado · deshabilitado · cargando (aria-busy="true")
   --------------------------------------------------------------------- */
.ct-boton {
  --_fondo: transparent;
  --_fondo-hover: var(--ct-primario-suave);
  --_texto: var(--ct-primario-texto);
  --_borde: transparent;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: var(--ct-espacio-interfaz-3);
  min-height: var(--ct-toque-fila);
  padding: 0 var(--ct-espacio-interfaz-6);
  border: 2px solid var(--_borde);
  border-radius: var(--ct-radio-boton);
  background: var(--_fondo);
  color: var(--_texto);
  font-family: var(--ct-fuente-texto);
  font-size: var(--ct-tipo-cuerpo-tamano);
  font-weight: var(--ct-peso-texto-fuerte);
  line-height: 1.2;
  text-align: center;
  text-decoration: none;
  cursor: pointer;
  -webkit-tap-highlight-color: transparent;
  transition: transform var(--ct-dur-pulsacion) var(--ct-curva-estado);
}
.ct-boton--primario {
  --_fondo: var(--ct-primario-relleno);
  --_fondo-hover: var(--ct-primario-relleno-hover);
  --_texto: var(--ct-sobre-primario);
}
.ct-boton--secundario { --_borde: var(--ct-primario); }
.ct-boton--fantasma { --_borde: transparent; }
/* Invertido: el CTA sobre la superficie verde. Blanco con texto tinta. Nunca amarillo. */
.ct-boton--invertido,
.ct-superficie-verde .ct-boton--primario {
  --_fondo: var(--ct-superficie-verde-tarjeta-fondo);
  --_fondo-hover: var(--ct-fondo-arena);
  --_texto: var(--ct-superficie-verde-tarjeta-texto);
  box-shadow: var(--ct-relieve-tarjeta);
}
/* Secundario y fantasma sobre verde: texto del titular de la superficie, velo claro al pasar */
.ct-superficie-verde .ct-boton--secundario,
.ct-superficie-verde .ct-boton--fantasma {
  --_texto: var(--ct-superficie-verde-titular);
  --_fondo-hover: color-mix(in srgb, var(--ct-superficie-verde-titular) 14%, transparent);
}
.ct-superficie-verde .ct-boton--secundario {
  --_borde: color-mix(in srgb, var(--ct-superficie-verde-titular) 60%, transparent);
}

/* tamaños */
.ct-boton--pequeno {
  min-height: var(--ct-toque-minimo);
  padding-inline: var(--ct-espacio-interfaz-5);
  font-size: var(--ct-tipo-interfaz-boton);
}
.ct-boton--grande {
  min-height: var(--ct-toque-accion);
  font-size: var(--ct-tipo-interfaz-linea);
}
.ct-boton--ancho { width: 100%; }
/* solo icono: cuadrado del tamaño del toque; necesita aria-label */
.ct-boton--icono { width: var(--ct-toque-fila); padding: 0; }
.ct-boton--icono.ct-boton--pequeno { width: var(--ct-toque-minimo); }

/* estados */
@media (hover: hover) {
  .ct-boton:hover:not(:disabled, [aria-disabled="true"], [aria-busy="true"]) { background: var(--_fondo-hover); }
}
.ct-boton.is-hover { background: var(--_fondo-hover); }
.ct-boton:active:not(:disabled, [aria-disabled="true"]),
.ct-boton.is-activo {
  background: var(--_fondo-hover);
  transform: scale(var(--ct-pulsacion-escala));
}
.ct-boton:disabled,
.ct-boton[aria-disabled="true"] {
  opacity: var(--ct-opacidad-deshabilitado);
  cursor: not-allowed;
}
/* cargando: el texto se queda y dice qué pasa («Enviando…»); delante gira un anillo */
.ct-boton[aria-busy="true"] { cursor: progress; }
.ct-boton[aria-busy="true"]::before {
  content: "";
  width: 1em; height: 1em;
  flex: 0 0 auto;
  border: 2px solid currentColor;
  border-inline-end-color: transparent;
  border-radius: 50%;
  /* una vuelta dura --ct-dur-giro y va a ritmo constante (--ct-curva-lineal) */
  animation: ct-gira var(--ct-dur-giro) var(--ct-curva-lineal) infinite;
}
@keyframes ct-gira { to { transform: rotate(360deg); } }

/* grupo de botones: se apilan a todo el ancho en móvil */
.ct-botones { display: flex; flex-wrap: wrap; gap: var(--ct-espacio-interfaz-4); align-items: center; }
@media (max-width: 480px) {
  .ct-botones--apila > .ct-boton { width: 100%; }
}

/* ---------------------------------------------------------------------
   2. ENLACE
   Verde de texto (--ct-primario-texto), siempre subrayado. Nunca amarillo.
   --------------------------------------------------------------------- */
.ct-enlace {
  color: var(--ct-primario-texto);
  font-weight: var(--ct-peso-texto-medio);
  text-decoration: underline;
  text-decoration-thickness: 1px;
  text-underline-offset: 0.2em;
  cursor: pointer;
}
button.ct-enlace { padding: 0; border: 0; background: none; font: inherit; font-weight: var(--ct-peso-texto-medio); }
@media (hover: hover) { .ct-enlace:hover { text-decoration-thickness: 2px; } }
.ct-enlace.is-hover { text-decoration-thickness: 2px; }
/* enlace suelto (fuera de un párrafo): área táctil de 44 px */
.ct-enlace--suelto {
  display: inline-flex;
  align-items: center;
  gap: var(--ct-espacio-interfaz-2);
  min-height: var(--ct-toque-minimo);
}
.ct-enlace--suelto .ct-icono { transition: transform var(--ct-dur-base) var(--ct-curva-entrada); }
@media (hover: hover) {
  .ct-enlace--suelto:hover .ct-icono { transform: translateX(var(--ct-dist-s)); }
}
.ct-superficie-verde .ct-enlace { color: var(--ct-superficie-verde-titular); }

/* ---------------------------------------------------------------------
   3. CAMPO DE FORMULARIO
   <div class="ct-campo"> etiqueta + control + ayuda + error </div>
   El error se marca con aria-invalid="true" en el control y se explica en
   .ct-campo__error (texto e icono: nunca solo color).
   --------------------------------------------------------------------- */
.ct-campo { display: grid; gap: var(--ct-espacio-interfaz-2); min-width: 0; }
.ct-campo__etiqueta {
  font-size: var(--ct-tipo-interfaz-cuerpo);
  font-weight: var(--ct-peso-texto-fuerte);
  color: var(--ct-texto);
}
.ct-campo__opcional { font-weight: var(--ct-peso-texto); color: var(--ct-texto-suave); }
.ct-campo__control {
  width: 100%;
  min-height: var(--ct-toque-fila);
  padding: var(--ct-espacio-interfaz-3) var(--ct-espacio-interfaz-4);
  border: 1.5px solid var(--ct-texto-suave);   /* 10,37:1 sobre blanco: el borde de un control necesita 3:1 */
  border-radius: var(--ct-radio-fila);
  background: var(--ct-superficie);
  color: var(--ct-texto);
  font-family: var(--ct-fuente-texto);
  font-size: var(--ct-tipo-cuerpo-tamano);   /* 16 px: evita el zoom de iOS */
  line-height: 1.4;
}
textarea.ct-campo__control { min-height: calc(var(--ct-toque-fila) * 2); resize: vertical; }
.ct-campo__control::placeholder { color: var(--ct-texto-suave); opacity: 1; }
.ct-campo__control:focus-visible,
.ct-campo__control.is-foco { border-color: var(--ct-primario); }
.ct-campo__control[aria-invalid="true"] { border-color: var(--ct-peligro); border-width: 2px; }
.ct-campo__control:disabled {
  background: var(--ct-fondo-alterno);
  opacity: var(--ct-opacidad-deshabilitado);
  cursor: not-allowed;
}
.ct-campo__ayuda { font-size: var(--ct-tipo-interfaz-chip); color: var(--ct-texto-suave); }
.ct-campo__error {
  display: flex;
  align-items: flex-start;
  gap: var(--ct-espacio-interfaz-2);
  font-size: var(--ct-tipo-interfaz-chip);
  font-weight: var(--ct-peso-texto-fuerte);
  color: var(--ct-peligro);
}
.ct-campo__error:empty { display: none; }
.ct-campo__error .ct-icono { margin-top: 0.1em; }

/* casilla y opción: el <label> entero da el toque de 44 px */
.ct-casilla {
  display: flex;
  align-items: center;
  gap: var(--ct-espacio-interfaz-4);
  min-height: var(--ct-toque-minimo);
  font-size: var(--ct-tipo-cuerpo-tamano);
  cursor: pointer;
}
.ct-casilla input {
  width: var(--ct-espacio-interfaz-6);
  height: var(--ct-espacio-interfaz-6);
  flex: 0 0 auto;
  margin: 0;
  accent-color: var(--ct-primario-relleno);
}
/* Sobre la superficie verde un formulario va siempre dentro de una .ct-tarjeta-flotante */

/* ---------------------------------------------------------------------
   4. TARJETA Y TARJETA FLOTANTE
   .ct-tarjeta: contenido agrupado sobre claro.
   .ct-tarjeta.ct-tarjeta-flotante: la misma estructura con el aspecto de la
   utilidad generada (tarjeta clara despegada de la superficie verde o de foto).
   --------------------------------------------------------------------- */
.ct-tarjeta {
  display: flex;
  flex-direction: column;
  gap: var(--ct-espacio-interfaz-4);
  min-width: 0;
  padding: var(--ct-espacio-interfaz-6);
  border: 1px solid var(--ct-borde);
  border-radius: var(--ct-radio-tarjeta);
  background: var(--ct-superficie);
  color: var(--ct-texto);
  box-shadow: var(--ct-sombra-suave);
}
.ct-tarjeta--plana { box-shadow: none; }
.ct-base .ct-tarjeta__medio,
.ct-tarjeta__medio {
  display: block;
  width: calc(100% + (var(--ct-espacio-interfaz-6) * 2));
  max-width: none;
  height: auto;
  margin: calc(var(--ct-espacio-interfaz-6) * -1) calc(var(--ct-espacio-interfaz-6) * -1) 0;
  aspect-ratio: 16 / 9;
  object-fit: cover;
  border-radius: calc(var(--ct-radio-tarjeta) - 1px) calc(var(--ct-radio-tarjeta) - 1px) 0 0;
  background: var(--ct-fondo-alterno);
}
.ct-base .ct-tarjeta__titulo,
.ct-tarjeta__titulo {
  margin: 0;
  font-family: var(--ct-fuente-titular);
  font-size: var(--ct-tipo-titulo-3-tamano);
  font-weight: var(--ct-tipo-titulo-3-peso);
  line-height: 1.2;
}
.ct-tarjeta__texto { margin: 0; color: var(--ct-texto-suave); }
.ct-tarjeta__pie {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--ct-espacio-interfaz-4);
  margin-top: auto;
  padding-top: var(--ct-espacio-interfaz-3);
}
/* tarjeta entera pulsable: el enlace del título cubre la tarjeta */
.ct-tarjeta--enlace { position: relative; transition: transform var(--ct-dur-base) var(--ct-curva-entrada); }
.ct-tarjeta--enlace .ct-tarjeta__titulo a { color: inherit; text-decoration: none; }
.ct-tarjeta--enlace .ct-tarjeta__titulo a::after { content: ""; position: absolute; inset: 0; border-radius: inherit; }
@media (hover: hover) {
  .ct-tarjeta--enlace:hover { transform: translateY(calc(var(--ct-dist-s) * -1)); box-shadow: var(--ct-sombra-media); }
}
.ct-tarjeta--enlace.is-hover { transform: translateY(calc(var(--ct-dist-s) * -1)); box-shadow: var(--ct-sombra-media); }
.ct-tarjeta--enlace:has(a:focus-visible) { outline: var(--ct-foco-grosor) solid var(--ct-foco); outline-offset: var(--ct-foco-separacion); }
.ct-tarjeta--enlace .ct-tarjeta__titulo a:focus-visible { outline: none; }

/* flotante: compone la utilidad generada. Dentro, los roles vuelven a los de claro:
   la tarjeta es blanca aunque la página esté en tema oscuro. */
.ct-tarjeta.ct-tarjeta-flotante {
  border-color: transparent;
  background: var(--ct-superficie-verde-tarjeta-fondo);
  color: var(--ct-superficie-verde-tarjeta-texto);
  box-shadow: var(--ct-relieve-tarjeta);
}
.ct-tarjeta-flotante :is(h1, h2, h3, h4, h5, h6),
.ct-superficie-verde .ct-tarjeta-flotante :is(h1, h2, h3, h4, h5, h6) { color: var(--ct-superficie-verde-tarjeta-texto); }
.ct-tarjeta-flotante .ct-tarjeta__texto { color: var(--ct-tinta-intensa-2); }
/* En tema oscuro la flotante sigue siendo blanca: dentro, los roles vuelven a los primitivos
   de claro para que un campo, un enlace o una tabla no salgan en texto claro sobre blanco.
   No se inventa ningún valor: son los mismos primitivos que usa :root. */
[data-ct-tema="oscuro"] .ct-tarjeta-flotante {
  --ct-fondo: var(--ct-gris-blanco);
  --ct-fondo-suave: var(--ct-arena-50);
  --ct-fondo-alterno: var(--ct-arena-100);
  --ct-superficie: var(--ct-gris-blanco);
  --ct-texto: var(--ct-tinta-intensa);
  --ct-texto-suave: var(--ct-tinta-intensa-2);
  --ct-linea: var(--ct-tinta-4);
  --ct-borde: var(--ct-gris-apoyo-3);
  --ct-primario: var(--ct-verde-500);
  --ct-primario-texto: var(--ct-verde-600);
  --ct-primario-suave: var(--ct-verde-100);
  --ct-foco: var(--ct-verde-500);
  --ct-peligro: var(--ct-panel-critico);
}
/* Lo que va DENTRO de la flotante está sobre blanco, no sobre verde: botón, enlace y
   rótulo vuelven a su aspecto de claro aunque la tarjeta esté en una superficie verde
   o en una página en tema oscuro. */
.ct-superficie-verde .ct-tarjeta-flotante .ct-boton--primario {
  --_fondo: var(--ct-primario-relleno);
  --_fondo-hover: var(--ct-primario-relleno-hover);
  --_texto: var(--ct-sobre-primario);
  box-shadow: none;
}
.ct-superficie-verde .ct-tarjeta-flotante :is(.ct-boton--secundario, .ct-boton--fantasma) {
  --_texto: var(--ct-verde-600);
  --_fondo-hover: var(--ct-verde-100);
}
.ct-superficie-verde .ct-tarjeta-flotante .ct-boton--secundario { --_borde: var(--ct-verde-500); }
.ct-superficie-verde .ct-tarjeta-flotante .ct-enlace { color: var(--ct-verde-600); }
.ct-superficie-verde .ct-tarjeta-flotante .ct-rotulo,
[data-ct-tema="oscuro"] .ct-tarjeta-flotante .ct-rotulo { color: var(--ct-rotulo-color); }
.ct-superficie-verde .ct-tarjeta-flotante .ct-rotulo::before,
[data-ct-tema="oscuro"] .ct-tarjeta-flotante .ct-rotulo::before { background: var(--ct-rotulo-guion); }
/* logos de terceros: siempre en tarjeta flotante y sin tocar sus colores */
.ct-tarjeta-flotante--logos {
  display: flex;
  flex-wrap: wrap;
  flex-direction: row;
  align-items: center;
  justify-content: center;
  gap: var(--ct-espacio-interfaz-6);
}

/* ---------------------------------------------------------------------
   5. SECCIÓN
   .ct-seccion (clara) · --suave · --alterna · --arena · y la verde, que se
   compone: <section class="ct-seccion ct-superficie-verde">
   --------------------------------------------------------------------- */
/* background-color y no background: el atajo borraría el degradado de .ct-superficie-verde */
.ct-seccion { padding-block: var(--ct-espacio-10); background-color: var(--ct-fondo); color: var(--ct-texto); }
.ct-seccion--ajustada { padding-block: var(--ct-espacio-7); }
.ct-seccion--suave { background-color: var(--ct-fondo-suave); }
.ct-seccion--alterna { background-color: var(--ct-fondo-alterno); }
.ct-seccion--arena { background-color: var(--ct-fondo-arena); }
/* El tema oscuro no redefine --ct-fondo-arena (DESIGN.md §13): con el texto claro encima
   daría 1,07:1. Hasta que exista ese token, la sección arena usa la superficie oscura. */
[data-ct-tema="oscuro"] .ct-seccion--arena { background-color: var(--ct-superficie); }
/* Verde: el fondo y el color del texto los pone .ct-superficie-verde. Más aire abajo,
   para que el texto se quede en la zona alta y media, donde pasa AA (DESIGN.md §3). */
.ct-seccion.ct-superficie-verde {
  padding-block: var(--ct-espacio-8) var(--ct-espacio-12);
  background-color: var(--ct-superficie-verde-base);
  color: var(--ct-superficie-verde-texto);
}
.ct-seccion__cabecera {
  display: grid;
  justify-items: start;
  gap: var(--ct-espacio-interfaz-4);
  max-width: 68ch;
  margin-bottom: var(--ct-espacio-interfaz-6);
}
.ct-seccion__cabecera--centro { justify-items: center; text-align: center; margin-inline: auto; }
.ct-seccion__texto { color: var(--ct-texto-suave); font-size: var(--ct-tipo-interfaz-linea); }
.ct-superficie-verde .ct-seccion__texto { color: var(--ct-superficie-verde-texto); }
@media (max-width: 720px) {
  .ct-seccion { padding-block: var(--ct-espacio-7); }
  .ct-seccion.ct-superficie-verde { padding-block: var(--ct-espacio-7) var(--ct-espacio-10); }
}
/* rejilla de tarjetas dentro de una sección */
.ct-rejilla {
  --_minimo: 260px;
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(min(100%, var(--_minimo)), 1fr));
  gap: var(--ct-espacio-interfaz-5);
}

/* ---------------------------------------------------------------------
   6. CABECERA, PIE Y LOGOTIPO
   El logotipo es SIEMPRE el SVG maestro en un <img>, nunca texto ni un filtro CSS.
   Va plano en cabecera y pie. Dos versiones vectoriales, las dos en activos\logo\:
     <a class="ct-logo" href="…">
       <img class="ct-logo__color"  src="…/clotitec-logo.svg"        alt="Clotitec">
       <img class="ct-logo__blanco" src="…/clotitec-logo-blanco.svg" alt="Clotitec">
     </a>
   Sobre claro se ve la de color; en tema oscuro y sobre la superficie verde, la blanca.
   Si solo se pone la de color, en oscuro y sobre verde recibe una placa clara para
   no perder contraste.
   --------------------------------------------------------------------- */
.ct-logo {
  display: inline-flex;
  align-items: center;
  flex: 0 0 auto;
  min-height: var(--ct-toque-minimo);
  border-radius: var(--ct-radio-fila);
  text-decoration: none;
  color: var(--ct-texto);
  font-family: var(--ct-fuente-titular);
  font-weight: var(--ct-peso-titular);
}
.ct-logo img { display: block; height: calc(var(--ct-espacio-1) * 5); width: auto; }   /* 40 px, como la cabecera de la web */
.ct-logo--pequeno img { height: calc(var(--ct-espacio-1) * 4); }                       /* 32 px, como el pie de la web */
.ct-logo__blanco { display: none !important; }
[data-ct-tema="oscuro"] .ct-logo:has(.ct-logo__blanco) .ct-logo__color,
.ct-superficie-verde .ct-logo:has(.ct-logo__blanco) .ct-logo__color { display: none; }
[data-ct-tema="oscuro"] .ct-logo .ct-logo__blanco,
.ct-superficie-verde .ct-logo .ct-logo__blanco { display: block !important; }
/* dentro de una tarjeta flotante (blanca) vuelve la de color, también en oscuro */
.ct-tarjeta-flotante .ct-logo:has(.ct-logo__blanco) .ct-logo__color { display: block; }
.ct-tarjeta-flotante .ct-logo .ct-logo__blanco { display: none !important; }
/* sin versión blanca: placa clara */
[data-ct-tema="oscuro"] .ct-logo:not(:has(.ct-logo__blanco)),
.ct-superficie-verde .ct-logo:not(:has(.ct-logo__blanco)) {
  padding: var(--ct-espacio-interfaz-1) var(--ct-espacio-interfaz-4);
  background: var(--ct-superficie-verde-tarjeta-fondo);
}
.ct-tarjeta-flotante .ct-logo:not(:has(.ct-logo__blanco)) { padding: 0; background: none; }

.ct-cabecera {
  position: sticky;
  top: 0;
  z-index: var(--ct-z-barra);
  background: var(--ct-fondo);
  border-bottom: 1px solid var(--ct-linea);
  color: var(--ct-texto);
}
.ct-cabecera--estatica { position: static; }
.ct-cabecera__fila {
  display: flex;
  align-items: center;
  gap: var(--ct-espacio-interfaz-5);
  min-height: var(--ct-espacio-11);          /* 88 px: el alto de cabecera de la web */
}
.ct-cabecera__nav {
  display: flex;
  flex-wrap: wrap;
  justify-content: flex-end;
  align-items: center;
  gap: var(--ct-espacio-interfaz-1);
  margin-inline-start: auto;
}
.ct-cabecera__nav a {
  display: inline-flex;
  align-items: center;
  min-height: var(--ct-toque-minimo);
  padding: 0 var(--ct-espacio-interfaz-4);
  border-radius: var(--ct-radio-fila);
  color: var(--ct-texto);
  font-size: var(--ct-tipo-interfaz-cuerpo);
  font-weight: var(--ct-peso-texto-medio);
  text-decoration: none;
  white-space: nowrap;
}
@media (hover: hover) { .ct-cabecera__nav a:hover { background: var(--ct-primario-suave); } }
.ct-cabecera__nav a.is-hover { background: var(--ct-primario-suave); }
.ct-cabecera__nav a[aria-current="page"] {
  color: var(--ct-primario-texto);
  font-weight: var(--ct-peso-texto-fuerte);
  background: var(--ct-primario-suave);
}
.ct-cabecera__menu { display: none; margin-inline-start: auto; }
/* En estrecho la navegación pasa a un panel bajo la cabecera. Solo se oculta si hay
   JavaScript (clase .ct-js en <html>): sin él, los enlaces quedan a la vista. */
@media (max-width: 900px) {
  .ct-cabecera__fila { flex-wrap: wrap; min-height: var(--ct-espacio-8); padding-block: var(--ct-espacio-interfaz-3); }
  .ct-cabecera__nav {
    order: 3;
    flex-basis: 100%;
    flex-direction: column;
    align-items: stretch;
    margin: 0;
    padding-bottom: var(--ct-espacio-interfaz-3);
  }
  .ct-cabecera__accion { order: 4; flex-basis: 100%; margin-bottom: var(--ct-espacio-interfaz-4); }
  .ct-js .ct-cabecera__menu { display: inline-flex; }
  .ct-js .ct-cabecera__menu[aria-expanded="false"] ~ .ct-cabecera__nav,
  .ct-js .ct-cabecera__menu[aria-expanded="false"] ~ .ct-cabecera__accion { display: none; }
  .ct-js .ct-cabecera__menu[aria-expanded="true"] ~ .ct-cabecera__nav { animation: ct-entra-baja var(--ct-dur-rapida) var(--ct-curva-entrada) both; }
}

.ct-pie {
  padding-block: var(--ct-espacio-7) var(--ct-espacio-interfaz-6);
  background: var(--ct-fondo-alterno);
  border-top: 1px solid var(--ct-linea);
  color: var(--ct-texto);
  font-size: var(--ct-tipo-interfaz-cuerpo);
}
.ct-pie__rejilla {
  display: grid;
  grid-template-columns: minmax(0, 1.4fr) repeat(auto-fit, minmax(150px, 1fr));
  gap: var(--ct-espacio-interfaz-6);
}
.ct-pie__marca { display: grid; gap: var(--ct-espacio-interfaz-4); align-content: start; justify-items: start; max-width: 38ch; color: var(--ct-texto-suave); }
.ct-base .ct-pie__titulo,
.ct-pie__titulo {
  margin: 0 0 var(--ct-espacio-interfaz-3);
  font-family: var(--ct-fuente-texto);
  font-size: var(--ct-tipo-etiqueta-tamano);
  font-weight: var(--ct-tipo-etiqueta-peso);
  letter-spacing: var(--ct-tipo-etiqueta-tracking);
  line-height: 1.3;
  text-transform: uppercase;
  color: var(--ct-texto-suave);
}
.ct-pie__lista { margin: 0; padding: 0; list-style: none; }
.ct-pie__lista a {
  display: flex;
  align-items: center;
  min-height: var(--ct-toque-minimo);
  color: var(--ct-texto);
  text-decoration: none;
}
@media (hover: hover) { .ct-pie__lista a:hover { text-decoration: underline; text-underline-offset: 0.2em; } }
.ct-pie__legal {
  display: flex;
  flex-wrap: wrap;
  justify-content: space-between;
  gap: var(--ct-espacio-interfaz-3) var(--ct-espacio-interfaz-6);
  margin-top: var(--ct-espacio-interfaz-6);
  padding-top: var(--ct-espacio-interfaz-5);
  border-top: 1px solid var(--ct-linea);
  color: var(--ct-texto-suave);
  font-size: var(--ct-tipo-interfaz-chip);
}
.ct-pie__legal > * { display: inline-flex; flex-wrap: wrap; align-items: center; gap: var(--ct-espacio-interfaz-3); min-height: var(--ct-toque-minimo); }
.ct-pie__legal .ct-enlace { display: inline-flex; align-items: center; min-height: var(--ct-toque-minimo); }
@media (max-width: 720px) {
  .ct-pie__rejilla { grid-template-columns: 1fr 1fr; }
  .ct-pie__marca { grid-column: 1 / -1; }
}

/* ---------------------------------------------------------------------
   7. RÓTULO Y PASTILLA
   Las dos son utilidades generadas (css/clotitec.css). Aquí no se redefinen.
     <span class="ct-rotulo">Turismo municipal</span>
     <span class="ct-pastilla">Nuevo</span>
   · Rótulo: verde sobre claro; amarillo sobre oscuro, foto o la mitad alta de la verde.
   · Pastilla: fondo de acento con su texto encima. Nunca es un botón ni un enlace.
   · Un golpe de amarillo por bloque: si hay pastilla, el titular no lleva .ct-destacado.
   --------------------------------------------------------------------- */

/* El subrayado en tema oscuro. La utilidad generada pinta una banda amarilla clara
   (--ct-acento-suave) que el tema oscuro no redefine: con el titular claro encima da
   1,13:1 (DESIGN.md §13). Hasta que los tokens lo resuelvan, en oscuro el subrayado
   pasa a ser texto en el amarillo de marca, que sobre oscuro sí está permitido (12,26:1).
   Apuntado en FALTAN-TOKENS.md. */
[data-ct-tema="oscuro"] .ct-destacado {
  background: none;
  padding-inline: 0;
  color: var(--ct-rotulo-color-sobre-oscuro);
}
[data-ct-tema="oscuro"] .ct-tarjeta-flotante .ct-destacado { color: inherit; }

/* ---------------------------------------------------------------------
   8. ETIQUETA DE ESTADO
   .ct-estado + --ok · --aviso · --critico · --neutro
   Punto de color + texto. El texto siempre dice el estado: nunca solo color.
   El texto de «aviso» no usa --ct-estado-aviso-texto: sobre su fondo da 4,26:1
   y no pasa AA a 12 px. Se usa la tinta del estado neutro (17,14:1).
   --------------------------------------------------------------------- */
.ct-estado {
  --_fondo: var(--ct-estado-neutro-fondo);
  --_texto: var(--ct-estado-neutro-texto);
  --_punto: var(--ct-estado-neutro-texto);
  display: inline-flex;
  align-items: center;
  gap: var(--ct-espacio-interfaz-2);
  padding: var(--ct-espacio-interfaz-1) var(--ct-espacio-interfaz-3);
  border-radius: var(--ct-radio-pildora);
  background: var(--_fondo);
  color: var(--_texto);
  font-family: var(--ct-fuente-texto);
  font-size: var(--ct-tipo-interfaz-nota);
  font-weight: var(--ct-peso-texto-fuerte);
  line-height: 1.3;
  white-space: nowrap;
}
.ct-estado::before {
  content: "";
  width: var(--ct-espacio-interfaz-3);
  height: var(--ct-espacio-interfaz-3);
  flex: 0 0 auto;
  border-radius: 50%;
  background: var(--_punto);
}
.ct-estado--ok { --_fondo: var(--ct-estado-ok-fondo); --_texto: var(--ct-estado-ok-texto); --_punto: var(--ct-estado-ok-texto); }
.ct-estado--aviso { --_fondo: var(--ct-estado-aviso-fondo); --_texto: var(--ct-estado-neutro-texto); --_punto: var(--ct-estado-aviso-texto); }
.ct-estado--critico { --_fondo: var(--ct-estado-critico-fondo); --_texto: var(--ct-estado-critico-texto); --_punto: var(--ct-estado-critico-texto); }
.ct-estado--neutro { --_fondo: var(--ct-estado-neutro-fondo); --_texto: var(--ct-estado-neutro-texto); --_punto: var(--ct-estado-neutro-texto); }
.ct-estado--sin-punto::before { display: none; }

/* ---------------------------------------------------------------------
   9. AVISO
   Bloque de mensaje dentro del contenido: filo izquierdo + fondo de estado.
   Sin modificador = informativo (fondo suave con borde, filo primario). --ok · --aviso · --critico.
   role="status" (informa) o role="alert" (interrumpe) lo decide quien lo usa.
   --------------------------------------------------------------------- */
.ct-aviso {
  --_fondo: var(--ct-fondo-suave);
  --_filo: var(--ct-primario);
  --_texto: var(--ct-texto);
  --_borde: var(--ct-borde);
  display: flex;
  align-items: flex-start;
  gap: var(--ct-espacio-interfaz-4);
  padding: var(--ct-espacio-interfaz-4) var(--ct-espacio-interfaz-5);
  border: 1px solid var(--_borde);
  border-inline-start: var(--ct-espacio-interfaz-1) solid var(--_filo);
  border-radius: var(--ct-radio-fila);
  background: var(--_fondo);
  color: var(--_texto);
  font-size: var(--ct-tipo-interfaz-cuerpo);
}
.ct-aviso > .ct-icono { margin-top: 0.15em; color: var(--_filo); }
.ct-aviso__cuerpo { flex: 1 1 auto; min-width: 0; }
.ct-aviso__titulo { display: block; font-weight: var(--ct-peso-texto-fuerte); }
.ct-aviso__texto { margin: 0; }
.ct-aviso--ok { --_fondo: var(--ct-estado-ok-fondo); --_filo: var(--ct-estado-ok-texto); --_texto: var(--ct-estado-neutro-texto); --_borde: transparent; }
.ct-aviso--aviso { --_fondo: var(--ct-estado-aviso-fondo); --_filo: var(--ct-estado-aviso-texto); --_texto: var(--ct-estado-neutro-texto); --_borde: transparent; }
.ct-aviso--critico { --_fondo: var(--ct-estado-critico-fondo); --_filo: var(--ct-estado-critico-texto); --_texto: var(--ct-estado-neutro-texto); --_borde: transparent; }
.ct-aviso .ct-enlace { color: inherit; }

/* ---------------------------------------------------------------------
   10. PESTAÑAS
   <div class="ct-pestanas" role="tablist"> <button role="tab" aria-selected> …
   La activa lleva el relleno primario (texto blanco). El script da las flechas.
   --------------------------------------------------------------------- */
.ct-pestanas {
  display: inline-flex;
  flex-wrap: wrap;
  gap: var(--ct-espacio-interfaz-1);
  width: fit-content;
  max-width: 100%;
  padding: var(--ct-espacio-interfaz-1);
  border-radius: var(--ct-radio-tarjeta);
  background: var(--ct-fondo-alterno);
  border: 1px solid var(--ct-borde);
}
.ct-pestanas--bloque { display: flex; width: auto; }
.ct-pestanas--bloque > .ct-pestana { flex: 1 1 0; }
.ct-pestana {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: var(--ct-espacio-interfaz-2);
  min-height: var(--ct-toque-minimo);
  padding: 0 var(--ct-espacio-interfaz-5);
  border: 0;
  border-radius: var(--ct-radio-boton);
  background: none;
  color: var(--ct-texto);
  font-family: var(--ct-fuente-texto);
  font-size: var(--ct-tipo-interfaz-cuerpo);
  font-weight: var(--ct-peso-texto-fuerte);
  white-space: nowrap;
  cursor: pointer;
  text-decoration: none;
}
@media (hover: hover) {
  .ct-pestana:hover:not([aria-selected="true"], [aria-pressed="true"], [aria-current="page"], :disabled) { background: var(--ct-primario-suave); }
}
.ct-pestana.is-hover { background: var(--ct-primario-suave); }
.ct-pestana[aria-selected="true"],
.ct-pestana[aria-pressed="true"],
.ct-pestana[aria-current="page"] { background: var(--ct-primario-relleno); color: var(--ct-sobre-primario); }
.ct-pestana:disabled { opacity: var(--ct-opacidad-deshabilitado); cursor: not-allowed; }
.ct-pestanas__panel { padding-top: var(--ct-espacio-interfaz-5); }
.ct-pestanas__panel[hidden] { display: none; }

/* ---------------------------------------------------------------------
   11. HOJA MODAL
   Sobre el elemento nativo <dialog>: el navegador atrapa el foco, cierra con
   Esc y devuelve el foco. Centrada en escritorio; hoja inferior en móvil.
     <dialog class="ct-hoja" aria-labelledby="…">
   .ct-hoja--muestra la enseña quieta dentro de la página (galería).
   --------------------------------------------------------------------- */
.ct-hoja {
  width: min(var(--ct-medida-hoja), 100% - (var(--ct-espacio-2) * 2));
  max-height: calc(100dvh - (var(--ct-espacio-2) * 2));
  padding: 0;
  border: 0;
  border-radius: var(--ct-radio-hoja);
  background: var(--ct-superficie);
  color: var(--ct-texto);
  box-shadow: var(--ct-sombra-elevada);
  overflow: hidden;
}
.ct-hoja[open] { display: flex; flex-direction: column; animation: ct-entra-sube var(--ct-dur-hoja) var(--ct-curva-entrada) both; }
.ct-hoja::backdrop {
  background: var(--ct-velo-fondo);
}
.ct-hoja__cabecera {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--ct-espacio-interfaz-4);
  padding: var(--ct-espacio-interfaz-5) var(--ct-espacio-interfaz-5) 0 var(--ct-espacio-interfaz-6);
}
.ct-base .ct-hoja__titulo,
.ct-hoja__titulo {
  margin: 0;
  font-family: var(--ct-fuente-titular);
  font-size: var(--ct-tipo-titulo-3-tamano);
  font-weight: var(--ct-peso-titular);
  line-height: 1.2;
}
.ct-hoja__cuerpo {
  flex: 1 1 auto;
  min-height: 0;
  overflow-y: auto;
  overscroll-behavior: contain;
  display: grid;
  gap: var(--ct-espacio-interfaz-5);
  padding: var(--ct-espacio-interfaz-5) var(--ct-espacio-interfaz-6);
}
.ct-hoja__pie {
  display: flex;
  flex-wrap: wrap;
  justify-content: flex-end;
  gap: var(--ct-espacio-interfaz-4);
  padding: 0 var(--ct-espacio-interfaz-6) var(--ct-espacio-interfaz-6);
}
@media (max-width: 720px), (max-height: 500px) {
  .ct-hoja:not(.ct-hoja--muestra) {
    width: 100%;
    max-width: 100%;
    max-height: 88dvh;
    margin: auto 0 0;
    border-radius: var(--ct-radio-hoja) var(--ct-radio-hoja) 0 0;
    padding-bottom: env(safe-area-inset-bottom, 0px);
  }
  .ct-hoja[open]:not(.ct-hoja--muestra) { animation-name: ct-entra-sube-hoja; }
  .ct-hoja__pie > .ct-boton { flex: 1 1 auto; }
}
.ct-hoja--muestra {
  position: static;
  display: flex;
  flex-direction: column;
  width: min(var(--ct-medida-hoja), 100%);
  margin: 0;
  border: 1px solid var(--ct-borde);
}

/* ---------------------------------------------------------------------
   12. TOAST
   Aviso breve que se va solo (--ct-dur-permanencia-aviso). role="status".
   Lo crea CTUI.toast('texto'); abajo y centrado, por encima de todo.
   --------------------------------------------------------------------- */
.ct-toast-zona {
  position: fixed;
  z-index: var(--ct-z-toast);
  inset: auto var(--ct-espacio-2) calc(env(safe-area-inset-bottom, 0px) + var(--ct-espacio-interfaz-6));
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: var(--ct-espacio-interfaz-3);
  pointer-events: none;
}
.ct-toast {
  display: inline-flex;
  align-items: center;
  gap: var(--ct-espacio-interfaz-3);
  max-width: 100%;
  min-height: var(--ct-toque-minimo);
  padding: var(--ct-espacio-interfaz-3) var(--ct-espacio-interfaz-6);
  border: 1px solid var(--ct-primario);
  border-radius: var(--ct-radio-pildora);
  background: var(--ct-primario-relleno);
  color: var(--ct-sobre-primario);
  font-family: var(--ct-fuente-texto);
  font-size: var(--ct-tipo-interfaz-cuerpo);
  font-weight: var(--ct-peso-texto-fuerte);
  line-height: 1.3;
  box-shadow: var(--ct-sombra-media);
  pointer-events: auto;
  animation: ct-entra-sube var(--ct-dur-hoja) var(--ct-curva-entrada) both;
}
.ct-toast--sale { animation: ct-sale-sube var(--ct-dur-hoja) var(--ct-curva-entrada) both; }
.ct-toast--muestra { animation: none; }

/* ---------------------------------------------------------------------
   13. TABLA
   <div class="ct-tabla-marco" role="region" aria-label="…" tabindex="0">
     <table class="ct-tabla"> … </table></div>
   El marco es el que se desplaza en horizontal, nunca la página.
   · Pista de desplazamiento: cuando la tabla no cabe, el borde por el que sigue se
     difumina hacia el fondo. El script pone data-ct-sigue="inicio", "fin" o los dos
     en el marco (CTUI.pista); sin script la tabla se desplaza igual, sin pista.
   · .ct-tabla--fija: en 720 px o menos, la primera columna se queda quieta al
     desplazar, para no perder de vista de qué fila es cada dato.
   --------------------------------------------------------------------- */
.ct-tabla-marco {
  display: grid;                 /* la tabla y las dos pistas comparten la misma celda… */
  grid-template-columns: minmax(min-content, 1fr);   /* …que mide lo que la tabla cuando no cabe */
  max-width: 100%;
  overflow-x: auto;
  border: 1px solid var(--ct-borde);
  border-radius: var(--ct-radio-fila);
  background: var(--ct-superficie);
}
.ct-tabla-marco > * { grid-area: 1 / 1; }
.ct-tabla-marco::before,
.ct-tabla-marco::after {
  content: "";
  grid-area: 1 / 1;
  position: sticky;
  z-index: 2;
  width: var(--ct-espacio-7);
  pointer-events: none;
  opacity: 0;
}
.ct-tabla-marco::before { left: 0; justify-self: start; background: linear-gradient(to right, var(--ct-superficie), transparent); }
.ct-tabla-marco::after { right: 0; justify-self: end; background: linear-gradient(to left, var(--ct-superficie), transparent); }
.ct-tabla-marco[data-ct-sigue~="inicio"]::before,
.ct-tabla-marco[data-ct-sigue~="fin"]::after { opacity: 1; }
.ct-tabla {
  width: 100%;
  border-collapse: separate;     /* con «collapse» el filo de una celda fija no la acompaña */
  border-spacing: 0;
  color: var(--ct-texto);
  font-family: var(--ct-fuente-texto);
  font-size: var(--ct-tipo-interfaz-cuerpo);
  line-height: 1.4;
}
.ct-tabla caption {
  padding: var(--ct-espacio-interfaz-4) var(--ct-espacio-interfaz-5);
  text-align: start;
  font-weight: var(--ct-peso-texto-fuerte);
  color: var(--ct-texto);
}
.ct-tabla :is(th, td) {
  padding: var(--ct-espacio-interfaz-4) var(--ct-espacio-interfaz-5);
  border-bottom: 1px solid var(--ct-linea);
  text-align: start;
  vertical-align: middle;
}
.ct-tabla thead th {
  font-size: var(--ct-tipo-interfaz-chip);
  font-weight: var(--ct-peso-texto-fuerte);
  color: var(--ct-texto-suave);
  white-space: nowrap;
  background: var(--ct-fondo-suave);
}
.ct-tabla tbody th { font-weight: var(--ct-peso-texto-fuerte); }
.ct-tabla tbody tr:last-child :is(th, td) { border-bottom: 0; }
.ct-tabla .ct-tabla__num { text-align: end; font-variant-numeric: tabular-nums; white-space: nowrap; }
@media (hover: hover) { .ct-tabla tbody tr:hover { background: var(--ct-fondo-suave); } }
.ct-tabla tbody tr.is-hover { background: var(--ct-fondo-suave); }
.ct-tabla tbody tr[aria-selected="true"] { background: var(--ct-primario-suave); }
@media (max-width: 720px) {
  /* primera columna fija: toma el fondo de su fila (normal, con el cursor o seleccionada) */
  .ct-tabla--fija tbody tr { background: var(--ct-superficie); }
  .ct-tabla--fija tbody tr.is-hover { background: var(--ct-fondo-suave); }
  .ct-tabla--fija tbody tr[aria-selected="true"] { background: var(--ct-primario-suave); }
  .ct-tabla--fija tr > :first-child { position: sticky; left: 0; z-index: 1; }
  .ct-tabla--fija tbody tr > :first-child { background: inherit; }
  .ct-tabla--fija tr > :first-child::after {
    content: "";
    position: absolute;
    inset: 0 0 0 auto;
    width: 1px;
    background: var(--ct-borde);
  }
  /* la pista del lado izquierdo taparía la columna fija: aquí la hace su filo */
  .ct-tabla-marco:has(.ct-tabla--fija)::before { display: none; }
}
@media (max-width: 720px) and (hover: hover) {
  .ct-tabla--fija tbody tr:hover { background: var(--ct-fondo-suave); }
}

/* ---------------------------------------------------------------------
   14. ESTADO VACÍO
   Cuando una lista o una búsqueda no devuelve nada: qué pasa y qué hacer.
   --------------------------------------------------------------------- */
.ct-vacio {
  display: grid;
  justify-items: center;
  gap: var(--ct-espacio-interfaz-4);
  padding: var(--ct-espacio-7) var(--ct-espacio-interfaz-6);
  border: 1.5px dashed var(--ct-texto-tenue);
  border-radius: var(--ct-radio-tarjeta);
  background: var(--ct-fondo-suave);
  color: var(--ct-texto);
  text-align: center;
}
.ct-vacio__icono {
  display: grid;
  place-items: center;
  width: var(--ct-espacio-8);
  height: var(--ct-espacio-8);
  border-radius: 50%;
  background: var(--ct-primario-suave);
  color: var(--ct-primario-texto);
}
.ct-vacio__icono .ct-icono { width: var(--ct-espacio-interfaz-6); height: var(--ct-espacio-interfaz-6); }
.ct-base .ct-vacio__titulo,
.ct-vacio__titulo {
  margin: 0;
  font-family: var(--ct-fuente-titular);
  font-size: var(--ct-tipo-titulo-3-tamano);
  font-weight: var(--ct-tipo-titulo-3-peso);
  line-height: 1.2;
}
.ct-vacio__texto { max-width: 46ch; color: var(--ct-texto-suave); }

/* ---------------------------------------------------------------------
   15. ESQUELETO DE CARGA
   Formas grises con el hueco del contenido que va a llegar. Decorativas:
   aria-hidden="true", y el contenedor lleva aria-busy="true".
   --------------------------------------------------------------------- */
.ct-esqueleto {
  display: block;
  width: var(--_ancho, 100%);
  height: 1em;
  border-radius: var(--ct-radio-fila);
  background: var(--ct-linea);
  /* latido: no hay token de bucle; se usa la permanencia del aviso (FALTAN-TOKENS.md) */
  animation: ct-late var(--ct-dur-permanencia-aviso) var(--ct-curva-estado) infinite alternate;
}
.ct-esqueleto--titulo { height: 1.6em; --_ancho: 60%; }
.ct-esqueleto--corta { --_ancho: 40%; }
.ct-esqueleto--circulo { width: var(--ct-toque-fila); height: var(--ct-toque-fila); border-radius: 50%; }
.ct-esqueleto--bloque { height: auto; aspect-ratio: 16 / 9; border-radius: var(--ct-radio-tarjeta); }
.ct-esqueleto--boton { --_ancho: 9em; height: var(--ct-toque-fila); border-radius: var(--ct-radio-boton); }
@keyframes ct-late { from { opacity: 1; } to { opacity: var(--ct-opacidad-deshabilitado); } }

/* ---------------------------------------------------------------------
   16. FOCO Y MOVIMIENTO REDUCIDO
   Un solo anillo de foco: 3 px + 2 px de separación, en --ct-foco.
   Sobre la superficie verde el anillo es el blanco del titular.
   --------------------------------------------------------------------- */
.ct-boton:focus-visible,
.ct-enlace:focus-visible,
.ct-campo__control:focus-visible,
.ct-casilla input:focus-visible,
.ct-pestana:focus-visible,
.ct-logo:focus-visible,
.ct-cabecera__nav a:focus-visible,
.ct-pie__lista a:focus-visible,
.ct-tabla-marco:focus-visible,
.ct-boton.is-foco,
.ct-enlace.is-foco,
.ct-campo__control.is-foco,
.ct-pestana.is-foco,
.ct-cabecera__nav a.is-foco,
.ct-tabla-marco.is-foco {
  outline: var(--ct-foco-grosor) solid var(--ct-foco);
  outline-offset: var(--ct-foco-separacion);
}
.ct-superficie-verde :is(.ct-boton, .ct-enlace, .ct-logo):focus-visible,
.ct-superficie-verde :is(.ct-boton, .ct-enlace).is-foco { outline-color: var(--ct-superficie-verde-titular); }
/* dentro de una tarjeta flotante (blanca) el anillo vuelve al de claro */
.ct-superficie-verde .ct-tarjeta-flotante :is(.ct-boton, .ct-enlace, .ct-campo__control):focus-visible { outline-color: var(--ct-verde-500); }

@media (prefers-reduced-motion: reduce) {
  .ct-boton,
  .ct-enlace--suelto .ct-icono,
  .ct-tarjeta--enlace { transition: none; }
  .ct-boton:active, .ct-boton.is-activo,
  .ct-tarjeta--enlace:hover, .ct-tarjeta--enlace.is-hover,
  .ct-enlace--suelto:hover .ct-icono { transform: none; }
  .ct-boton[aria-busy="true"]::before,
  .ct-esqueleto,
  .ct-hoja[open],
  .ct-toast,
  .ct-toast--sale,
  .ct-js .ct-cabecera__menu[aria-expanded="true"] ~ .ct-cabecera__nav { animation: none !important; }
}
