/* ============================================
   FrameLab — hoja de estilos única
   Orden: tokens · reset · tipografía · utilidades · secciones
   ============================================ */

:root {
  --negro: #0A0A0A;
  --negro-2: #121212;
  --amarillo: #FFE01B;
  --amarillo-oscuro: #C4A800;   /* estados hover/activo, designado por la spec */
  --blanco: #FFFFFF;
  --blanco-70: rgba(255, 255, 255, 0.70);
  /* Microcopy. La spec pide 7:1 (AAA) para este texto: a 0.45 daba 4.50:1,
     justo en el límite de AA, y afecta a los .mono de 11 px y a las etiquetas
     de los faders, de 9 px. A 0.62 sobre #0A0A0A da ~7.2:1. */
  --blanco-62: rgba(255, 255, 255, 0.62);
  --borde: rgba(255, 255, 255, 0.10);
  --glow: rgba(255, 224, 27, 0.15);
  --telegram: #229ED9;

  --display: 'Bebas Neue', system-ui, sans-serif;
  --cuerpo: 'Inter', system-ui, -apple-system, sans-serif;
  --mono: 'JetBrains Mono', ui-monospace, monospace;

  --ancho-max: 1180px;
  --radio: 14px;
  --transicion: 240ms cubic-bezier(0.22, 1, 0.36, 1);
}

/* ---------- reset ---------- */

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

html {
  scroll-behavior: smooth;
  -webkit-text-size-adjust: 100%;
  /* La cabecera es fija (~71 px con su padding): sin esto los anclas quedan
     tapados por ella al saltar a una sección. */
  scroll-padding-top: 88px;
}

body {
  margin: 0;
  background: var(--negro);
  color: var(--blanco);
  font-family: var(--cuerpo);
  font-size: 16px;
  line-height: 1.6;
  -webkit-font-smoothing: antialiased;
  overflow-x: hidden;
}

img, svg, video { display: block; max-width: 100%; }
img { height: auto; }

/* `hidden` gana siempre: hay secciones ocultas hasta tener contenido confirmado
   y ninguna regla de sección debe poder resucitarlas por accidente. */
[hidden] { display: none !important; }

.svg-filtros { position: absolute; width: 0; height: 0; overflow: hidden; }

button { font: inherit; color: inherit; background: none; border: none; cursor: pointer; }

a { color: inherit; }

/* foco visible, obligatorio en todo elemento interactivo */
:where(a, button, input, summary, [tabindex]):focus-visible {
  outline: 2px solid var(--amarillo);
  outline-offset: 3px;
  border-radius: 4px;
}

/* ---------- tipografía ---------- */

h1, h2, h3, .display {
  font-family: var(--display);
  font-weight: 400;
  text-transform: uppercase;
  letter-spacing: -0.01em;
  line-height: 0.88;
  margin: 0;
}

h1 { font-size: clamp(2.75rem, 9vw, 6.5rem); }
h2 { font-size: clamp(2rem, 6vw, 4rem); }
h3 { font-size: clamp(1.25rem, 3vw, 1.75rem); }

p { margin: 0; color: var(--blanco-70); }

.mono {
  font-family: var(--mono);
  font-size: 0.6875rem;
  letter-spacing: 0.22em;
  text-transform: uppercase;
  color: var(--blanco-62);
}

/* ---------- utilidades ---------- */

.contenedor {
  width: 100%;
  max-width: var(--ancho-max);
  margin-inline: auto;
  padding-inline: 24px;
}

.badge {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  padding: 7px 16px;
  border: 1px solid var(--borde);
  border-radius: 999px;
  background: rgba(255, 224, 27, 0.06);
  color: var(--amarillo);
}

.badge::before {
  content: '';
  width: 6px;
  height: 6px;
  border-radius: 50%;
  background: var(--amarillo);
  animation: latido 2s ease-in-out infinite;
}

@keyframes latido {
  0%, 100% { opacity: 1; transform: scale(1); }
  50% { opacity: 0.35; transform: scale(1.35); }
}

