/* ============================================================
   FestFlow — Variante A · «Nuit de festival»
   Identidad ACTUAL conservada (naranja FestFlow, fondo nocturno,
   Space Grotesk + Inter). Lo que cambia es la estructura: menos
   cristal y gradiente decorativo, más jerarquía tipográfica y
   más aire. El naranja se reserva para lo que hay que pulsar.
   ============================================================ */

:root {
  /* --- Marca (sin tocar) --- */
  --orange: #f06640;
  --orange-soft: #ff8a68;
  --amber: #f5a623;

  /* --- Fondo nocturno, con sesgo cálido para no ser gris muerto --- */
  --ink-900: #0b0b12;
  --ink-800: #12121c;
  --ink-700: #191926;
  --ink-600: #23233442;
  --line: rgba(255, 255, 255, 0.09);
  --line-strong: rgba(255, 255, 255, 0.16);

  --text: #f4f2f0;
  --text-soft: #a8a6b3;
  /* #74727f daba 3.95:1 sobre --ink-800 y 4.16:1 sobre --ink-900: por debajo
     del mínimo WCAG AA (4.5:1) en TODO lo que lo usa — pies de captura, sellos
     de rol, notas del formulario y el copyright. Medido con la fórmula WCAG
     sobre el fondo compuesto real, #8c8a96 da 5.78 (ink-900), 5.48 (ink-800),
     5.12 (ink-700) y 4.95 sobre la banda del assess, que es el fondo más claro
     donde cae. Sigue leyéndose como texto secundario: --text-soft está en 7.8. */
  --text-dim: #8c8a96;

  --teal: #50c9b0;

  --r-sm: 10px;
  --r-md: 16px;
  --r-lg: 26px;

  --step--1: clamp(0.82rem, 0.79rem + 0.15vw, 0.9rem);
  --step-0: clamp(1rem, 0.96rem + 0.2vw, 1.09rem);
  --step-1: clamp(1.2rem, 1.1rem + 0.5vw, 1.45rem);
  --step-2: clamp(1.5rem, 1.3rem + 1vw, 2rem);
  --step-3: clamp(2rem, 1.6rem + 2vw, 3rem);
  --step-4: clamp(2.6rem, 1.9rem + 3.4vw, 4.6rem);

  --pad: clamp(1.25rem, 4vw, 2.5rem);
  --gap: clamp(1.5rem, 3vw, 2.75rem);
  --section: clamp(4.5rem, 9vw, 8rem);
  --maxw: 1180px;
}

/* --- Ancho por tramos, no ancho completo ---------------------------------
   En un monitor de 3800 px, 1180 px de contenido dejaban la página como una
   columna estrecha flotando en el vacío. La respuesta NO es quitar el tope:
   una línea de texto de 3800 px es ilegible, la medida cómoda son 65-75
   caracteres.

   Lo que se ensancha son las REJILLAS y las tarjetas; el texto corrido ya está
   topado en `ch` allá donde vive (`.lede` 62ch, `.hero__sub` 56ch,
   `.hook__bridge` 48ch, `.assess-band > div` 54ch), así que subir `--maxw` le
   da más columnas de aire sin estirar ni una frase.

   Los dos escalones y por qué esos números:

   · Hasta 1400 px no cambia NADA. Un portátil de 13-16" (1280-1440 px de
     viewport) ve exactamente la misma página que hoy.
   · 1400 px → 1440 px de tope. `.wrap` es `min(100% - pad*2, --maxw)`, así que
     entre 1400 y 1520 px sigue mandando el gutter y el ensanchamiento entra
     progresivamente, sin salto. Con 1440 la rejilla de 3 columnas da columnas
     de 479 px: el texto de tarjeta (`--step--1`, ~14,4 px) cae en ~59
     caracteres de medida útil.
   · 1800 px → 1600 px de tope. Es el último escalón que aguanta la medida:
     columnas de 533 px → ~64 caracteres en las tarjetas de 3 columnas y 62ch
     topados en las de 2 (`.gain p`, abajo). Por encima de 1600 las tarjetas
     empezarían a pasar de 75 caracteres, que es donde el ojo pierde el
     renglón, y lo correcto es dejar margen — no llenarlo.

   1600 px sobre 3800 px sigue siendo una columna centrada, sí: es lo que debe
   ser. Lo que se corrige es que el salto de 1180 a 1600 son +36 % de superficie
   útil para rejillas y capturas, que es lo que se veía escaso. */
@media (min-width: 1400px) { :root { --maxw: 1440px; } }
@media (min-width: 1800px) { :root { --maxw: 1600px; } }

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

body {
  margin: 0;
  background: var(--ink-900);
  color: var(--text);
  font-family: 'Inter', -apple-system, BlinkMacSystemFont, system-ui, sans-serif;
  font-size: var(--step-0);
  line-height: 1.6;
  -webkit-font-smoothing: antialiased;
  overflow-x: hidden;
}

h1, h2, h3, .display {
  font-family: 'Space Grotesk', 'Inter', sans-serif;
  font-weight: 700;
  line-height: 1.08;
  letter-spacing: -0.022em;
  text-wrap: balance;
  margin: 0;
  /* El alemán compone palabras que no caben: «Warteschlange» pedía 302 px en el
     h1 de un móvil de 320, donde el `.wrap` da 280. Como `body` lleva
     `overflow-x: hidden`, no salía una barra de scroll — salía la palabra
     CORTADA por el borde derecho, que es peor porque no se ve el fallo.
     `hyphens: auto` corta por sílaba de verdad, y funciona porque el cargador
     de idioma pone `<html lang>` al idioma activo; `overflow-wrap` es la red
     por si el navegador no tiene diccionario para ese idioma. */
  hyphens: auto;
  overflow-wrap: break-word;
}
h1 { font-size: var(--step-4); }
h2 { font-size: var(--step-3); }
h3 { font-size: var(--step-1); }
p { margin: 0; }
/* height:auto es obligatorio: con width/height en el HTML (que evitan el salto
   de layout al cargar), sin esto el alto del atributo gana y la imagen se
   estira. */
img { max-width: 100%; height: auto; display: block; }
a { color: inherit; }

.wrap { width: min(100% - var(--pad) * 2, var(--maxw)); margin-inline: auto; }
.section { padding-block: var(--section); }
.stack { display: flex; flex-direction: column; gap: var(--gap); }
.lede { font-size: var(--step-1); color: var(--text-soft); max-width: 62ch; line-height: 1.5; }

