/* ===========================================================================
   e2VisaInterView — complementos a Tailwind.
   Tailwind llega por CDN con el sistema de diseño en el `tailwind.config` de
   includes/head.php. Aquí va SOLO lo que una utilidad no puede expresar:
   superficies del navegador, el momento de movimiento con autor, el raíl del
   método y los estados del formulario.

   Los hex de este fichero NO los conoce Tailwind: si cambias la paleta del
   config, hay que sincronizarlos a mano. Son los únicos de todo el proyecto.
     deep-navy  #0A192F
     accent-gold #FEC001  (color oficial de Juris Magister)
     slate-gray #3C4043
     border-subtle #DADCE0
   =========================================================================== */

:root {
  --deep-navy: #0a192f;
  --accent-gold: #FEC001;       /* oficial de Juris Magister */
  --accent-gold-hover: #E5AD01; /* el mismo, un 10% más oscuro */
  --slate-gray: #3c4043;
  --border-subtle: #dadce0;
}

/* ---------------------------------------------------------------------------
   1. Superficies del navegador
   Selección, caret, scrollbar, anillo de foco, subrayados y cifras llegan con
   los valores por defecto del navegador, que no pertenecen a ningún sistema de
   diseño. Tematizarlos es la señal más barata de que una página se construyó
   en lugar de ensamblarse.
   --------------------------------------------------------------------------- */

::selection {
  background: var(--accent-gold);
  color: var(--deep-navy);
}

html {
  scroll-behavior: smooth;
  /* El caret y los controles nativos (checkbox, select, date) heredan el tono
     de marca en lugar del azul del sistema. */
  caret-color: var(--deep-navy);
  accent-color: var(--deep-navy);
  scrollbar-color: var(--border-subtle) transparent;
  scrollbar-width: thin;
}

/* WebKit no soporta `scrollbar-color`, así que lleva su propia regla. */
::-webkit-scrollbar { width: 12px; height: 12px; }
::-webkit-scrollbar-track { background: transparent; }
::-webkit-scrollbar-thumb {
  background: var(--border-subtle);
  border: 3px solid #fff;
  border-radius: 999px;
}
::-webkit-scrollbar-thumb:hover { background: #b9bcc1; }

/* Anillo de foco. `:focus-visible` y no `:focus`: no aparece al hacer clic con
   ratón, solo al navegar con teclado.

   El color depende del fondo, y esto NO es un detalle estético. La versión
   anterior usaba oro en todo el sitio: sobre blanco da ~1,6:1, por debajo del
   mínimo de 3:1 para elementos no textuales, y sobre el propio botón dorado del
   formulario era oro sobre oro, es decir, ningún indicador en el único botón de
   conversión de la página.

   Navy por defecto; oro solo sobre fondo navy. El orden importa: la regla del
   fondo blanco va la última para que una tarjeta blanca dentro de una sección
   navy (el formulario de contacto) recupere el anillo oscuro. */
:focus-visible {
  outline: 2px solid var(--deep-navy);
  outline-offset: 3px;
  border-radius: 2px;
}

.bg-deep-navy :focus-visible {
  outline-color: var(--accent-gold);
}

.bg-surface-white :focus-visible {
  outline-color: var(--deep-navy);
}

/* Cifras en tabla: alinea columnas de números y evita el baile de anchos. */
.tabular-nums { font-variant-numeric: tabular-nums; }

/* ---------------------------------------------------------------------------
   1b. Comportamiento táctil
   Lo que separa «una web en un navegador» de algo que se siente bien en el
   móvil. El tráfico de esta página es mayoritariamente iPhone.
   --------------------------------------------------------------------------- */

/* El rectángulo azul que iOS pinta sobre cada elemento tocado no pertenece a
   ningún sistema de diseño. Se quita y el feedback táctil lo da `:active`, que
   ya está en los botones. */
html {
  -webkit-tap-highlight-color: transparent;
}

/* Evita que el tirón hacia abajo estando ya arriba dispare el refresco de la
   página, y que el scroll rebote más allá del documento. */
body {
  overscroll-behavior-y: contain;
}

/* El texto de los botones no se selecciona al mantener pulsado, que en iOS
   abre el menú de copiar en lugar de activar el botón. */
button,
[role="button"],
.skip-link {
  -webkit-user-select: none;
  user-select: none;
}

/* Zona segura. Tres elementos de esta página son `position: fixed`: la nav
   arriba, y el banner de cookies y su panel de preferencias abajo. Sin esto,
   en un iPhone con muesca la nav se mete bajo la isla dinámica y los botones
   de «Aceptar» y «Rechazar» quedan parcialmente bajo la barra de gestos.

   Se suma al padding que ya traen las utilidades de Tailwind en lugar de
   sustituirlo, para no perder el espaciado del sistema de diseño. */
#site-nav {
  padding-top: env(safe-area-inset-top, 0px);
  padding-left: env(safe-area-inset-left, 0px);
  padding-right: env(safe-area-inset-right, 0px);
}