.boton {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 10px;
  padding: 16px 30px;
  border-radius: var(--radio);
  font-weight: 600;
  font-size: 0.9375rem;
  text-decoration: none;
  transition: transform var(--transicion), background var(--transicion),
              filter var(--transicion), box-shadow var(--transicion);
}

.boton:hover { transform: translateY(-2px); }

.boton--marca {
  background: var(--amarillo);
  color: var(--negro);
  box-shadow: 0 8px 32px rgba(255, 224, 27, 0.22);
}

/* --amarillo-oscuro es el estado hover/activo que designa la spec: 8.4:1 con el
   texto negro. Antes había un --amarillo-claro inventado, fuera de paleta. */
.boton--marca:hover { background: var(--amarillo-oscuro); }

/* Texto negro, no blanco: el blanco sobre #229ED9 da 3.02:1, por debajo del
   mínimo AA de 4.5:1, y este CTA aparece dos veces. En negro sube a 6.6:1 sin
   tocar el azul de marca de Telegram, que la spec fija. El ícono hereda el
   color con currentColor, así que también queda negro. */
.boton--telegram {
  background: var(--telegram);
  color: var(--negro);
}

/* Hover sin introducir un color nuevo: se aclara el propio azul de marca.
   A brightness(1.12) el fondo queda en ~8.2:1 con el texto negro, así que el
   estado hover cumple AA con margen. El negro del texto y del ícono no se
   mueve de forma perceptible (#0A0A0A → #0B0B0B). */
.boton--telegram:hover { filter: brightness(1.12); }

/* marco con esquinas, motivo recurrente de la referencia */
.marco-esquinas { position: relative; }

.marco-esquinas::before,
.marco-esquinas::after {
  content: '';
  position: absolute;
  width: 14px;
  height: 14px;
  border: 1px solid var(--amarillo);
  pointer-events: none;
}

.marco-esquinas::before {
  top: 0; left: 0;
  border-right: 0; border-bottom: 0;
}

.marco-esquinas::after {
  bottom: 0; right: 0;
  border-left: 0; border-top: 0;
}

/* ---------- preloader ---------- */

.preloader { display: none; }

/* El estado de salida (`--abriendo`) va en el mismo bloque que el estado de
   carga: durante la disolución la clase `cargando` ya no está puesta (la landing
   necesita empezar a aparecer al mismo tiempo), y sin esto el preloader pasaría
   a `display: none` de golpe en vez de desvanecerse. */
.cargando .preloader,
.preloader--abriendo {
  display: grid;
  place-items: center;
  position: fixed;
  inset: 0;
  z-index: 9999;
  background: var(--negro);
}

.cargando body { overflow: hidden; }

/* La landing aparece bajo un velo desenfocado que se disipa. El desenfoque vive
   en el preloader —una capa fija del tamaño del viewport, que la GPU compone
   barato— y NO en <main>: filtrar un elemento de varias pantallas de alto corre
   por el hilo principal, se desincroniza de la cabecera (que sí va por GPU) y
   arriesga tirones en móvil. Acá <main> solo hace fundido de opacidad. */
main, .cabecera { transition: opacity 380ms ease-out; }

.cargando main,
.cargando .cabecera { opacity: 0; }

/* Esquinas de encuadre del visor, blancas como en las cámaras reales */
.preloader__esquina {
  position: absolute;
  width: 34px;
  height: 34px;
  border: 2px solid rgba(255, 255, 255, 0.85);
  animation: entrada-esquina 600ms 150ms cubic-bezier(0.22, 1, 0.36, 1) backwards;
}

.preloader__esquina--tl { top: 22px; left: 22px; border-right: 0; border-bottom: 0; }
.preloader__esquina--tr { top: 22px; right: 22px; border-left: 0; border-bottom: 0; }
.preloader__esquina--bl { bottom: 22px; left: 22px; border-right: 0; border-top: 0; }
.preloader__esquina--br { bottom: 22px; right: 22px; border-left: 0; border-top: 0; }

@keyframes entrada-esquina {
  from { opacity: 0; transform: scale(1.3); }
  to   { opacity: 1; transform: none; }
}