/* ---------- Eyebrow: nombra la sección, no decora ---------- */
.eyebrow {
  font-family: 'Space Grotesk', sans-serif;
  font-size: var(--step--1);
  font-weight: 600;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  color: var(--orange);
  display: flex;
  align-items: center;
  gap: 0.7em;
}
.eyebrow::after {
  content: '';
  flex: 1;
  height: 1px;
  background: var(--line);
  max-width: 8rem;
}

/* ---------- Navegación ---------- */
.nav {
  position: sticky; top: 0; z-index: 50;
  background: rgba(11, 11, 18, 0.82);
  -webkit-backdrop-filter: blur(14px);
  backdrop-filter: blur(14px);
  border-bottom: 1px solid var(--line);
}
.nav__inner {
  display: flex; align-items: center;
  /* `position: relative` ancla el panel de idiomas al ANCHO DE CONTENIDO, no al
     botón que lo abre. Anclado al botón, a 320 px el panel (184 px) sobresale
     por la IZQUIERDA; como `body` lleva `overflow-x: hidden`, no saldría barra
     de scroll — saldría el panel recortado, que es peor porque no se ve. */
  position: relative;
  gap: clamp(0.75rem, 0.4rem + 1.5vw, 1.5rem);
  padding-block: clamp(0.6rem, 0.42rem + 0.55vw, 0.9rem);
}
/* El <a> del logo es un ítem flex y encoge por defecto: a 390 px se quedaba en
   12,9 px de ancho (relación natural 2.796 → pedía 83,9) y el logo se veía como
   una tira de píxeles. flex:none en el ancla, y min-width en la imagen para que
   ni siquiera un cambio futuro del contenido de al lado la vuelva a comprimir. */
.nav__inner > a:first-child { flex: none; display: flex; }
/* 40 px, no 30: es la altura que ya tiene el logo en la pantalla del
   diagnóstico (`className="h-10"` en src/pages/Assess.tsx) y las dos caras de
   FestFlow tienen que verse iguales. La relación natural del PNG es 2,796, así
   que 40 px de alto son 112 px de ancho — de ahí el min-width, que existe para
   que el logo no se comprima a una tira si algo cambia a su lado.

   Medido en las 5 páginas y los 5 idiomas: a 320, 360 y 390 px la cabecera mide
   exactamente lo mismo que con 30 px (118 px), porque ahí el selector de idioma
   ya bajaba de línea por el `flex-wrap` de `.nav__right` y el logo más alto cabe
   dentro de esa altura. Cero desbordes en cualquier ancho.

   Lo único que cambia: entre 400 y 479 px de viewport la cabecera pasa de 85 a
   119 px en fr/en/es/it, porque los 28 px extra de ancho del logo empujan el
   selector a su propia línea. En alemán ya envolvía ahí («Sprechen wir darüber»
   es largo), así que no es un caso nuevo sino el comportamiento previsto de la
   cabecera, ahora en una franja algo más ancha. Se acepta a cambio de que el
   logo se lea. */
.nav__logo { height: 40px; width: auto; flex: none; min-width: 112px; }
.nav__links { display: none; gap: 1.6rem; margin-left: auto; font-size: var(--step--1); }
.nav__links a { color: var(--text-soft); text-decoration: none; }
.nav__links a:hover { color: var(--text); }
/* Página actual, marcada en la navegación y en el pie. Solo color: no cambia
   layout. Vivía en un <style> suelto de food-trucks.html; aquí sirve a las 4. */
.nav__links a[aria-current="page"],
.footer a[aria-current="page"] { color: var(--orange); }
/* `flex-wrap` no es decorativo: en un móvil estrecho no caben a la vez el logo,
   los cinco idiomas y el botón, y el que se salía era el botón (el que vende).
   Envolviendo, los idiomas bajan a su propia línea en vez de empujar nada fuera
   de la pantalla. Y aguanta que el texto del botón crezca al traducirlo, que es
   justo lo que va a pasar: «Parlons-en» es de las formas cortas. */
.nav__right {
  margin-left: auto; display: flex; align-items: center; justify-content: flex-end;
  flex-wrap: wrap; gap: 0.35rem 0.5rem;
}
/* (los enlaces de sección aparecen a 1000 px — ver el bloque de escritorio) */
/* El `nowrap` NO puede encenderse a la vez que `.nav__links`: a 900 px se
   suman los cuatro enlaces de sección, los cinco idiomas y el botón, y en
   alemán («Sprechen wir darüber», 228 px con `.btn { white-space: nowrap }`)
   eso no cabe. Medido antes de este cambio: 900 px → 60 px de desborde
   horizontal, 940 → 24, 960 → 6, limpio solo a partir de 968. La franja
   900-964 px es tablet en horizontal, y lo que se salía de la pantalla era
   justo el CTA. Entre 900 y 1000 se deja envolver: los idiomas bajan a su
   propia línea, que es lo que ya hacen en móvil. Solo idioma afectado: DE. */
/* (el nowrap de .nav__right se fija abajo, junto al resto del escritorio) */
/* El otro extremo: por debajo de 400 px el botón de la cabecera mide 216 px y
   el logo 112, y el `.wrap` de un móvil de 320 px son 280. Ahí no caben en una
   línea ni envolviendo los idiomas, así que además se le encoge el relleno. */
/* El CTA compacto vivía en `max-width: 399px`. Se amplía a 600 porque entre
   400 y 479 el botón recuperaba tamaño y volvía a partir la cabecera en dos
   filas (medido en alemán: 114 px a 412 y a 430). */
@media (max-width: 599.98px) {
  .nav__right .btn { font-size: var(--step--1); padding-inline: 0.95rem; }
}

/* Selector de idioma. Estuvo retirado del HTML entre el 18 y el 20 de ago 2026
   porque no había ni un solo fichero de idioma: cambiar de idioma daba un 404 y
   dejaba la página en francés. Vuelve el 20 ago 2026, con el francés cargándose
   ya desde `/shared/i18n/fr.json` (lo genera `scripts/extract-landing-i18n.cjs`)
   y el cargador enchufado en las cinco páginas. Mientras falten en/de/es/it,
   esos cuatro caen a francés — ver § Estado del multiidioma en el README.

   En móvil se encoge y baja de línea (`flex-wrap` de `.nav__right`) en vez de
   ocultarse: es la única forma de cambiar de idioma desde un móvil. La nav de
   secciones sí puede desaparecer bajo 900 px porque repite sus enlaces en el
   pie; el idioma no está en ningún otro sitio. */