#cookie-banner,
#cookie-prefs {
  padding-bottom: calc(1rem + env(safe-area-inset-bottom, 0px));
  padding-left: calc(1rem + env(safe-area-inset-left, 0px));
  padding-right: calc(1rem + env(safe-area-inset-right, 0px));
}

@media (min-width: 768px) {
  #cookie-banner,
  #cookie-prefs {
    padding-bottom: calc(1.5rem + env(safe-area-inset-bottom, 0px));
    padding-left: calc(1.5rem + env(safe-area-inset-left, 0px));
    padding-right: calc(1.5rem + env(safe-area-inset-right, 0px));
  }
}

/* Enlaces en prosa. El subrayado respira en lugar de cortar los descendentes. */
/* Enlaces en prosa. El oro oficial de Juris Magister es el SUBRAYADO, no el
   color del texto.

   El motivo es medible: #FEC001 sobre blanco da 1,65:1, muy por debajo del
   mínimo de 4,5:1 para texto. Un enlace escrito en ese color sería de marca y
   sería ilegible. Como subrayado de 2px el oro se ve perfectamente, el texto
   se queda en navy a 17,6:1, y el enlace sigue distinguiéndose del texto que
   lo rodea por la forma —está subrayado— y no solo por el color, que es lo que
   exige la norma.

   Sobre navy el oro sí llega a 10,69:1, así que ahí puede ser el color del
   texto sin problema. */
.link-inline {
  color: var(--deep-navy);
  text-decoration: underline;
  text-decoration-thickness: 2px;
  text-underline-offset: 0.2em;
  text-decoration-color: var(--accent-gold);
  transition: text-decoration-color 0.2s, color 0.2s;
}
.link-inline:hover {
  text-decoration-color: var(--accent-gold-hover);
  color: #000;
}

/* Sobre navy el oro pasa a ser el color del texto: ahí sí tiene contraste. */
.bg-deep-navy .link-inline,
footer .link-inline {
  color: inherit;
  text-decoration-color: var(--accent-gold);
}
.bg-deep-navy .link-inline:hover,
footer .link-inline:hover { color: var(--accent-gold); }

/* Sobre fondo navy el enlace invierte. */
.bg-deep-navy .link-inline,
footer .link-inline { color: inherit; }

/* Salto al contenido. Fuera de pantalla hasta recibir foco. */
.skip-link {
  position: absolute;
  left: -9999px;
  z-index: 100;
  padding: 0.75rem 1.25rem;
  background: var(--deep-navy);
  color: #fff;
  border-radius: 0 0 0.5rem 0;
}
.skip-link:focus {
  left: 0;
  top: 0;
}

/* ---------------------------------------------------------------------------
   2. El momento de movimiento con autor
   Las seis preguntas del bloque focal se enfocan en secuencia al entrar en
   viewport. Es el ÚNICO movimiento de entrada de la página.

   El contenido parte de visible y nítido: sin JS, o si el observer no llega,
   la pregunta se lee igual. La animación solo quita un desenfoque, que es
   reaching más allá de transform y opacity sin coste de layout.
   --------------------------------------------------------------------------- */

.ask {
  /* Estado de reposo: legible. Lo que falta es el enfoque, no el contenido. */
  opacity: 0.45;
  filter: blur(5px);
  transform: translateY(0.5rem);
  transition:
    opacity 0.7s cubic-bezier(0.16, 1, 0.3, 1),
    filter 0.7s cubic-bezier(0.16, 1, 0.3, 1),
    transform 0.7s cubic-bezier(0.16, 1, 0.3, 1);
  transition-delay: calc(var(--ask-index, 0) * 110ms);
  will-change: filter, opacity, transform;
}

.ask.asked {
  opacity: 1;
  filter: blur(0);
  transform: translateY(0);
}

/* Al terminar su entrada deja de reservar capa de composición. */
.ask.asked { will-change: auto; }