.preloader__hud {
  position: absolute;
  top: 32px;
  left: 76px;
  right: 76px;
  display: flex;
  justify-content: space-between;
  align-items: center;
  color: var(--blanco-62);
}

.preloader__rec {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  color: var(--blanco);
  letter-spacing: 0.3em;
}

/* Rojo REC, no amarillo de marca: es el único elemento de la página que lo usa
   y es deliberado — el punto rojo de grabación es un código universal de cámara. */
.preloader__rec-punto {
  width: 10px;
  height: 10px;
  border-radius: 50%;
  background: #FF3B30;
  box-shadow: 0 0 12px rgba(255, 59, 48, 0.8);
  animation: rec-parpadeo 1.2s steps(1) infinite;
}

@keyframes rec-parpadeo {
  0%, 100% { opacity: 1; }
  50% { opacity: 0.15; }
}

.preloader__centro { text-align: center; width: min(720px, 88vw); }

.preloader__isotipo {
  margin-inline: auto;
  animation: entrada-isotipo 600ms cubic-bezier(0.22, 1, 0.36, 1) both;
}

@keyframes entrada-isotipo {
  from { opacity: 0; transform: scale(0.88) rotate(-25deg); }
  to   { opacity: 1; transform: scale(1) rotate(0); }
}

.preloader__marca {
  font-family: var(--cuerpo);
  font-weight: 600;
  font-size: 1.25rem;
  color: var(--blanco);
  margin: 14px 0 30px;
  animation: entrada-isotipo 600ms 200ms both;
}

.preloader__cargando {
  margin-bottom: 18px;
  letter-spacing: 0.34em;
  color: var(--blanco-70);
}

/* La raya de carga cruza la pantalla, no una cajita */
.preloader__barra {
  width: min(640px, 76vw);
  margin-inline: auto;
  height: 3px;
  background: var(--borde);
  border-radius: 2px;
  overflow: hidden;
}

.preloader__progreso {
  display: block;
  height: 100%;
  width: 0%;
  background: var(--amarillo);
  transition: width 120ms linear;
}

.preloader__porcentaje {
  margin-top: 16px;
  font-size: 0.875rem;
  letter-spacing: 0.22em;
  color: var(--blanco);
}

/* Sistemas de la cámara en la franja baja del visor, como en la referencia:
   apagados de entrada, se encienden en amarillo uno a uno conforme carga. */
.preloader__sistemas {
  position: absolute;
  left: 0;
  right: 0;
  bottom: clamp(56px, 12vh, 110px);
  display: flex;
  justify-content: center;
  align-items: start;
  gap: clamp(18px, 4vw, 54px);
  margin: 0;
  padding: 0 70px;
  list-style: none;
}

.preloader__sistemas li {
  display: grid;
  justify-items: center;
  gap: 7px;
  max-width: 110px;
  text-align: center;
  font-family: var(--mono);
  font-size: 0.625rem;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  color: rgba(255, 255, 255, 0.24);
  transition: color 300ms ease-out;
}

.preloader__sistemas svg { width: 30px; height: 30px; }

/* Sin uppercase: la notación fotográfica del número f va en minúscula (f/2.8). */
.preloader__sistema-valor { font-size: 0.6875rem; text-transform: none; }

.preloader__sistemas li.ok {
  color: var(--amarillo);
  animation: check-pop 500ms cubic-bezier(0.34, 1.56, 0.64, 1);
}

.preloader__sistemas li.ok .preloader__sistema-nombre { color: var(--blanco); }
.preloader__sistemas li.ok .preloader__sistema-valor { color: var(--blanco-70); }

@keyframes check-pop {
  0%   { transform: scale(0.82); }
  55%  { transform: scale(1.12); }
  100% { transform: scale(1); }
}

@media (max-width: 760px) {
  .preloader__sistemas {
    display: grid;
    grid-template-columns: repeat(3, auto);
    justify-content: center;
    gap: 22px 28px;
    padding: 0 24px;
  }
}