/* POR QUÉ EL ESTADO POR DEFECTO ES «DESPLEGADO» Y LO PLIEGA EL JS.
   Sin `loader.js` esta web ya es monolingüe: los cinco botones son <button>
   inertes cuyo handler lo pone ese script, y `?lang=` también lo lee él. Si el
   control naciera plegado y lo desplegara el JS, un fallo de carga escondería
   ADEMÁS la única pista de que la web habla cinco idiomas. Naciendo desplegado,
   el peor caso es EXACTAMENTE la cabecera anterior: la misma fila de cinco,
   igual de inerte. La clase `js` la pone un <script> en línea del <head>, así
   que el plegado ocurre antes del primer pintado — ni parpadeo ni salto.

   Y por qué no <details>/<summary>, que es la respuesta de manual: desde
   Chrome 131 el contenido cerrado se oculta con `content-visibility: hidden`
   sobre `::details-content` y un `display: flex` en el hijo NO lo revierte,
   así que no se puede forzar ABIERTO por CSS en escritorio sin duplicar el
   marcado. Tampoco cierra con Escape ni al pulsar fuera. Y `:focus-within`
   tampoco sirve: Safari no lleva el foco a un <button> al pulsarlo, con lo que
   el panel no abriría en iPhone — justo el aparato de la queja. */
.langs {
  display: flex; gap: 0.15rem; flex: none;
  /* Explícito a propósito: si alguien le pone `position: relative`, el panel se
     ancla al botón y vuelve el recorte silencioso de 320 px. */
  position: static;
}
.langs__list { display: flex; gap: 0.15rem; }
.langs__list button {
  background: none; border: 0; cursor: pointer; padding: 0.3rem;
  color: var(--text-dim); font: inherit; font-size: 0.72rem; text-transform: uppercase;
  border-radius: 6px; letter-spacing: 0.04em;
}
.langs__list button:hover { color: var(--text); }
.langs__list button.active { color: var(--orange); font-weight: 600; }
.langs__list button:focus-visible,
.langs__toggle:focus-visible { outline: 2px solid var(--orange); outline-offset: 2px; }
/* El nombre largo solo se usa dentro del panel plegable; en la fila de
   escritorio manda el código de dos letras, como hasta ahora. */
.langs__name { display: none; }
/* Sin JS no hay disparador: ver el comentario de arriba. */
.langs__toggle { display: none; }

/* Utilidad que no existía en esta hoja. */
.sr-only {
  position: absolute; width: 1px; height: 1px; padding: 0; margin: -1px;
  overflow: hidden; clip-path: inset(50%); white-space: nowrap; border: 0;
}

/* ---------- Por debajo de 1000 px: cabecera de UNA sola fila ----------

   El diagnóstico intuitivo era que la culpa la tenía el logo. Medido, no:
   con el logo a 36 px la cabecera alemana seguía en 119 px a 320. Lo que fija
   la altura es el ANCHO DEL CTA TRADUCIDO. A 390 px de viewport hay 350 px
   útiles y las tres piezas pedían 428 (fr) o 511 (de). Plegando los cinco
   idiomas a una píldora se liberan ~70 px, que es lo que hace posible la fila
   única. */
@media (max-width: 999.98px) {
  /* El CTA es «el que vende» y no puede bajar de línea ni empujar al selector
     fuera de la fila. Con `nowrap` + `min-width: 0`, si algún día no cabe, el
     que cede es el TEXTO del botón (que envuelve dentro) y no la estructura de
     la cabecera. */
  .nav__right { flex-wrap: nowrap; }
  .nav__right .btn { min-height: 44px; padding-block: 0.45rem; line-height: 1.25; min-width: 0; }

  html.js .langs__toggle {
    display: inline-flex; align-items: center; gap: 0.3rem;
    min-height: 44px; padding: 0.3rem 0.55rem;
    background: none; cursor: pointer; font: inherit;
    font-size: 0.78rem; font-weight: 600; letter-spacing: 0.04em;
    text-transform: uppercase; color: var(--text-soft);
    /* 0.38 y no `--line-strong` (0.16): sobre `--ink-900` el borde a 0.16 da
       1,9:1 y a 0.38 da 3,5:1, el mínimo de WCAG 1.4.11 para el contorno de un
       control. Importa más aquí que en ningún otro sitio, porque este control es
       la ÚNICA vía para cambiar de idioma en móvil. */
    border: 1px solid rgba(255, 255, 255, 0.38); border-radius: 999px;
  }
  /* Triángulo de despliegue. Un globo terráqueo pedía 20 px más y dice
     «idiomas»; el código activo ya lo dice, y el triángulo dice «esto se
     abre», que es lo que faltaba. */
  html.js .langs__toggle::after {
    content: ''; width: 0; height: 0;
    border-left: 4px solid transparent; border-right: 4px solid transparent;
    border-top: 5px solid currentColor;
  }

  html.js .langs__list {
    position: absolute; top: calc(100% - 0.2rem); right: 0; z-index: 60;
    display: none; flex-direction: column; gap: 0.1rem;
    min-width: 11.5rem; padding: 0.4rem;
    /* Fondo OPACO, no el rgba de la cabecera: el panel flota sobre el contenido
       y con transparencia el texto se vuelve ilegible justo encima de una
       captura clara. */
    background: var(--ink-800); border: 1px solid rgba(255, 255, 255, 0.38);
    border-radius: 14px; box-shadow: 0 18px 44px rgba(0, 0, 0, 0.55);
  }
  html.js .langs[data-open='true'] .langs__list { display: flex; }

  html.js .langs__list button {
    display: flex; align-items: center; gap: 0.6rem;
    width: 100%; min-height: 44px; padding: 0.5rem 0.7rem;
    border-radius: 10px; font-size: 1rem;
    text-transform: none; letter-spacing: 0; text-align: left;
  }
  html.js .langs__list .langs__code {
    font-size: 0.72rem; letter-spacing: 0.04em; color: var(--text-dim); min-width: 1.6em;
  }
  html.js .langs__list button.active .langs__code { color: var(--orange); }
  /* El idioma activo se marcaba SOLO con color (naranja y negrita), que es justo
     lo que WCAG 1.4.1 no admite como único indicador. La marca de verificación
     lo dice sin depender del color; `aria-current`, sin depender de la vista. */
  html.js .langs__list button.active::after {
    content: ''; margin-left: auto; width: 0.75rem; height: 0.42rem;
    border-left: 2px solid var(--orange); border-bottom: 2px solid var(--orange);
    transform: rotate(-45deg);
  }
  html.js .langs__list .langs__name { display: inline; }
}