/* La sangría progresiva. Solo desde `md`: por debajo no hay ancho que ceder y
   empujar el texto haría que la sexta pregunta se leyera en una columna
   estrechísima. El tope de seis pasos está calculado sobre el índice máximo
   (5), así que la última entra un 25% y el bloque sigue cabiendo. */
@media (min-width: 768px) {
  .ask-step {
    margin-left: calc(var(--ask-index, 0) * 5%);
  }
}

/* ---------------------------------------------------------------------------
   3. El raíl del método
   Una sola línea recorre los seis pasos, dibujada por el contenedor: seis
   trozos independientes podrían desalinearse entre sí.
   --------------------------------------------------------------------------- */

.method-rail { position: relative; }

/* La línea pasa por el CENTRO de los números, no al lado. El numeral ocupa
   2.1rem de ancho, así que su eje está en 1.05rem; en pantallas anchas ocupa
   3.1rem y el eje pasa a 1.55rem. Si cambias el ancho de `.method-step__n`,
   estos dos valores tienen que seguirlo o la línea se despega de las cifras que
   debería enhebrar. */
.method-rail::before {
  content: "";
  position: absolute;
  top: 0.4rem;
  bottom: 0.4rem;
  left: 1.05rem;
  width: 1px;
  background: var(--border-subtle);
}

/* El número se apoya en la línea con un fondo blanco que la interrumpe. */
.method-step__n {
  background: #fff;
  padding: 0.3rem 0;
  width: 2.1rem;
  text-align: center;
}

@media (min-width: 640px) {
  .method-rail::before { left: 1.55rem; }
  .method-step__n { width: 3.1rem; }
}

/* ---------------------------------------------------------------------------
   4. FAQ nativo
   `<details>` con un chevron que gira. El marcador por defecto se quita en
   todos los navegadores, incluido Safari, que necesita la regla de WebKit.
   --------------------------------------------------------------------------- */

.faq-summary { list-style: none; }
.faq-summary::-webkit-details-marker { display: none; }

.faq-chevron { transition: transform 0.25s cubic-bezier(0.16, 1, 0.3, 1); }
.faq-item[open] .faq-chevron { transform: rotate(180deg); }

/* ---------------------------------------------------------------------------
   5. Formulario
   --------------------------------------------------------------------------- */

/* Honeypot. Oculto por CSS y no con `type="hidden"`, que algunos bots
   reconocen. `left` fuera de pantalla en lugar de `display:none` porque hay
   bots que ignoran los campos no renderizados. */
.hp-field {
  position: absolute;
  left: -9999px;
  width: 1px;
  height: 1px;
  overflow: hidden;
}

.field-error {
  color: #ba1a1a;
  font-size: 0.8125rem;
  line-height: 1.3;
}

/* El campo con error se marca también en el borde: el color no puede ser la
   única señal. */
.field-invalid {
  border-color: #ba1a1a !important;
  box-shadow: 0 0 0 1px #ba1a1a;
}