/* Captura: destello blanco y el HUD desaparece de golpe, como al sacar la foto */
.preloader__flash {
  position: absolute;
  inset: 0;
  background: #FFFFFF;
  opacity: 0;
  pointer-events: none;
}

.preloader--captura .preloader__flash { animation: flash-captura 280ms ease-out; }

@keyframes flash-captura {
  0%   { opacity: 0; }
  22%  { opacity: 0.95; }
  100% { opacity: 0; }
}

.preloader--captura .preloader__centro,
.preloader--captura .preloader__hud,
.preloader--captura .preloader__sistemas,
.preloader--captura .preloader__esquina {
  opacity: 0;
  transition: opacity 180ms ease-out;
}

/* El velo se arma junto con el destello y no antes: así el backdrop-filter, que
   no es gratis, sólo vive los ~600 ms de la salida y no toda la carga. */
.preloader--captura {
  backdrop-filter: blur(26px);
  -webkit-backdrop-filter: blur(26px);
}

/* Disolución final: el negro se va, el velo desenfocado se aclara y se
   desvanece, y debajo queda la landing nítida. Sin recorte geométrico ni zoom.
   Doble clase a propósito: con `.preloader--abriendo` solo (0,1,0) la regla
   perdería contra el bloque de arriba (0,2,0) y la transición no correría. */
.preloader.preloader--abriendo {
  opacity: 0;
  background-color: transparent;
  backdrop-filter: blur(0px);
  -webkit-backdrop-filter: blur(0px);
  pointer-events: none;
  /* La opacidad arranca 120 ms tarde a propósito: el velo tiene que quedarse
     opaco un instante para que se VEA la landing desenfocada. Si se desvanece a
     la par del desenfoque, el ojo sólo percibe un fundido desde negro. */
  transition: opacity 360ms ease-out 120ms,
              background-color 190ms ease-out,
              backdrop-filter 480ms ease-out;
}

/* ---------- cabecera ---------- */

.cabecera {
  position: fixed;
  inset: 0 0 auto 0;
  z-index: 100;
  transition: background var(--transicion), border-color var(--transicion);
  border-bottom: 1px solid transparent;
}

.cabecera--fija {
  background: rgba(10, 10, 10, 0.8);
  backdrop-filter: blur(12px);
  border-bottom-color: var(--borde);
}

.cabecera__interior {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 16px;
  padding-block: 16px;
}

.cabecera__cta { padding: 11px 22px; font-size: 0.875rem; }

@media (max-width: 560px) {
  /* El logo escala proporcionalmente. Antes se recortaba a 44×44 con
     `object-fit: none` sobre el logo completo (viewBox 260×64): el isotipo
     quedaba de 6 px y el wordmark de unos 2 px, ilegible. A 32 px de alto el
     logo entero mide ~130 px de ancho y entra de sobra junto al CTA. */
  .cabecera__logo img { width: auto; height: 32px; }
  .cabecera__cta { padding: 10px 16px; font-size: 0.8125rem; }
}

/* ---------- hero ---------- */

.hero { position: relative; padding-block: 150px 90px; overflow: hidden; }

.hero__glow {
  position: absolute;
  top: 12%;
  left: -10%;
  width: 520px;
  height: 520px;
  border-radius: 50%;
  background: var(--glow);
  filter: blur(140px);
  pointer-events: none;
}

.hero__interior {
  position: relative;
  display: grid;
  grid-template-columns: 1fr 0.8fr;
  gap: 56px;
  align-items: center;
}

.hero__acento { color: var(--amarillo); display: block; }

h1 span { display: block; }

.hero__bajada {
  max-width: 46ch;
  margin-block: 26px 34px;
  font-size: 1.0625rem;
}

/* Acotado al hero: antes se reabría `.badge` acá y el margen alcanzaba también
   al badge del cierre, que ya toma su separación de `.cierre h2`. */
.hero__texto .badge { margin-bottom: 26px; }

.hero__acciones { display: flex; flex-wrap: wrap; gap: 14px; }