/* ---------- 1000 px: escritorio ----------
   Sustituye a los tres bloques que había. Los cuatro enlaces de sección
   aparecen a 1000 y no a 900 porque a 900 piden ~555 px y, sumados al CTA,
   partían la cabecera en dos filas de 130 px — el peor caso real de toda la
   web, y uno que plegar el idioma NO arregla por sí solo. Entre 900 y 999 px
   se comportan como en móvil, que es legítimo: esos cuatro enlaces se repiten
   íntegros en el pie. El idioma no, y por eso el idioma no se oculta nunca. */
@media (min-width: 1000px) {
  .nav__links { display: flex; }
  .nav__right { margin-left: 0; gap: 0.75rem; flex-wrap: nowrap; }
  .langs__list button { padding: 0.3rem 0.45rem; font-size: var(--step--1); }
}

/* Coherente con el resto de la hoja: la animación es opt-in. */
@media (prefers-reduced-motion: no-preference) {
  html.js .langs[data-open='true'] .langs__list { animation: langs-in 0.16s ease-out; }
}
@keyframes langs-in {
  from { opacity: 0; transform: translateY(-0.35rem); }
  to   { opacity: 1; transform: none; }
}

/* ---------- Botones ---------- */
.btn {
  display: inline-flex; align-items: center; justify-content: center; gap: 0.55rem;
  padding: 0.85rem 1.5rem; border-radius: 999px; border: 1px solid transparent;
  font-family: 'Space Grotesk', sans-serif; font-weight: 600; font-size: var(--step-0);
  text-decoration: none; cursor: pointer; white-space: nowrap;
  transition: transform 0.18s ease, background 0.18s ease, border-color 0.18s ease;
}
/* En un móvil de 320 px el `.wrap` son 280 px y hay etiquetas traducidas que no
   caben de ninguna manera: «Let’s talk about your project» pide 329 px con
   `.btn--lg`, y con `white-space: nowrap` se salía 29 px de la pantalla (32 en
   alemán) en las cuatro sub-webs. Medido con los cinco ficheros de idioma ya
   cargados — con la web solo en francés esto no se veía, y por eso pasó la
   revisión anterior.
   Dejar envolver no cambia nada cuando el texto cabe: solo actúa justo en el
   caso en el que la alternativa era desbordar. Por encima de 480 px se
   mantiene el `nowrap`, que es lo que garantiza la píldora de una línea. */