.form-status { padding-top: 0.25rem; }
.form-status[data-state="ok"]  { color: #1b5e20; }
.form-status[data-state="err"] { color: #ba1a1a; }

/* Los `input[type=date]` llegan con cromo propio del navegador. El icono del
   calendario en WebKit hereda el tono de marca en lugar del gris del sistema. */
.field-date::-webkit-calendar-picker-indicator {
  cursor: pointer;
  opacity: 0.55;
  transition: opacity 0.2s;
}
.field-date::-webkit-calendar-picker-indicator:hover { opacity: 1; }

/* Firefox pinta un borde rojo propio en campos inválidos antes de enviar. */
input:invalid, select:invalid, textarea:invalid { box-shadow: none; }

/* ---------------------------------------------------------------------------
   6. Menú móvil
   Transición sobre `grid-template-rows` de 0fr a 1fr, no sobre `max-height`.

   Dos razones. La animación de `max-height` provoca recálculo de layout en
   cada frame, y además obliga a un número mágico: el valor tiene que ser mayor
   que el contenido real, así que `max-height: 32rem` habría roto el menú en
   cuanto añadiéramos un quinto enlace, y la transición nunca va a la velocidad
   que aparenta porque recorre el sobrante. Con `1fr` el destino es la altura
   real del contenido, sea la que sea.

   La regla va dentro de la media query para no pelearse con el `lg:hidden` de
   Tailwind: por encima de 1024px esta declaración ni existe, así que no hay
   dos reglas de `display` compitiendo por orden de cascada.
   --------------------------------------------------------------------------- */

@media (max-width: 1023.98px) {
  .mobile-menu {
    display: grid;
    grid-template-rows: 0fr;
    transition: grid-template-rows 0.3s cubic-bezier(0.16, 1, 0.3, 1);
  }

  .mobile-menu.open { grid-template-rows: 1fr; }

  /* El hijo necesita las dos: `overflow` recorta mientras la fila se abre, y
     `min-height: 0` anula el mínimo automático que da el grid a sus hijos y
     que, sin esto, impediría que la fila llegue a cero.

     `visibility: hidden` no es redundante con el recorte: sin ella los enlaces
     del menú cerrado siguen en el orden de tabulación y en el árbol de
     accesibilidad, así que alguien navegando con teclado cae dentro de un menú
     que no ve. El retardo igual a la duración la mantiene visible mientras la
     fila se cierra, y al abrir entra sin retardo. */
  .mobile-menu > * {
    overflow: hidden;
    min-height: 0;
    visibility: hidden;
    transition: visibility 0s linear 0.3s;
  }

  .mobile-menu.open > * {
    visibility: visible;
    transition-delay: 0s;
  }
}

/* ---------------------------------------------------------------------------
   6b. El montón de la sección «Juris Magister»
   Siete capas que crecen de tamaño según se acumulan. El bloque argumenta por
   acumulación —detrás de un E-2 hay siete cosas y una sola persona tiene que
   explicarlas todas— así que la tipografía hace ese trabajo en lugar de
   describirlo.

   El paso va en CSS y no en el atributo `style` para poder cambiarlo por
   breakpoint: en móvil la última capa desbordaría los 390px con el paso de
   escritorio.
   --------------------------------------------------------------------------- */

/* El tamaño se interpola del primero al último, NO con un paso fijo.
   Con paso fijo, una pila de cuatro recorría 18->26px y una de siete
   18->33px: el mismo incremento por línea, pero en la corta el efecto no
   llegaba a leerse. Normalizando contra el índice máximo (`--capa-n`), todas
   las pilas recorren el mismo rango y el crecimiento se nota igual tengan
   tres elementos o siete.

   `--capa-n` es el índice del ÚLTIMO elemento, es decir, el total menos uno.
   Lo declara cada `<ul>`. Si se añade o quita una línea hay que actualizarlo,
   o la pila se queda corta o se pasa de largo.

   OJO con el valor por defecto: va en el `var()`, NUNCA declarado dentro de
   `.capa`. Una propiedad personalizada declarada en el propio elemento gana
   sobre la heredada del padre, así que un `--capa-n: 1` aquí anula el valor
   que cada `<ul>` define y la división pasa a ser siempre entre uno: la
   última línea de una pila de siete llegaba así a 109px. */
.capa { font-size: calc(1.0625rem + (var(--capa, 0) / var(--capa-n, 1)) * 0.5rem); }

@media (min-width: 768px) {
  .capa { font-size: calc(1.125rem + (var(--capa, 0) / var(--capa-n, 1)) * 0.95rem); }
}

/* ---------------------------------------------------------------------------
   7. Iconos
   Dos SVG en línea, trazo 2, mismo redondeo. Sustituyen a la hoja completa de
   Material Symbols, que se cargaba entera para servir estos dos glifos y, con
   `display=swap`, pintaba las palabras «menu» y «expand_more» en texto antes de
   que la fuente llegara.

   Cuál se ve lo decide `aria-expanded`, no una clase aparte: el estado visual
   deriva del accesible y no pueden desincronizarse.
   --------------------------------------------------------------------------- */

.nav-toggle .icon-close { display: none; }
.nav-toggle[aria-expanded="true"] .icon-menu { display: none; }
.nav-toggle[aria-expanded="true"] .icon-close { display: block; }

/* ---------------------------------------------------------------------------
   8. Movimiento reducido
   Todo lo animado colapsa a su estado final, de forma inmediata. Nada queda
   invisible: el bloque focal parte de contenido legible precisamente para que
   esto sea posible.
   --------------------------------------------------------------------------- */

@media (prefers-reduced-motion: reduce) {
  html { scroll-behavior: auto; }

  *, *::before, *::after {
    animation-duration: 0.01ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: 0.01ms !important;
    transition-delay: 0ms !important;
  }

  .ask {
    opacity: 1;
    filter: none;
    transform: none;
  }
}