.hero__figura {
  margin: 0;
  border-radius: var(--radio);
  overflow: hidden;
  border: 1px solid var(--borde);
}

/* La foto del hero es un retrato vertical y la caja es apaisada, así que
   `cover` recorta arriba y abajo. El camarógrafo y la cámara viven en el
   tercio superior: al 30% entran completos y queda algo de aire encima. */
.hero__figura img { width: 100%; height: 520px; object-fit: cover;
                    object-position: 50% 30%; }

@media (max-width: 900px) {
  .hero { padding-block: 120px 70px; }
  .hero__interior { grid-template-columns: 1fr; gap: 36px; }
  .hero__figura img { height: 340px; }
  .hero__acciones .boton { flex: 1 1 100%; }
}

/* ---------- franja en marquee ---------- */

.franja {
  padding-block: 26px;
  border-block: 1px solid var(--borde);
  overflow: hidden;
  /* se desvanece en los bordes para que no corte en seco */
  mask-image: linear-gradient(to right, transparent, #000 12%, #000 88%, transparent);
  -webkit-mask-image: linear-gradient(to right, transparent, #000 12%, #000 88%, transparent);
}

.franja__pista {
  display: flex;
  width: max-content;
  animation: desplazar 34s linear infinite;
}

.franja__lista {
  display: flex;
  align-items: center;
  gap: 46px;
  margin: 0;
  padding: 0 23px;
  list-style: none;
  font-family: var(--display);
  text-transform: uppercase;
  font-size: 1.5rem;
  letter-spacing: 0.02em;
  color: var(--blanco-62);
  white-space: nowrap;
}

/* separador con el motivo del diafragma */
.franja__lista li + li::before {
  content: '◉';
  color: var(--amarillo);
  font-size: 0.6rem;
  vertical-align: middle;
  margin-right: 46px;
}

@keyframes desplazar {
  from { transform: translateX(0); }
  to   { transform: translateX(-50%); }
}

.franja:hover .franja__pista { animation-play-state: paused; }

@media (prefers-reduced-motion: reduce) {
  .franja__pista { animation: none; }
  .franja { mask-image: none; -webkit-mask-image: none; }
}

/* ---------- revelado al scroll ---------- */

.js [data-revelar] {
  opacity: 0;
  transform: translateY(16px);
  transition: opacity 500ms ease-out var(--retardo, 0ms),
              transform 500ms cubic-bezier(0.22, 1, 0.36, 1) var(--retardo, 0ms);
}

[data-revelar].revelado { opacity: 1; transform: none; }

/* Red de seguridad con movimiento reducido: tiene que ganarle a
   `.js [data-revelar] { opacity: 0 }`. Las media queries no aportan
   especificidad, así que el selector se iguala a (0,2,0) — con sólo
   `[data-revelar]` (0,1,0) esta regla no se aplicaba nunca. */
@media (prefers-reduced-motion: reduce) {
  [data-revelar],
  .js [data-revelar] { opacity: 1; transform: none; }
}

/* ---------- secciones, cabecera común ---------- */

section { padding-block: 90px; }

.seccion__cabecera { max-width: 640px; margin-bottom: 44px; }

.seccion__cabecera h2 { margin-block: 14px 18px; }

.seccion__bajada { font-size: 1.0625rem; }

/* ---------- simulador ---------- */

/* Acotada a 960px y con la vista limitada en alto: a ancho completo, la foto
   sola ocupaba todo el viewport y los faders quedaban fuera de pantalla. La
   interacción se entiende solo si foto y controles se ven juntos. */
.consola {
  max-width: 960px;
  margin-inline: auto;
  background: var(--negro-2);
  border: 1px solid var(--borde);
  border-radius: var(--radio);
  padding: 16px;
  display: grid;
  gap: 14px;
}

/* Aparición más fluida que el revelado genérico: sube más, tarda más y se
   asienta con una curva suave. Sin scale: alteraría el bounding box de los
   faders mientras la consola no está revelada. La especificidad (0,3,0)
   obliga a repetir el estado final `.revelado` al mismo nivel. */
.js .consola[data-revelar] {
  transform: translateY(30px);
  transition: opacity 750ms ease-out var(--retardo, 0ms),
              transform 750ms cubic-bezier(0.22, 1, 0.36, 1) var(--retardo, 0ms);
}

.js .consola[data-revelar].revelado { opacity: 1; transform: none; }

.consola__barra {
  display: flex;
  justify-content: space-between;
  padding-bottom: 14px;
  border-bottom: 1px solid var(--borde);
}

.consola__rec { color: var(--amarillo); animation: latido 2s ease-in-out infinite; }

.consola__vista {
  position: relative;
  margin: 0;
  border-radius: 10px;
  overflow: hidden;
  aspect-ratio: 3 / 2;
  /* Más chica que la consola y centrada: el punto de la sección es mover un
     fader y VER el cambio en la foto al mismo tiempo, sin scrollear. A ancho
     completo, la foto empujaba los controles fuera de pantalla. El tope de
     altura recorta la proporción 3/2 a un encuadre más panorámico si hace falta. */
  width: min(100%, 620px);
  margin-inline: auto;
  max-height: min(40vh, 380px);
  background: #000;
  isolation: isolate;

  /* estado del simulador, lo escribe /js/simulador.js */
  --sim-grano: 0.17;   /* valor de ISO 400, el inicial; lo recalcula el JS */
  --sim-brillo: 1;
  --sim-bokeh: 4px;
  --sim-temp-color: rgb(255, 255, 255);
  --sim-temp-fuerza: 0;
  --sim-contraste: 1;
  --sim-saturacion: 1;
}

.consola__foto {
  width: 100%;
  height: 100%;
  object-fit: cover;
  /* La foto fuente es vertical (1600×2400) y la caja es 3/2 apaisada, así que
     `cover` recorta mucho en vertical. Centrado dejaba el encuadre a la altura
     del mentón: un torso sin cabeza. Subiéndolo al 15% entra la cara. */
  object-position: 50% 15%;
  filter: brightness(var(--sim-brillo))
          contrast(var(--sim-contraste))
          saturate(var(--sim-saturacion))
          url(#sim-motion-blur);
  transition: filter 120ms linear;
}

/* Bokeh: capa que desenfoca lo que tiene detrás, enmascarada para que el
   centro quede nítido. Así el sujeto se mantiene definido y el desenfoque
   crece hacia los bordes, sin necesidad de recortar la figura a mano. */
.consola__vista::after {
  content: '';
  position: absolute;
  inset: 0;
  backdrop-filter: blur(var(--sim-bokeh));
  -webkit-backdrop-filter: blur(var(--sim-bokeh));
  mask-image: radial-gradient(ellipse 46% 52% at 50% 46%,
                              transparent 55%, #000 100%);
  -webkit-mask-image: radial-gradient(ellipse 46% 52% at 50% 46%,
                                      transparent 55%, #000 100%);
  pointer-events: none;
  z-index: 1;
}

/* soft-light, no overlay: sobre una foto clara como ésta, overlay se comía la
   textura del grano y el resultado era que subir el ISO sólo aclaraba la imagen.
   Con soft-light el grano se lee sobre el fondo y sobre la piel sin lavar tanto
   las sombras. Ver el módulo 02: el ISO alto tiene que verse como degradación. */
.consola__grano {
  position: absolute;
  inset: 0;
  z-index: 2;
  opacity: var(--sim-grano);
  filter: url(#sim-grano-filtro);
  mix-blend-mode: soft-light;
  pointer-events: none;
}

.consola__temperatura {
  position: absolute;
  inset: 0;
  z-index: 3;
  background: var(--sim-temp-color);
  opacity: var(--sim-temp-fuerza);
  mix-blend-mode: overlay;
  pointer-events: none;
  transition: background 160ms linear, opacity 160ms linear;
}

/* el preset "cine" agrega una leve dominante fría en las sombras */
.consola__vista[data-color="cine"] .consola__foto {
  filter: brightness(var(--sim-brillo))
          contrast(var(--sim-contraste))
          saturate(var(--sim-saturacion))
          sepia(0.12)
          url(#sim-motion-blur);
}

.consola__faders {
  display: grid;
  grid-template-columns: repeat(5, 1fr);
  gap: 10px;
}

.fader {
  display: grid;
  justify-items: center;
  gap: 10px;
  padding: 14px 6px;
  border: 1px solid var(--borde);
  border-radius: 10px;
  background: rgba(255, 255, 255, 0.015);
  transition: border-color var(--transicion), background var(--transicion);
}

.fader:focus-within {
  border-color: var(--amarillo);
  background: rgba(255, 224, 27, 0.05);
}

/* Las etiquetas y lecturas de los faders heredan .mono, que aplica
   text-transform: uppercase. En fotografía el número f va en minúscula: "f/2",
   nunca "F/2". Esta landing enseña cámara, así que la notación importa. */
.fader__etiqueta,
.fader__lectura { text-transform: none; }

.fader__etiqueta { font-size: 0.5625rem; }

.fader__lectura {
  font-size: 0.6875rem;
  color: var(--amarillo);
  letter-spacing: 0.08em;
  min-height: 1em;
}

.fader__control {
  writing-mode: vertical-lr;
  direction: rtl;
  width: 26px;
  height: 118px;
  accent-color: var(--amarillo);
  cursor: ns-resize;
}

@media (max-width: 760px) {
  .consola__faders { grid-template-columns: 1fr; }
  .fader { grid-template-columns: 64px 1fr 64px; align-items: center;
           justify-items: start; }
  /* 44 px de alto: es la interacción central de la página y en móvil se toca
     con el dedo. Antes eran 26 px, por debajo del mínimo recomendado. */
  .fader__control { writing-mode: horizontal-tb; direction: ltr;
                    width: 100%; height: 44px; cursor: ew-resize; }
  .fader__lectura { justify-self: end; }
}

.consola__sinjs {
  margin: 0;
  padding: 14px;
  border: 1px solid var(--borde);
  border-radius: 10px;
  text-align: center;
  font-family: var(--mono);
  font-size: 0.75rem;
  letter-spacing: 0.02em;
  color: var(--blanco-70);
}

.consola__modulo {
  display: grid;
  grid-template-columns: auto 1fr;
  gap: 20px;
  align-items: start;
  max-width: 960px;   /* mismo ancho que la consola, para que lean como un bloque */
  margin: 18px auto 0;
  padding: 20px 22px;
  border: 1px solid var(--borde);
  border-left: 2px solid var(--amarillo);
  border-radius: 10px;
  background: var(--negro-2);
  opacity: 0;
  transform: translateY(8px);
  transition: opacity 260ms ease-out, transform 260ms ease-out;
}

.consola__modulo.modulo--visible { opacity: 1; transform: none; }

.modulo__numero {
  font-size: 2.75rem;
  line-height: 1;
  color: var(--amarillo);
  opacity: 0.35;
}

.consola__modulo h3 { margin-block: 6px 8px; }

@media (max-width: 560px) {
  .consola__modulo { grid-template-columns: 1fr; gap: 10px; }
}

/* ---------- proyectos ---------- */

.proyectos__grilla {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: 16px;
}

.proyecto {
  position: relative;
  margin: 0;
  border-radius: var(--radio);
  overflow: hidden;
  aspect-ratio: 2 / 3;
  border: 1px solid var(--borde);
}

.proyecto img {
  width: 100%;
  height: 100%;
  object-fit: cover;
  transition: transform 600ms cubic-bezier(0.22, 1, 0.36, 1);
}

.proyecto:hover img { transform: scale(1.05); }

.proyecto figcaption {
  position: absolute;
  inset: auto 0 0 0;
  display: grid;
  gap: 4px;
  padding: 18px;
  background: linear-gradient(to top, rgba(10, 10, 10, 0.92), transparent);
}

.proyecto__rol { color: var(--amarillo); font-size: 0.5625rem; }

.proyecto__nota { font-size: 0.875rem; color: var(--blanco); }

@media (max-width: 900px) {
  .proyectos__grilla { grid-template-columns: repeat(2, 1fr); }
}

@media (max-width: 560px) {
  .proyectos__grilla { grid-template-columns: 1fr; }
}

/* ---------- módulos ---------- */

.modulos__grilla {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: 16px;
}

.modulo-tarjeta {
  position: relative;
  padding: 28px 24px 26px;
  border: 1px solid var(--borde);
  border-radius: var(--radio);
  background: var(--negro-2);
  overflow: hidden;
  transition: border-color var(--transicion), transform var(--transicion);
}

.modulo-tarjeta:hover {
  border-color: rgba(255, 224, 27, 0.4);
  transform: translateY(-3px);
}

.modulo-tarjeta__numero {
  position: absolute;
  top: 10px;
  right: 16px;
  font-size: 3.5rem;
  line-height: 1;
  color: var(--amarillo);
  opacity: 0.14;
}

.modulo-tarjeta h3 { margin-bottom: 10px; max-width: 82%; }

@media (max-width: 900px) { .modulos__grilla { grid-template-columns: 1fr 1fr; } }
@media (max-width: 560px) { .modulos__grilla { grid-template-columns: 1fr; } }

/* ---------- testimonios ---------- */

.testimonios__grilla,
.numeros__grilla {
  display: grid;
  gap: 16px;
}

.testimonios__grilla { grid-template-columns: repeat(3, 1fr); }

.testimonio {
  margin: 0;
  padding: 26px;
  border: 1px solid var(--borde);
  border-radius: var(--radio);
  background: var(--negro-2);
}

.testimonio footer { margin-top: 16px; }

/* ---------- números ---------- */

.numeros { padding-block: 60px; border-block: 1px solid var(--borde); }

.numeros__grilla { grid-template-columns: repeat(4, 1fr); text-align: center; }

.numero { display: grid; gap: 6px; }

.numero__valor { font-size: clamp(2.5rem, 6vw, 4rem); color: var(--amarillo); }

/* ---------- preguntas frecuentes ---------- */

.faq__lista { display: grid; gap: 10px; max-width: 780px; }

.faq details {
  border: 1px solid var(--borde);
  border-radius: var(--radio);
  background: var(--negro-2);
}

/* El padding va en el <summary>, no en el <details>: puesto en el contenedor,
   los ~18 px de arriba y abajo de cada pregunta quedaban muertos, fuera del
   área clicable. `min-height: 44px` asegura el objetivo táctil mínimo. */
.faq summary {
  cursor: pointer;
  font-weight: 600;
  list-style: none;
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 16px;
  min-height: 44px;
  padding: 12px 22px;
  border-radius: var(--radio);
}

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

.faq summary::after {
  content: '+';
  color: var(--amarillo);
  font-size: 1.25rem;
  line-height: 1;
}

.faq details[open] summary::after { content: '−'; }

.faq details p { margin-top: 0; padding: 2px 22px 18px; }

/* ---------- cierre y pie ---------- */

.cierre { position: relative; text-align: center; overflow: hidden;
          padding-block: 120px; }

.cierre__glow {
  position: absolute;
  top: 50%; left: 50%;
  transform: translate(-50%, -50%);
  width: 620px; height: 620px;
  border-radius: 50%;
  background: var(--glow);
  filter: blur(150px);
  pointer-events: none;
}

.cierre__interior { position: relative; }

.cierre h2 { margin-block: 20px 18px; }

.cierre .seccion__bajada { margin-inline: auto; max-width: 46ch; }

.cierre__acciones { justify-content: center; margin-top: 32px; }

.pie { border-top: 1px solid var(--borde); padding-block: 34px; }

.pie__interior {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 16px;
  flex-wrap: wrap;
}

@media (max-width: 900px) {
  .testimonios__grilla { grid-template-columns: 1fr; }
  .numeros__grilla { grid-template-columns: repeat(2, 1fr); gap: 28px; }
}

/* ---------- movimiento reducido ---------- */

@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;
  }
}