@media (max-width: 479px) {
  .btn { white-space: normal; text-align: center; }
}
.btn:focus-visible { outline: 2px solid var(--orange); outline-offset: 3px; }
.btn--primary { background: var(--orange); color: #1a0d07; }
.btn--primary:hover { background: var(--orange-soft); }
.btn--ghost { border-color: var(--line-strong); color: var(--text); }
.btn--ghost:hover { border-color: var(--orange); color: var(--orange); }
.btn--lg { padding: 1rem 1.9rem; font-size: var(--step-1); }
@media (prefers-reduced-motion: no-preference) { .btn:hover { transform: translateY(-1px); } }

.btn-row { display: flex; flex-wrap: wrap; gap: 0.85rem; align-items: center; }

/* ---------- Hero ---------- */
.hero { padding-block: clamp(3.5rem, 8vw, 7rem) var(--section); position: relative; }
.hero::before {
  content: ''; position: absolute; inset: 0 0 auto; height: 480px; pointer-events: none;
  background: radial-gradient(ellipse 70% 100% at 15% 0%, rgba(240, 102, 64, 0.13), transparent 65%);
}
.hero > * { position: relative; }
.hero__title { max-width: 17ch; }
/* Titular largo (el de festivales de food trucks tiene 92 caracteres frente a
   los 35 de la home): un escalón menos y más medida, o son seis líneas. */
.hero__title--long { font-size: var(--step-3); max-width: 22ch; }
.hero__sub { font-size: var(--step-1); color: var(--text-soft); max-width: 56ch; line-height: 1.5; }

/* ---------- Selector de público (home) ---------- */
.audience { display: grid; gap: 1rem; grid-template-columns: 1fr; }
@media (min-width: 720px) { .audience { grid-template-columns: 1fr 1fr; } }

.card-audience {
  display: flex; flex-direction: column; gap: 0.7rem;
  padding: clamp(1.4rem, 3vw, 2.1rem);
  background: var(--ink-800); border: 1px solid var(--line); border-radius: var(--r-lg);
  text-decoration: none; color: inherit;
  transition: border-color 0.2s ease, background 0.2s ease, transform 0.2s ease;
}
.card-audience:hover { border-color: var(--orange); background: var(--ink-700); }
@media (prefers-reduced-motion: no-preference) { .card-audience:hover { transform: translateY(-3px); } }
.card-audience__icon { font-size: 1.9rem; line-height: 1; }
.card-audience h3 { font-size: var(--step-1); }
.card-audience p { color: var(--text-soft); font-size: var(--step-0); }
.card-audience__cta {
  margin-top: auto; padding-top: 0.6rem; color: var(--orange);
  font-family: 'Space Grotesk', sans-serif; font-weight: 600; font-size: var(--step--1);
  display: inline-flex; align-items: center; gap: 0.4rem;
}
.card-audience:hover .card-audience__cta { gap: 0.7rem; }

/* ---------- Pasos: la numeración es real (es una secuencia) ---------- */
.steps { display: grid; gap: 1.5rem; counter-reset: step; }
@media (min-width: 760px) { .steps { grid-template-columns: repeat(4, 1fr); } }
.step { display: flex; flex-direction: column; gap: 0.55rem; padding-top: 1.1rem; border-top: 2px solid var(--line); }
.step::before {
  counter-increment: step; content: counter(step, decimal-leading-zero);
  font-family: 'Space Grotesk', sans-serif; font-size: var(--step--1); font-weight: 700;
  color: var(--orange); letter-spacing: 0.1em;
}
.step h3 { font-size: var(--step-0); font-weight: 700; }
.step p { color: var(--text-soft); font-size: var(--step--1); line-height: 1.55; }

/* ---------- Beneficios por rol ---------- */
.roles { display: grid; gap: 1.25rem; }
@media (min-width: 860px) { .roles { grid-template-columns: repeat(3, 1fr); } }
.role {
  padding: clamp(1.4rem, 2.5vw, 2rem); border-radius: var(--r-md);
  background: var(--ink-800); border: 1px solid var(--line);
  display: flex; flex-direction: column; gap: 1rem;
}
/* Las tres tarjetas de rol se ven igual: destacar solo la del organizador
   hacía leer las otras dos como secundarias, y las tres venden a la vez.
   Lo único que se mantiene en naranja es la etiqueta de rol. */
.role--you { border-color: var(--line); background: var(--ink-800); }
.role__label {
  font-family: 'Space Grotesk', sans-serif; font-size: var(--step--1); font-weight: 600;
  letter-spacing: 0.12em; text-transform: uppercase; color: var(--text-dim);
}
.role--you .role__label { color: var(--orange); }
.role h3 { font-size: var(--step-1); }
.role ul { list-style: none; margin: 0; padding: 0; display: flex; flex-direction: column; gap: 0.65rem; }
.role li { display: flex; gap: 0.65rem; color: var(--text-soft); font-size: var(--step--1); line-height: 1.5; }
.role li::before { content: '—'; color: var(--orange); flex-shrink: 0; }

/* ---------- Features ---------- */
.features { display: grid; gap: 1px; background: var(--line); border: 1px solid var(--line); border-radius: var(--r-md); overflow: hidden; }
@media (min-width: 640px) { .features { grid-template-columns: 1fr 1fr; } }
@media (min-width: 1000px) { .features { grid-template-columns: repeat(3, 1fr); } }
.feature { background: var(--ink-800); padding: clamp(1.3rem, 2.4vw, 1.8rem); display: flex; flex-direction: column; gap: 0.5rem; }
.feature h3 { font-size: var(--step-0); font-weight: 700; }
.feature p { color: var(--text-soft); font-size: var(--step--1); line-height: 1.55; }

/* ---------- Prueba: capturas reales ---------- */
.proof { display: grid; gap: var(--gap); align-items: center; }
@media (min-width: 900px) { .proof { grid-template-columns: 1fr 1fr; } }
/* La tablet es la base; el móvil se apoya delante, a la derecha. Los anchos
   suman 100% contando el solape negativo: así nunca desborda su columna. */
.shots { display: flex; align-items: flex-end; justify-content: center; }
.tablet {
  width: 74%; max-width: 470px; border-radius: 12px; overflow: hidden;
  border: 8px solid #1c1c28; box-shadow: 0 26px 60px rgba(0, 0, 0, 0.5);
  background: var(--ink-800); flex-shrink: 0;
}
.phone {
  width: 36%; max-width: 205px; margin-left: -10%; margin-bottom: -1.5rem;
  border-radius: 22px; overflow: hidden; position: relative; z-index: 2;
  border: 6px solid #1c1c28; box-shadow: 0 26px 60px rgba(0, 0, 0, 0.6);
  background: var(--ink-800); flex-shrink: 0;
}
.shot-caption {
  color: var(--text-dim); font-size: var(--step--1); text-align: center;
  margin-top: 2.4rem; max-width: 70ch; margin-inline: auto;
}

/* ---------- Franja de confianza ---------- */
.trust { display: grid; gap: 1.5rem; }
@media (min-width: 700px) { .trust { grid-template-columns: repeat(2, 1fr); } }
@media (min-width: 1000px) { .trust { grid-template-columns: repeat(3, 1fr); } }
.trust-item { display: flex; flex-direction: column; gap: 0.4rem; padding-left: 1rem; border-left: 2px solid var(--orange); }
.trust-item h3 { font-size: var(--step-0); font-weight: 700; }
.trust-item p { color: var(--text-soft); font-size: var(--step--1); line-height: 1.55; }

/* ---------- CTA final + formulario ---------- */
.cta-band { background: var(--ink-800); border-block: 1px solid var(--line); }
.contact { display: grid; gap: var(--gap); }
@media (min-width: 900px) { .contact { grid-template-columns: 0.9fr 1.1fr; align-items: start; } }
/* Con el tope ancho, la columna de 1.1fr medía 836 px y el formulario —topado a
   34rem— se quedaba pegado a su izquierda con 300 px de vacío a la derecha, que
   se leía como un desalineado. Se le da a la columna EXACTAMENTE el ancho del
   formulario: así queda a ras del borde derecho y el texto se come el resto. */
@media (min-width: 1400px) { .contact { grid-template-columns: minmax(0, 1fr) 34rem; } }

/* El formulario NO se ensancha con el resto. Su columna en `.contact` es la de
   1.1fr: con `--maxw` a 1600 serían campos de 856 px de ancho para escribir un
   nombre y un teléfono, que además alejan la etiqueta del final del campo. Un
   formulario estrecho es lo correcto; lo que gana ancho es la rejilla. */
.form { display: flex; flex-direction: column; gap: 0.9rem; max-width: 34rem; }
.field { display: flex; flex-direction: column; gap: 0.35rem; }
.field label { font-size: var(--step--1); color: var(--text-soft); font-weight: 500; }
.field input, .field select, .field textarea {
  background: var(--ink-900); border: 1px solid var(--line-strong); border-radius: var(--r-sm);
  padding: 0.75rem 0.9rem; color: var(--text); font: inherit; font-size: var(--step-0); width: 100%;
}
.field input:focus, .field select:focus, .field textarea:focus {
  outline: none; border-color: var(--orange); box-shadow: 0 0 0 3px rgba(240, 102, 64, 0.16);
}
.field textarea { resize: vertical; min-height: 96px; }
.field-row { display: grid; gap: 0.9rem; }
@media (min-width: 560px) { .field-row { grid-template-columns: 1fr 1fr; } }
.hp { position: absolute; left: -9999px; width: 0; height: 0; border: 0; padding: 0; }

.form-note { color: var(--text-dim); font-size: var(--step--1); }
.form-success, .form-error {
  display: flex; gap: 0.6rem; align-items: center; padding: 0.9rem 1.1rem;
  border-radius: var(--r-sm); font-size: var(--step--1);
}
.form-success { background: rgba(80, 201, 176, 0.1); border: 1px solid rgba(80, 201, 176, 0.28); color: var(--teal); }
.form-error { background: rgba(255, 107, 107, 0.1); border: 1px solid rgba(255, 107, 107, 0.28); color: #ff8f8f; }
.hidden { display: none; }

/* ---------- Banda del assess ---------- */
.assess-band {
  border: 1px solid var(--line-strong); border-radius: var(--r-lg);
  padding: clamp(1.5rem, 3vw, 2.4rem);
  display: flex; flex-wrap: wrap; gap: 1.25rem; align-items: center; justify-content: space-between;
  background: linear-gradient(120deg, rgba(240, 102, 64, 0.09), transparent 60%), var(--ink-800);
}
.assess-band > div { max-width: 54ch; display: flex; flex-direction: column; gap: 0.4rem; }
.assess-band p { color: var(--text-soft); font-size: var(--step--1); }

/* ---------- Pie ---------- */
.footer { border-top: 1px solid var(--line); padding-block: 2.5rem; color: var(--text-dim); font-size: var(--step--1); }
.footer__inner { display: flex; flex-wrap: wrap; gap: 1.25rem; justify-content: space-between; align-items: center; }
.footer a { color: var(--text-soft); text-decoration: none; margin-right: 1.1rem; }
.footer a:hover { color: var(--orange); }

/* ---------- Aparición al hacer scroll ---------- */
@media (prefers-reduced-motion: no-preference) {
  [data-reveal] { opacity: 0; transform: translateY(14px); transition: opacity 0.5s ease, transform 0.5s ease; }
  [data-reveal].in { opacity: 1; transform: none; }
}

/* ---------- Utilidades de composición ---------- */
.stack--tight { gap: 0.75rem; }
.stack--head { gap: 0.9rem; }
.section--flush { padding-top: 0; }

/* ---------- Lightbox de fonctionnalités ----------
   Cada tarjeta con captura es pulsable y enseña la pantalla real. */
.feature.is-clickable { cursor: zoom-in; position: relative; }
.feature.is-clickable:hover { background: var(--ink-700); }
.feature.is-clickable:focus-visible { outline: 2px solid var(--orange); outline-offset: -2px; }
.feature.is-clickable::after {
  content: '⤢'; position: absolute; top: 0.9rem; right: 1rem;
  color: var(--orange); font-size: var(--step--1); opacity: 0.55;
}
.feature.is-clickable:hover::after { opacity: 1; }

.lb {
  position: fixed; inset: 0; z-index: 100; display: flex; align-items: center; justify-content: center;
  background: rgba(6, 6, 10, 0.9); padding: clamp(1rem, 4vw, 3rem);
  -webkit-backdrop-filter: blur(6px); backdrop-filter: blur(6px);
}
.lb[hidden] { display: none; }
.lb__fig { margin: 0; display: flex; flex-direction: column; gap: 0.9rem; align-items: center; max-height: 100%; }
.lb__fig img {
  max-height: 78vh; width: auto; border-radius: var(--r-md);
  border: 1px solid var(--line-strong); box-shadow: 0 30px 80px rgba(0, 0, 0, 0.6);
}
.lb__fig figcaption { color: var(--text-soft); font-size: var(--step--1); text-align: center; max-width: 60ch; }
.lb__close {
  position: absolute; top: 1rem; right: 1.2rem; background: none; border: 0; cursor: pointer;
  color: var(--text); font-size: 2.2rem; line-height: 1; padding: 0.3rem 0.6rem;
}
.lb__close:focus-visible { outline: 2px solid var(--orange); outline-offset: 2px; }

/* ============================================================
   HOME v2 — el trabajo de la home es explicar el mecanismo
   ------------------------------------------------------------
   La v1 abría con una frase abstracta y escondía el producto al
   final. Aquí el hero muestra el producto al lado del mensaje, y
   justo debajo va el concepto en tres tiempos, que es lo que la
   gente no entendía.
   ============================================================ */

/* ---------- Hero partido: mensaje + producto vivo ---------- */
.hero-split { display: grid; gap: clamp(2.5rem, 5vw, 4rem); align-items: center; }
@media (min-width: 1000px) { .hero-split { grid-template-columns: 1.05fr 0.95fr; } }

.hero-kicker {
  display: inline-flex; align-items: center; gap: 0.6rem; align-self: start;
  font-family: 'Space Grotesk', sans-serif; font-size: var(--step--1); font-weight: 600;
  letter-spacing: 0.1em; text-transform: uppercase; color: var(--orange);
  border: 1px solid rgba(240, 102, 64, 0.3); border-radius: 999px; padding: 0.45rem 0.95rem;
}
.hero-kicker::before {
  content: ''; width: 7px; height: 7px; border-radius: 50%; background: var(--teal);
  box-shadow: 0 0 0 3px rgba(80, 201, 176, 0.2);
}
.hero-split h1 { font-size: clamp(2.5rem, 1.6rem + 3.6vw, 4.3rem); max-width: 15ch; }
.hero-split .hero__sub { max-width: 52ch; }

/* Composición del producto: la tablet detrás, el móvil delante. */
.hero-device { position: relative; display: flex; justify-content: center; align-items: flex-end; }
.hero-device__tablet {
  width: 82%; border-radius: 14px; overflow: hidden; border: 9px solid #191924;
  box-shadow: 0 34px 80px rgba(0, 0, 0, 0.6); background: var(--ink-800);
}
.hero-device__phone {
  position: absolute; left: 0; bottom: -1.5rem; width: 33%; max-width: 200px;
  border-radius: 24px; overflow: hidden; border: 7px solid #191924;
  box-shadow: 0 24px 60px rgba(0, 0, 0, 0.7); background: var(--ink-800);
}
@media (max-width: 640px) {
  .hero-device__tablet { width: 100%; }
  .hero-device__phone { width: 42%; left: -0.5rem; bottom: -2rem; }
}

/* ---------- El concepto en tres tiempos ---------- */
.flow { display: grid; gap: 1.5rem; counter-reset: flow; }
@media (min-width: 860px) { .flow { grid-template-columns: repeat(3, 1fr); gap: 2rem; } }
.flow-step { display: flex; flex-direction: column; gap: 1rem; }
.flow-step__shot {
  border-radius: var(--r-md); overflow: hidden; border: 1px solid var(--line-strong);
  background: var(--ink-800); box-shadow: 0 16px 40px rgba(0, 0, 0, 0.35);
  /* Las tres capturas tienen proporciones distintas (un móvil vertical, una
     tablet apaisada, una pantalla de TV). Sin recorte, la fila se descuadra y
     los tres títulos quedan a alturas distintas. */
  width: 100%; aspect-ratio: 4 / 3; object-fit: cover; object-position: top center;
}
.flow-step__head { display: flex; align-items: baseline; gap: 0.7rem; }
.flow-step__head::before {
  counter-increment: flow; content: counter(flow);
  font-family: 'Space Grotesk', sans-serif; font-weight: 700; font-size: var(--step-2);
  color: var(--orange); line-height: 1;
}
.flow-step h3 { font-size: var(--step-1); }
.flow-step p { color: var(--text-soft); font-size: var(--step--1); line-height: 1.6; }

/* ---------- Lo que cambia: resultados, no funciones ---------- */
.gains { display: grid; gap: 1px; background: var(--line); border: 1px solid var(--line); border-radius: var(--r-md); overflow: hidden; }
@media (min-width: 700px) { .gains { grid-template-columns: 1fr 1fr; } }
.gain { background: var(--ink-800); padding: clamp(1.5rem, 3vw, 2.2rem); display: flex; flex-direction: column; gap: 0.6rem; }
.gain__label {
  font-family: 'Space Grotesk', sans-serif; font-size: var(--step--1); font-weight: 600;
  letter-spacing: 0.12em; text-transform: uppercase; color: var(--teal);
}
.gain h3 { font-size: var(--step-1); }
/* La única rejilla de DOS columnas con texto a `--step-0`: con `--maxw` a 1600
   la columna mide 800 px y el párrafo se iba a ~84 caracteres de medida. Las
   rejillas de 3 y 4 columnas se quedan solas por debajo de 70; esta no. */
.gain p { color: var(--text-soft); font-size: var(--step-0); line-height: 1.6; max-width: 62ch; }

/* ---------- Franja de credibilidad, compacta ---------- */
.badges { display: flex; flex-wrap: wrap; gap: 0.6rem; }
.badge-item {
  display: inline-flex; align-items: center; gap: 0.5rem;
  border: 1px solid var(--line-strong); border-radius: 999px;
  padding: 0.5rem 1.1rem; font-size: var(--step--1); color: var(--text-soft);
}
.badge-item strong { color: var(--text); font-weight: 600; }

/* ============================================================
   HOME v3 — la home no vende: engancha y enruta
   ------------------------------------------------------------
   La v2 explicaba el mecanismo con capturas de festival, así que
   un dueño de bar veía pantallas ajenas y se iba. Aquí el hero es
   una pregunta rotatoria válida para los cuatro sectores y el
   selector ES el CTA: al posarse en cada oficio, la pantalla de
   al lado cambia a la de ESE sector. La venta por sector y por
   rol vive en las sub-webs.
   ============================================================ */

.hook { padding-block: clamp(2.5rem, 5vw, 4rem) clamp(1.5rem, 3vw, 2.5rem); position: relative; }
.hook::before {
  content: ''; position: absolute; inset: 0 0 auto; height: 520px; pointer-events: none;
  background: radial-gradient(ellipse 65% 100% at 20% 0%, rgba(240, 102, 64, 0.14), transparent 65%);
}
.hook > * { position: relative; }

/* --- La pregunta que rota --- */
.hook__q {
  font-family: 'Space Grotesk', sans-serif; font-weight: 700;
  font-size: clamp(1.9rem, 1.2rem + 2.5vw, 3.2rem); line-height: 1.1;
  letter-spacing: -0.02em; margin: 0; max-width: 24ch;
  /* Alto reservado para la frase más larga: sin esto la página da un salto
     en cada cambio de pregunta. text-wrap:balance NO se usa aquí: reparte
     las líneas de forma distinta en cada frase y el salto vuelve. */
  min-height: calc(3 * 1.1em);
}
.hook__q .lead { color: var(--text); }
.hook__q .rot { color: var(--orange); }
/* Las otras cuatro variantes de la pregunta viven en el DOM para que las
   traduzca el cargador de idioma (ver el comentario en index.html). El
   atributo `hidden` ya las oculta; esta regla existe porque `hidden` es una
   declaración de user-agent y cualquier `display` posterior sobre el elemento
   la gana en silencio. */
.rot-alts { display: none !important; }
@media (prefers-reduced-motion: no-preference) {
  .hook__q .rot { transition: opacity 0.32s ease, transform 0.32s ease; display: inline-block; }
  .hook__q .rot.out { opacity: 0; transform: translateY(-6px); }
}
.hook__bridge { font-size: var(--step-1); color: var(--text-soft); max-width: 48ch; line-height: 1.5; }

/* --- Selector de oficio: es el CTA principal --- */
.hook__grid { display: grid; gap: clamp(2rem, 4vw, 3.5rem); align-items: center; }
@media (min-width: 1000px) { .hook__grid { grid-template-columns: 1.1fr 0.9fr; } }
/* Sin la columna de previsualización, la rejilla seguía reservando su hueco y
   la home se quedaba con media pantalla vacía. `:has()` deja la regla de dos
   columnas intacta para cuando la previsualización vuelva: no hay que acordarse
   de revertir nada. */
@media (min-width: 1000px) {
  .hook__grid:not(:has(.preview)) { grid-template-columns: minmax(0, 1fr); max-width: 62rem; }
}

.picker { display: grid; gap: 0.7rem; }
@media (min-width: 560px) { .picker { grid-template-columns: 1fr 1fr; } }

.pick {
  display: flex; flex-direction: column; gap: 0.3rem;
  padding: 1.05rem 1.2rem; border-radius: var(--r-md);
  background: var(--ink-800); border: 1px solid var(--line);
  text-decoration: none; color: inherit; cursor: pointer;
  transition: border-color 0.18s ease, background 0.18s ease, transform 0.18s ease;
}
.pick:hover, .pick:focus-visible, .pick.is-active {
  border-color: var(--orange); background: var(--ink-700);
}
/* El outline:none de la regla de arriba dejaba las CUATRO tarjetas del selector
   —el CTA principal de la home— como los únicos focusables del sitio sin anillo:
   el foco se distinguía solo por un borde de 1 px idéntico al de :hover y al de
   .is-active. Anillo propio, el mismo que ya usan .btn y .role.is-clickable.
   Va DESPUÉS de la regla combinada a propósito: misma especificidad, gana la
   última, y así no depende de que nadie reordene el bloque. */
.pick:focus-visible { outline: 2px solid var(--orange); outline-offset: 3px; }
@media (prefers-reduced-motion: no-preference) {
  .pick:hover, .pick:focus-visible { transform: translateX(3px); }
}
.pick__top { display: flex; align-items: center; gap: 0.6rem; }
.pick__icon { font-size: 1.35rem; line-height: 1; }
.pick__name { font-family: 'Space Grotesk', sans-serif; font-weight: 600; font-size: var(--step-0); }
.pick__pain { color: var(--text-soft); font-size: var(--step--1); line-height: 1.45; }
.pick__go { color: var(--orange); opacity: 0; margin-left: auto; font-size: var(--step--1); }
.pick:hover .pick__go, .pick:focus-visible .pick__go, .pick.is-active .pick__go { opacity: 1; }

/* --- La pantalla que cambia según el oficio señalado --- */
.preview { display: flex; justify-content: center; }
.preview__frame {
  position: relative; width: min(78%, 280px);
  border-radius: 30px; overflow: hidden; border: 8px solid #191924;
  box-shadow: 0 30px 70px rgba(0, 0, 0, 0.6); background: var(--ink-800);
}
.preview__frame img { display: block; width: 100%; }
@media (prefers-reduced-motion: no-preference) {
  .preview__frame img { transition: opacity 0.25s ease; }
}
.preview__frame img.fading { opacity: 0.25; }
.preview__cap {
  text-align: center; margin-top: 1rem; color: var(--text-dim);
  font-size: var(--step--1); min-height: 2.6em;
}
/* La captura iba ANTES del titular en todo lo que baja de 1000 px (`order: -1`).
   Retirado el 20 ago 2026 por decisión del titular: quien abre la web en el
   móvil tiene que leer primero la pregunta —«Envie de…»— y no una pantalla de
   una app que todavía no sabe de qué va. La captura pasa a su sitio natural del
   DOM, detrás del selector de oficio, donde ilustra en vez de interrumpir.
   Por encima de 1000 px son dos columnas y el orden no significa nada. */
@media (max-width: 999px) { .preview__frame { width: min(62%, 240px); } }
/* Con `--maxw` a 1440/1600 la columna de la previsualización pasa de ~530 a
   ~700 px y un teléfono topado en 280 px se quedaba flotando en medio del
   hueco. 340 px sigue siendo un teléfono creíble (un iPhone real son 390 px de
   viewport) y llena la columna. */
@media (min-width: 1400px) { .preview__frame { width: min(78%, 340px); } }

/* --- Sellos compactos bajo el selector --- */
.hook__badges { display: flex; flex-wrap: wrap; gap: 0.55rem; }

/* ---------- Tarjeta de rol con su pantalla (sub-webs) ---------- */
/* Tres proporciones conviven en la misma fila: capturas de escritorio 900×563
   (1.60) y 900×629 (1.43), y capturas de móvil 780×1328 (0.59). Una sola caja
   4/3 con object-fit:cover recortaba los laterales de las apaisadas y partía las
   palabras de la barra lateral por la mitad («ISINE & PRÉPARATION», «MINISTRA-
   TION»): a ojo parecía un fallo de render, no un encuadre. Se separan por el
   atributo width del HTML —que ya distingue las dos familias— en vez de por una
   clase nueva o un :nth-child, que se rompería si alguien reordena las tarjetas.
   Apaisadas: contain, no se corta nada (la caja 16/10 casa con 900×563 y deja un
   pillarbox mínimo en 900×629, sobre fondo, que se lee como marco).
   Verticales: caja vertical propia y cover, que conserva el ANCHO completo del
   teléfono y recorta por abajo — ninguna palabra queda partida. */
/* UNA SOLA CAJA para las tres tarjetas de la fila, apaisadas y verticales.

   Antes habia dos: `16/10` por defecto y `3/4` para las capturas verticales
   (seleccionadas por `[width="780"]`). Como las tres tarjetas comparten fila en
   una rejilla de tres columnas, eso dejaba imagenes de 419 px de alto al lado
   de otras de 196 px — 223 px de diferencia — y los titulares de las tres
   tarjetas arrancaban a alturas distintas, con un hueco muerto al final de la
   que llevaba la imagen corta. Es la primera prueba visual de cada sub-web.

   Se fija la MISMA relacion para todas y se acepta el letterbox en las
   verticales: preferimos margen a los lados antes que tres titulares
   descuadrados. `contain` (y no `cover`) porque recortar una captura de
   telefono le come la cabecera o la barra de navegacion, que es justo lo que
   se quiere ensenar. */
.role__shot {
  width: 100%; aspect-ratio: 1 / 1; object-fit: contain; object-position: center;
  background: var(--ink-900);
  border-radius: var(--r-sm); border: 1px solid var(--line-strong); margin-bottom: 0.2rem;
}
.role.is-clickable { cursor: zoom-in; }
.role.is-clickable:focus-visible { outline: 2px solid var(--orange); outline-offset: 3px; }
.role.is-clickable:hover .role__shot { border-color: var(--orange); }


/* ---------- Anclas bajo la cabecera pegajosa ----------
   La cabecera es `position: sticky`, así que al saltar a un ancla («Parlons-en»
   apunta a #…--contact) el navegador deja el destino justo debajo del borde
   superior… que es donde está la cabecera. El arranque de la sección quedaba
   tapado. `scroll-margin-top` le dice al navegador que reserve ese hueco.
   El valor sigue a la cabecera real: 64 px en móvil, 87 en escritorio, más un
   respiro. No se pone en `html` porque solo importa en los destinos. */
[id] { scroll-margin-top: 5.5rem; }
@media (min-width: 1000px) { [id] { scroll-margin-top: 6.5rem; } }
