/* ============================================================
   BRIOX BAKER · Landing
   Poppins es LA voz: jerarquía por PESO (900/400) y ESCALA. La mono no habla,
   solo etiqueta (HUD técnico). Negro de horno + oro de marca. Dark locked.

   Escala: o MUY grande o MUY pequeño. Los tamaños medios son la firma del
   diseño genérico — medido en las 6 referencias de Juan (landonorris, terminal,
   igloo, cornrevolution, adidaschile20, gq-lab).
   ============================================================ */

/* ---------- Fuentes de la casa (auto-alojadas) ----------
   `font-display: swap` = pinta YA con la fuente del sistema y cambia a Poppins
   cuando llegue. Es preferible un cambio de letra a 200ms que una página en
   blanco: el texto se puede leer desde el primer frame.
   Solo va el subconjunto LATINO — el español entra entero (la ñ es U+00F1, los
   acentos y los ¿¡ también). Bajar cirílico o griego sería tirar KB al usuario. */
@font-face {
  font-family: 'Poppins'; font-style: normal; font-weight: 400; font-display: swap;
  src: url('../fonts/poppins-400.woff2') format('woff2');
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+2074, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}
@font-face {
  font-family: 'Poppins'; font-style: normal; font-weight: 500; font-display: swap;
  src: url('../fonts/poppins-500.woff2') format('woff2');
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+2074, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}
@font-face {
  font-family: 'Poppins'; font-style: normal; font-weight: 600; font-display: swap;
  src: url('../fonts/poppins-600.woff2') format('woff2');
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+2074, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}
@font-face {
  font-family: 'Poppins'; font-style: normal; font-weight: 900; font-display: swap;
  src: url('../fonts/poppins-900.woff2') format('woff2');
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+2074, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}
@font-face {
  font-family: 'JetBrains Mono'; font-style: normal; font-weight: 500; font-display: swap;
  src: url('../fonts/jetbrains-mono-500.woff2') format('woff2');
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+2074, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}

:root {
  /* — Superficies: negro con TEMPERATURA de horno (no negro genérico) — */
  --black: #080605;          /* base tostada, no azulada */
  --surface-1: #121110;      /* inputs */
  --surface-2: #1c1a18;      /* elevado */
  --ink-invert: #0a0908;     /* texto sobre oro */
  --ember: 22, 12, 4;        /* rescoldo: la luz del horno detrás del objeto */

  /* — Marca — */
  --gold: #feb300;
  --gold-2: #ffce5c;
  --red: #dd1d1d;
  --cream: #f5efe3;
  --muted: #b9ad97;          /* 8,52:1 sobre surface-1 */

  /* — Líneas: NEUTRAS por defecto. El oro solo cuando SIGNIFICA — */
  --line: rgba(255, 255, 255, .08);
  --line-gold: rgba(254, 179, 0, .32);

  /* — Tipografía — */
  --font: 'Poppins', system-ui, -apple-system, sans-serif;
  /* La mono NO es una segunda voz: solo etiqueta lo técnico (HUD, metadatos).
     Nunca titulares, nunca párrafos. Es lo que hacen Terminal (Geist Mono) e Igloo. */
  --font-mono: 'JetBrains Mono', ui-monospace, SFMono-Regular, Menlo, monospace;
  --fw-black: 900;
  --fw-semi: 600;
  --fw-med: 500;
  --fw-reg: 400;

  --fs-hero: clamp(3.5rem, 9.2vw, 11rem);     /* 56px móvil · 132px @1440 · cap 176px */
  --fs-h2: clamp(1.75rem, 3.4vw, 3rem);       /* 28 → 48px */
  --fs-h3: 1.25rem;                            /* 20px */
  --fs-lead: clamp(1.05rem, .9rem + .55vw, 1.25rem);
  --fs-body: 1.0625rem;                        /* 17px fijo */
  --fs-small: .8125rem;                        /* 13px · SUELO DURO */
  --fs-hud: .75rem;                            /* 12px · mono, may. — suelo absoluto */

  --lh-hero: .89;   /* .86 hacía que la tilde de ESPAÑA tocara BURGER (verificado en navegador) */
  --lh-h2: .95;

  --ls-hero: -.035em;
  --ls-h2: -.025em;
  --ls-h3: -.01em;
  --ls-body: 0;
  --ls-eyebrow: .16em;

  /* — Ritmo vertical — COMPACTO (Juan, 16-jul: "en brioxbaker.com tenía muy poco
       aire entre secciones"). Medido contra su web: el aire entre bloques ronda los
       60-80px, no 190. Antes gap-xl daba 192px a 1440 → media pantalla en blanco. */
  --gap-s: clamp(1.5rem, 3vw, 2.4rem);
  --gap-m: clamp(2.5rem, 4.5vw, 4rem);
  --gap-xl: clamp(3.5rem, 6.5vw, 5.5rem);

  /* — Radios (sistema cerrado) — */
  --r-tight: 4px;
  --r-media: 10px;           /* fotos: redondeo ligero (Juan, 16-jul) */

  --ease: cubic-bezier(.16, 1, .3, 1);
  --maxw: 1240px;
  /* Aire real a la izquierda: el titular no se pega al borde (Juan, 16-jul) */
  --pad: clamp(1.5rem, 7vw, 7rem);
  /* Medido contra brioxbaker.com: los logos del ticker son discretos, no gritan.
     A 100px competían con el titular. Este valor es la altura de un logo CUADRADO;
     el resto se deriva por área óptica (--s). */
  --logo-h: 76px;

  /* La celda de la rejilla del fondo. Es un TOKEN porque JS la lee para calcular
     el parallax en módulo: si aquí cambia el número, el fondo sigue cuadrando.
     64px (Juan, 17-jul: "los cuadrados muy grandes"). A 96 la rejilla se leía
     como un panel; a 64 es trama de fondo, que es su papel. */
  --tile: 64px;
}

*, *::before, *::after { box-sizing: border-box; }
html {
  -webkit-text-size-adjust: 100%;
  scroll-behavior: smooth;
  background: var(--black);
  /* CINTURÓN CONTRA EL SCROLL LATERAL.
     `clip` y NO `hidden`: son casi iguales pero con una diferencia que aquí es
     crítica — `overflow:hidden` convierte al elemento en contenedor de scroll y
     eso ROMPE el `position: sticky` del header. `clip` recorta sin crear
     contenedor: el header sigue pegándose arriba.
     Por qué hace falta: esta web tiene varias piezas que se salen A PROPÓSITO
     (tickers, la burger sangrando por la derecha, el grid de fondo). Cualquiera
     de ellas, con un cambio futuro, puede abrir 20px de scroll lateral que nadie
     ve en el portátil y arruina el móvil — que es el 70% del tráfico. Esto lo
     hace imposible por construcción, no por vigilancia. */
  overflow-x: clip;
}
@media (prefers-reduced-motion: reduce) { html { scroll-behavior: auto; } }

body {
  margin: 0;
  /* SIN background: el fondo lo pinta `html` (va al canvas) y la rejilla vive en
     z-index:-1. Si el body tuviera fondo propio, se pintaría ENCIMA de los hijos
     con z-index negativo y se COMERÍA la rejilla entera — es exactamente lo que
     pasaba: el grid se pintaba y el body lo tapaba (cazado el 17-jul midiendo). */
  color: var(--cream);
  font-family: var(--font);
  font-size: var(--fs-body);
  line-height: 1.55;
  font-weight: var(--fw-reg);
  letter-spacing: var(--ls-body);
  -webkit-font-smoothing: antialiased;
  overflow-x: hidden;
}

img { max-width: 100%; height: auto; display: block; }
a { color: inherit; text-decoration: none; }
h1, h2, h3 { font-family: var(--font); margin: 0; }

.wrap { width: 100%; max-width: var(--maxw); margin-inline: auto; padding-inline: var(--pad); }
.visually-hidden { position: absolute; width: 1px; height: 1px; overflow: hidden; clip: rect(0 0 0 0); white-space: nowrap; }
/* Sangrar a borde: la página deja de ser una caja */
.bleed { width: 100vw; margin-left: calc(50% - 50vw); max-width: none; }

/* ---------- Fondo: LUZ DE HORNO, no rejilla plana ----------
   Terminal pone el camión a contraluz del amanecer; aquí el rescoldo del horno
   sale de detrás del objeto. La rejilla se queda (está en la foto original de
   Briox, es de la casa) pero baja a un susurro: la luz manda, no la retícula. */
/* SOLO las líneas doradas, más presentes, y RESPIRANDO (Juan, 16-jul).
   El brillo va en una capa propia que anima OPACIDAD (compositor, coste ~0);
   animar el background-image obligaría a repintar la pantalla entera en cada frame. */
/* La CAJA: quieta, pegada al viewport. Aquí vive el degradado de bordes, que NO
   debe moverse (si viajara con la rejilla, la sombra de las esquinas subiría al
   hacer scroll y se notaría el truco). Dentro, dos planos que sí se mueven. */
.grid-bg {
  position: fixed; inset: 0; z-index: -1; pointer-events: none;
  background-color: var(--black);
  overflow: hidden;
  /* Bordes INFINITOS degradados, jamás un canto recto (regla dura de Juan):
     la rejilla es fuerte en el centro y se disuelve en la nada por los lados. */
  -webkit-mask-image: radial-gradient(135% 100% at 50% 38%, #000 30%, transparent 88%);
  mask-image: radial-gradient(135% 100% at 50% 38%, #000 30%, transparent 88%);
}
/* UNA sola rejilla, en dos capas CLAVADAS a la misma posición. Se pasan de la
   caja --tile por los 4 lados para que al desplazarse no asome un borde vacío.
   Ojo: probé las dos capas a distinta velocidad buscando "dos planos" y se ve
   FATAL — a igual tamaño de celda no dan hondura, dan líneas DOBLADAS (parece un
   error de imprenta). La profundidad la da la rejilla contra el CONTENIDO, no
   contra sí misma. */
.grid-bg::before,
.grid-bg::after {
  content: ""; position: absolute; inset: calc(var(--tile) * -1);
  background-size: var(--tile) var(--tile);
  transform: translate3d(0, var(--gy, 0px), 0);
  will-change: transform;
}
/* La rejilla que siempre está. Puede permitirse tener PRESENCIA porque ya no
   compite con nada: donde hay contenido, lo apaga la sombra de `.velo` (abajo).
   Fuerte en el vacío, callada bajo lo que importa (Juan, 17-jul). */
.grid-bg::before {
  background-image:
    linear-gradient(to right, rgba(254, 179, 0, .19) 1px, transparent 1px),
    linear-gradient(to bottom, rgba(254, 179, 0, .19) 1px, transparent 1px);
}
/* la gemela: MISMA rejilla y MISMA posición, pero más encendida. No se ve entera:
   la descubre la brasa (.grid-bg__brasa) al pasar por encima. */
.grid-bg::after {
  background-image:
    linear-gradient(to right, rgba(254, 179, 0, .3) 1px, transparent 1px),
    linear-gradient(to bottom, rgba(254, 179, 0, .3) 1px, transparent 1px);
  /* La brasa es quien decide qué trozo de esta capa se ve. Sin ella, invisible. */
  -webkit-mask-image: var(--brasa); mask-image: var(--brasa);
  -webkit-mask-repeat: no-repeat;   mask-repeat: no-repeat;
  -webkit-mask-position: var(--bx, 50%) var(--by, 50%);
  mask-position: var(--bx, 50%) var(--by, 50%);
  -webkit-mask-size: 150% 130%;     mask-size: 150% 130%;
}

/* Registrar las variables es OBLIGATORIO para poder animarlas: sin @property el
   navegador las trata como texto suelto y no sabe interpolar 18% -> 74%; la brasa
   daría saltos secos en vez de derivar. Registradas, son números de verdad.
   `inherits:true` porque quien las lee es el ::after, no .grid-bg. */
@property --bx { syntax: '<percentage>'; inherits: true; initial-value: 50%; }
@property --by { syntax: '<percentage>'; inherits: true; initial-value: 45%; }

/* ---------- LA BRASA ----------
   Un rescoldo de horno que deriva despacio y va ENCENDIENDO las líneas por donde
   pasa: la rejilla deja de ser un papel pintado y respira como un obrador.
   Por qué así y no de otra forma:
   · Solo se mueve la MÁSCARA (--bx/--by), no se repinta nada más.
   · `alternate` = va y vuelve → NUNCA da el salto del bucle (regla de Juan: lo
     infinito tiene que ser infinito de verdad, sin golpe al repetir).
   · Recorrido corto y lentísimo (26s): tiene que notarse como que el fondo está
     VIVO, no como un foco barriendo. Si se ve la animación, se ha pasado. */
.grid-bg {
  --brasa: radial-gradient(ellipse 46% 42% at 50% 50%,
             #000 0%, rgba(0,0,0,.55) 42%, transparent 72%);
  animation: brasa 26s ease-in-out infinite alternate;
}
@keyframes brasa {
  0%   { --bx: 18%; --by: 22%; }
  50%  { --bx: 74%; --by: 62%; }
  100% { --bx: 30%; --by: 88%; }
}
@media (prefers-reduced-motion: reduce) {
  /* sin movimiento, pero la rejilla no se queda muerta: la brasa se planta en el
     centro y se queda */
  .grid-bg { animation: none; --bx: 50%; --by: 45%; }
}

/* ---------- EL VELO: la rejilla se aparta de lo que importa ----------
   Idea de Juan (17-jul): "el grid sutil donde hay algo encima — el mapa, un texto,
   una imagen — y con más fuerza donde no hay nada".

   Cómo: cada bloque de contenido lleva PEGADA su propia sombra, una mancha oscura
   difuminada que se posa entre la rejilla y el texto. Donde hay algo que leer, la
   rejilla se apaga sola; en el vacío, sigue encendida. Y como la mancha va con el
   elemento, funciona sin JS, en cualquier tamaño de pantalla y al hacer scroll.

   Por qué RADIAL y no un rectángulo con fondo: un rectángulo se vería (Juan odia
   las cajas). Un radial no tiene borde — solo se nota que ahí el fondo respira menos.

   Hace falta `isolation: isolate` en NINGÚN sitio: el ::before va a z-index -1, que
   lo deja por debajo del contenido del propio elemento pero por encima de .grid-bg
   (que está antes en el DOM y también en -1). El orden del DOM desempata. */
.velo { position: relative; }
/* La curva del velo va en un token: las tres capas que lo usan tienen que morir
   IGUAL. Son 12 paradas siguiendo una smoothstep — pendiente cero en los dos
   extremos, o sea, el velo nace y muere sin que se vea DÓNDE.
   Con 4 paradas lineales se veía un canto vertical en mitad del héroe (Juan,
   17-jul: "se ve un corte que queda feísimo"). El ojo no detecta el degradado:
   detecta el punto donde el degradado DEJA de bajar. Por eso hay que frenarlo
   poco a poco en vez de cortarlo. */
/* El mapa también se merece su velo: es contenido, y el grid encima lo ensuciaba
   (Juan, 17-jul: "sutil en zonas en las que hay algo encima — el mapa, un texto,
   una imagen"). Ojo: el velo va DEBAJO de la imagen del mapa (z-index -1 dentro
   del elemento), así que apaga la rejilla pero NO toca los puntos. */
.mapa__viz.velo::before { inset: -6% -4%; }
.velo::before {
  content: ""; position: absolute; z-index: -1; pointer-events: none;
  /* se pasa del elemento: la sombra tiene que empezar a caer ANTES del texto */
  inset: -18% -14%;
  background: radial-gradient(ellipse 74% 68% at 50% 50%,
    rgba(8,6,5,.94) 0%,
    rgba(8,6,5,.933) 12%,
    rgba(8,6,5,.911) 20%,
    rgba(8,6,5,.874) 28%,
    rgba(8,6,5,.822) 36%,
    rgba(8,6,5,.756) 44%,
    rgba(8,6,5,.677) 52%,
    rgba(8,6,5,.588) 60%,
    rgba(8,6,5,.470) 68%,
    rgba(8,6,5,.352) 76%,
    rgba(8,6,5,.216) 85%,
    rgba(8,6,5,.094) 93%,
    rgba(8,6,5,0) 100%);
}

/* ---------- Botones: press rápido, retorno lento ---------- */
.btn {
  display: inline-flex; align-items: center; justify-content: center;
  font: inherit; font-weight: var(--fw-semi); font-size: var(--fs-body);
  padding: .85em 1.6em; border-radius: var(--r-tight); border: 1px solid transparent;
  cursor: pointer; white-space: nowrap;
  transition: transform 280ms var(--ease), background-color 200ms var(--ease), color 200ms var(--ease), border-color 200ms var(--ease);
}
.btn:active { transform: scale(.97); transition-duration: 85ms; transition-timing-function: ease-in; }
.btn--gold { background: var(--gold); color: var(--ink-invert); }
.btn--gold:hover { background: var(--gold-2); }
:focus-visible { outline: 2px solid var(--gold); outline-offset: 3px; }

/* ---------- Reveal: cada elemento se COLOCA, no aparece ----------
   Sube, entra y se asienta con un ease de salida largo (.19,1,.22,1): arranca
   rápido y frena despacio, que es como se mueven las cosas con peso. El desenfoque
   mínimo hace que "enfoque" al llegar — es lo que separa un fade genérico de algo
   que parece caro. Solo opacity/transform/filter → compositor.

   Ojo al `.js`: sin JavaScript nadie añadiría la clase `.in` y la página entera
   se quedaría invisible (contenido real, opacity 0). El velo solo se echa si hay
   JS para levantarlo. */
.js [data-reveal] {
  opacity: 0;
  transform: translate3d(0, 26px, 0) scale(.985);
  filter: blur(6px);
  transition:
    opacity .8s cubic-bezier(.19, 1, .22, 1),
    transform .9s cubic-bezier(.19, 1, .22, 1),
    filter .8s cubic-bezier(.19, 1, .22, 1);
  will-change: opacity, transform;
}
[data-reveal].in { opacity: 1; transform: none; filter: none; }
/* al terminar, soltar el will-change: mantenerlo eterno gasta memoria de GPU */
[data-reveal].done { will-change: auto; }
@media (prefers-reduced-motion: reduce) {
  .js [data-reveal] { opacity: 1 !important; transform: none !important; filter: none !important; transition: none; }
}

/* ---------- Header: se DISUELVE, no se separa con una línea ----------
   El blur progresivo apila 6 capas de desenfoque creciente, cada una recortada en
   su banda con una máscara. Resultado: nítido abajo → muy borroso arriba, sin corte
   visible. Es la receta de iOS/Apple y es lo que hace que un header no parezca una
   barra pegada encima de la página.
   SIN border-bottom (Juan, 16-jul: "esa línea divisoria la odio"). */
.site-header {
  position: sticky; top: 0; z-index: 50;
  transition: transform .45s var(--ease);
}
/* El blur SOLO existe si hay algo que difuminar. Arriba del todo no hay nada
   detrás del header, y encendido emborronaba el kicker del titular: se veía una
   mancha dorada bajo la barra (Juan, 16-jul: "tiene un error ese header"). */
.pblur {
  position: absolute; inset: 0 0 -30% 0; pointer-events: none; z-index: -1;
  opacity: 0; transition: opacity .35s var(--ease);
}
.site-header.scrolled .pblur { opacity: 1; }
/* Cada capa: opaca desde arriba hasta --o, y de ahí se funde hasta morir en --c.
   Siempre termina en `transparent` → ninguna capa deja canto. */
.pblur > div {
  position: absolute; inset: 0;
  backdrop-filter: blur(var(--b));
  -webkit-backdrop-filter: blur(var(--b));
  -webkit-mask-image: linear-gradient(to bottom, #000 var(--o), transparent var(--c));
  mask-image: linear-gradient(to bottom, #000 var(--o), transparent var(--c));
}
/* Un velo mínimo que oscurece SOLO lo justo para que el logo siempre se lea.
   La rampa NO es lineal a propósito. Un degradado de 2 paradas baja la opacidad a
   ritmo constante y el ojo lee ese final abrupto como un CANTO — se ve el borde
   del velo aunque técnicamente "termine en transparente" (Juan, 17-jul: "hace 2
   saltos, va a trompicones"). Estas 17 paradas siguen una curva SMOOTHSTEP, cuya
   pendiente es cero en los dos extremos: el velo nace y muere sin que se note
   dónde. De paso, tantas paradas parten las bandas de color de 8 bits, que en
   oscuros se ven como escalones. */
.site-header::after {
  content: ""; position: absolute; inset: 0 0 -30% 0; z-index: -1; pointer-events: none;
  background: linear-gradient(to bottom,
    rgba(8,6,5,.720) 0%,
    rgba(8,6,5,.712) 6.2%,
    rgba(8,6,5,.689) 12.5%,
    rgba(8,6,5,.654) 18.8%,
    rgba(8,6,5,.607) 25%,
    rgba(8,6,5,.553) 31.2%,
    rgba(8,6,5,.492) 37.5%,
    rgba(8,6,5,.427) 43.8%,
    rgba(8,6,5,.360) 50%,
    rgba(8,6,5,.293) 56.2%,
    rgba(8,6,5,.228) 62.5%,
    rgba(8,6,5,.167) 68.8%,
    rgba(8,6,5,.112) 75%,
    rgba(8,6,5,.066) 81.2%,
    rgba(8,6,5,.031) 87.5%,
    rgba(8,6,5,.008) 93.8%,
    rgba(8,6,5,0) 100%);
  opacity: 0; transition: opacity .4s var(--ease);
}
.site-header.scrolled::after { opacity: 1; }
/* al bajar se aparta; al subir vuelve. El contenido manda sobre el crómo. */
.site-header.hidden { transform: translateY(-104%); }
/* Logo CENTRADO (Juan, 17-jul). Con `space-between` y un solo hijo, el logo se
   pegaba a la izquierda — space-between reparte huecos ENTRE elementos, y con uno
   solo no hay nada que repartir. Con `center` manda el eje del centro.
   Y encaja con la web: la sección de Champions también se centró; el eje de la
   página es el centro, no el margen. */
.header__inner { display: flex; align-items: center; justify-content: center; height: 72px; }
.brand img { height: 26px; width: auto; }
@media (prefers-reduced-motion: reduce) { .site-header.hidden { transform: none; } }

/* ---------- HÉROE: el objeto es un MONUMENTO, el titular rompe el cajón ----------
   Lando pone el retrato a sangre ocupando la pantalla y el titular pegado al borde.
   Aquí igual: el héroe deja de ser una caja centrada de 1240px. */
.hero {
  position: relative;
  min-height: calc(100svh - 72px);   /* descontar el header sticky */
  display: grid; align-items: center;
  /* Aire de arriba MÍNIMO (Juan, 17-jul): había 83px muertos entre el logo y el
     kicker — medido. El titular es lo primero que hay que leer; ese hueco solo
     lo empujaba fuera de la vista. */
  padding: clamp(.5rem, 1.5vh, 1.2rem) 0 clamp(2rem, 5vh, 3.5rem);
  overflow: hidden;   /* el objeto sangra por la derecha sin abrir scroll lateral */
}
/* Mismo contenedor que el resto de la web: el titular y el logo del header
   comparten eje izquierdo. Antes el héroe iba a 1720 y el header a 1240 → el
   logo quedaba 100px desalineado del titular. */
.hero__grid {
  position: relative;
  width: 100%; max-width: var(--maxw); margin-inline: auto;
  padding-inline: var(--pad);
  /* Las dos piezas van JUNTAS y a la misma altura (Juan, 17-jul: "hay que juntar
     más esos 2 elementos... dejáis mucho aire en el medio, ambas tienen relación
     entre ellas"). Y tiene razón en el fondo del asunto: el titular dice "la mejor
     burger" y la burger es ESA. Son una sola frase, no dos columnas.
     El gap baja casi a cero: el aire real ya lo pone el texto, que no llega al
     borde de su columna (las líneas acaban antes). Un gap medido sobre las CAJAS
     miente — lo que el ojo ve es el hueco entre la LETRA y el PAN. */
  display: grid; grid-template-columns: minmax(0, 1fr) auto; align-items: center;
  gap: 0;
}

/* El titular es un BLOQUE compuesto, no una frase */
.hero__copy { position: relative; z-index: 2; }
.hero__title {
  font-size: var(--fs-hero);
  font-weight: var(--fw-black);
  text-transform: uppercase;
  line-height: var(--lh-hero);
  letter-spacing: var(--ls-hero);
  margin: 0;
  /* que mida lo que mide el texto, no toda la columna: así el aire entre el
     titular y el objeto es real y el crosshair tiene dónde apoyarse */
  width: fit-content;
}
/* Cada línea es una VENTANA y dentro el texto sube desde abajo: el titular se monta
   solo, línea a línea. Solo transform → va en el compositor.
   El recorte va con clip-path, NO con overflow:hidden — `overflow` recorta la caja
   entera y le cortaba la virgulilla a la Ñ de ESPAÑA por arriba (Juan, 16-jul).
   Con inset(-.34em 0 0 0) la ventana solo cierra por ABAJO, que es por donde entra
   el texto, y deja aire arriba para los acentos. */
.hero__title .l {
  display: block; white-space: nowrap; position: relative;
  clip-path: inset(-.34em -.12em 0 -.06em);
}
.hero__title .l__in { display: block; position: relative; z-index: 1; will-change: transform; }
.hero__title .l--gold { color: var(--gold); }
/* El aire extra antes de ESPAÑA se RETIRÓ (Juan, 16-jul): dejaba el hueco del medio
   al doble que los otros dos y el lockup perdía su ritmo. Que la virgulilla de la Ñ
   roce BURGER da igual — el cambio de color (crema → oro) ya separa los bloques.
   Ritmo uniforme > detalle tipográfico. Lo que NO puede pasar es que la Ñ salga
   CORTADA: de eso se encarga el clip-path de arriba. */

/* ---------- ENTRADA: PALABRA A PALABRA, CON DESENFOQUE DE MOVIMIENTO ----------
   CALCO del vídeo que mandó Juan (17-jul). Lo destripé fotograma a fotograma a
   10 fps y el efecto es exactamente éste: las palabras NO aparecen a la vez ni
   suben de una caja — llegan de UNA EN UNA, cada una con una estela horizontal,
   y enfocan al frenar. Es la lectura convertida en movimiento: el ojo va donde va
   la frase.

   Antes probé un "estampado" con bloques de color barriendo (más brutalista).
   Fuera: él quería ESTO, y una referencia concreta se CALCA, no se reinterpreta.

   La estela: `blur` + `scaleX` estirado + un empujón en X. Los tres a la vez son
   lo que el ojo lee como velocidad; el blur solo parecería una foto movida.
   La curva `(.16,1,.3,1)` frena fuerte al final: llega lanzada y clava. */
.js .hero__title .p,
.js .hero__title .hero__kicker {
  opacity: 0;
  filter: blur(12px);
  transform: translate3d(34px, 0, 0) scaleX(1.5);
  transform-origin: left center;
}
.hero__title.in .p,
.hero__title.in .hero__kicker {
  opacity: 1;
  filter: blur(0);
  transform: none;
  transition:
    opacity .34s linear,
    filter .46s cubic-bezier(.16, 1, .3, 1),
    transform .52s cubic-bezier(.16, 1, .3, 1);
}
/* El retardo lo pone JS palabra por palabra (--d): son 8 palabras y escribir 8
   reglas a mano se rompe en cuanto cambie el copy. */
.hero__title.in .p { transition-delay: var(--d, 0s); }

/* Cada palabra es su propia caja para poder moverla y desenfocarla suelta.
   `will-change` NO se pone aquí: son 8 cajas y crear 8 capas de GPU para una
   animación de un segundo cuesta más de lo que ahorra. Se suelta al acabar. */
.hero__title .p { display: inline-block; }

@media (prefers-reduced-motion: reduce) {
  .js .hero__title .p,
  .js .hero__title .hero__kicker {
    opacity: 1; filter: none; transform: none;
  }
}

/* EL ROTULADOR (Juan, 16-jul: "como lo de MÁS VIRAL"): un trazo dorado SÓLIDO se
   pinta por detrás de ESPAÑA · 2025 y el texto se vuelve negro a su paso — como
   subrayar con un marcador de verdad. No es un subrayado: es un resaltado. */
/* el texto pasa de oro a negro justo cuando el rotulador ya lo ha cubierto */
/* cada línea, su turno: primero ESPAÑA, después 2025 */
@media (prefers-reduced-motion: reduce) {
  .js .hero__title .l__in { transform: none; }
  .js .hero__title .hero__kicker { opacity: 1; transform: none; }
  .hero__title .l--mark::before { transform: scaleX(1); transition: none; }
  .hero__title .l--mark .l__in { color: var(--ink-invert); transition: none; }
}
/* CALCADO de brioxbaker.com (Juan, 17-jul: "y mira esto también").
   Va en Poppins NEGRITA y en minúsculas, no en mono-mayúsculas-espaciadas.
   La diferencia no es capricho: el mono en mayúsculas con letter-spacing es el
   "eyebrow" que lleva TODA landing del mundo — el gesto genérico por excelencia.
   En minúsculas y con peso, la frase se LEE como una frase ("Nuestro brioche está
   en... LA MEJOR BURGER") y encadena con el titular en vez de anunciarlo.
   Es además su voz real: es como lo tiene él en su web. */
.hero__kicker {
  display: block;
  text-transform: none;
  font-size: clamp(1rem, 1.5vw, 1.45rem);
  font-weight: var(--fw-black);
  letter-spacing: -.01em;
  line-height: 1.15;
  color: var(--gold);
  margin-bottom: clamp(.3rem, .6vw, .55rem);
}
/* ---------- EL SELLO DEL CAMPEONATO ----------
   Es un reconocimiento NACIONAL: se merece brillar (Juan, 17-jul). Pero con
   cuidado — el arcoíris de la burger lo quitó él mismo porque ensuciaba. La
   diferencia: aquel era arcoíris sobre oro (dos idiomas peleando); éste es ORO
   SOBRE ORO, que no es suciedad, es LUZ.
   Dos capas:
   · un halo dorado permanente, muy suave → el sello parece metal, no una pegatina.
   · un destello que lo cruza UNA VEZ al entrar (y otra si le pasas por encima).
     UNA vez, no en bucle: un sello que destella cada 5 segundos es un gif de 2009.
     La regla de la casa manda: lo decorativo es de un solo disparo. */
.hero__sello {
  position: relative;
  display: block; width: fit-content;
  margin: clamp(.7rem, 1.2vw, 1rem) 0 0;
}
.hero__sello img {
  display: block;
  width: clamp(180px, 17vw, 240px);
  height: auto;
  /* El halo sigue la SILUETA del logo (drop-shadow), no su caja. Con box-shadow
     saldría un rectángulo brillante, que es justo lo contrario de lo que se busca. */
  filter: drop-shadow(0 0 10px rgba(254, 179, 0, .28))
          drop-shadow(0 0 26px rgba(254, 179, 0, .14));
}
/* EL DESTELLO. Una banda de luz cruza el sello, RECORTADA por la forma del propio
   logo: la luz solo toca la tinta, nunca el hueco. Ese recorte es lo que lo hace
   parecer metal de verdad y no un brillo pegado encima. */
.hero__sello::after {
  content: ""; position: absolute; inset: 0;
  background: linear-gradient(104deg,
    transparent 40%, rgba(255, 240, 205, .8) 50%, transparent 60%);
  background-size: 240% 100%;
  background-position: 190% 0;
  background-repeat: no-repeat;
  -webkit-mask-image: url("../img/logo-campeonato.webp"); mask-image: url("../img/logo-campeonato.webp");
  -webkit-mask-size: clamp(180px, 17vw, 240px) auto; mask-size: clamp(180px, 17vw, 240px) auto;
  -webkit-mask-repeat: no-repeat; mask-repeat: no-repeat;
  mix-blend-mode: screen;
  pointer-events: none;
}
@keyframes destello { to { background-position: -70% 0; } }
/* Entra cuando entra el titular, con un respiro: el sello es la PRUEBA de lo que
   acaba de decir el titular, así que habla después, no a la vez. */
.hero__title.in ~ .hero__sello::after,
.hero__sello.is-in::after {
  animation: destello 1.15s cubic-bezier(.4, 0, .2, 1) .95s 1 forwards;
}
.hero__sello:hover::after {
  animation: destello 1s cubic-bezier(.4, 0, .2, 1) 1 forwards;
}
@media (prefers-reduced-motion: reduce) {
  .hero__sello::after { animation: none !important; }
}
.hero__sub { color: var(--muted); font-size: var(--fs-lead); max-width: 30ch; margin: clamp(1.2rem, 2vw, 1.8rem) 0 0; }
/* El crédito de quién montó la burger campeona: anotación, no titular (Juan, 16-jul) */
/* CALCADO de brioxbaker.com (Juan, 17-jul: "mira como lo tengo en la web
   oficial"): minúsculas, negrita, en CREMA. Lo tenía en mono mayúsculas y oro,
   como una etiqueta técnica — y esto no es una etiqueta: es una FIRMA, la de
   quien montó la burger campeona. Se lee como se lee un crédito, no como un dato.
   Y de paso quita una de las 20 reglas doradas: el oro tiene que volver a ser
   acento, no el color de la casa. */
.hero__credit {
  margin: clamp(.5rem, 1vw, .8rem) 0 0;
  font-family: var(--font);
  font-size: var(--fs-body);
  font-weight: var(--fw-black);
  text-transform: none;
  letter-spacing: -.01em;
  color: var(--cream);
}

/* ---------- EL MONUMENTO: recortado, sin marco, ENORME ---------- */
.hero__object {
  position: relative; z-index: 1;
  justify-self: end;
  /* sangra FUERA del contenedor por la derecha: el objeto no cabe en la página,
     la página cabe en él. El overflow del héroe evita el scroll lateral. */
  margin-right: clamp(-11rem, -9vw, -2rem);
}
.briox-holo { --mx: 50%; --my: 50%; display: inline-block; perspective: 1800px; }
.briox-holo__inner { position: relative; transform-style: preserve-3d; }
.briox-holo.is-active .briox-holo__inner { will-change: transform; }
.hero__object img {
  display: block; width: auto;
  /* MÁS GRANDE (Juan, 17-jul). Es el objeto protagonista: en las referencias que
     mandó (Lando, Terminal) el objeto no cabe en la página — la página cabe en él.
     A 78vh se quedaba en ilustración; a 92vh es un monumento. */
  height: clamp(26rem, 92vh, 54rem);
  /* La sombra sigue la SILUETA, no la caja. NEUTRA: nunca halo de oro sobre casi-negro */
  filter: drop-shadow(0 40px 60px rgba(0, 0, 0, .85)) drop-shadow(0 8px 16px rgba(0, 0, 0, .6));
  /* La burger no se CORTA contra el ticker: se hunde en el negro (Juan, 17-jul:
     "eso ahí hace un corte muy feo y directo"). El plato se disuelve en los
     últimos píxeles y el objeto parece salir de la oscuridad en vez de estar
     recortado con tijeras. Misma regla que en todo: nada acaba en un canto. */
  -webkit-mask-image: linear-gradient(to bottom, #000 82%, transparent 99%);
  mask-image: linear-gradient(to bottom, #000 82%, transparent 99%);
}

/* El HUD del héroe y los crosshairs se retiraron (Juan, 16-jul: "esos textos fuera").
   La mono sigue viva donde SÍ etiqueta: números del proceso y pies de galería. */
.hud {
  font-family: var(--font-mono);
  font-size: var(--fs-hud); font-weight: 500;
  letter-spacing: .08em; text-transform: uppercase;
  color: var(--muted);
}
/* El foil ARCOÍRIS se retiró (Juan, 16-jul: "queda fatal"). Tenía razón: un
   color-dodge iridiscente sobre oro real lo ensucia — parece mancha de aceite,
   no holograma. El oro de la corona ya brilla solo; lo que necesita es que la
   LUZ lo recorra, no un tinte de colores encima.
   Se queda el destello (blanco cálido, sigue al puntero) + el tilt 3D. */
.briox-holo__glare {
  position: absolute; inset: 0; pointer-events: none; opacity: 0;
  transition: opacity .45s var(--ease);
  -webkit-mask-image: url(../img/hero-object.webp?v=17); mask-image: url(../img/hero-object.webp?v=17);
  -webkit-mask-size: contain; mask-size: contain;
  -webkit-mask-repeat: no-repeat; mask-repeat: no-repeat;
  -webkit-mask-position: center; mask-position: center;
  background: radial-gradient(circle at var(--mx) var(--my), rgba(255, 244, 224, .3), transparent 38%);
  mix-blend-mode: soft-light;
}
.briox-holo.is-active .briox-holo__glare { opacity: 1; }
@media (prefers-reduced-motion: reduce) { .briox-holo__inner { transform: none !important; } .briox-holo__glare { display: none; } }

/* ---------- Prueba social: los logos ENCENDIDOS ----------
   Sin líneas arriba/abajo y banda más fina (Juan, 16-jul): los logos flotan sobre
   el fondo, no viven dentro de una caja. */
.proof { padding: clamp(1.2rem, 2.5vw, 2rem) 0; }
/* El rótulo se retiró (Juan, 16-jul): los logos ya dicen quién usa el brioche.
   Un cartel que nombra lo obvio sobra. */
.marquee {
  overflow: hidden;
  -webkit-mask-image: linear-gradient(90deg, transparent, #000 6%, #000 94%, transparent);
  mask-image: linear-gradient(90deg, transparent, #000 6%, #000 94%, transparent);
}
/* NUNCA se para: sin pausa al pasar el ratón (Juan, 16-jul: "que sea infinito"). */
.marquee__track { display: flex; align-items: center; width: max-content; animation: marquee 37s linear infinite; }
.marquee__track img {
  flex: none;
  /* ÁREA óptica constante (--s = 1/√ratio, calculado del bbox real de cada logo):
     Flacco es 6,4x más ancho que alto y MrBeast casi cuadrado — a la misma ALTURA,
     uno grita y el otro desaparece. Igualando el área pesan lo mismo en la fila. */
  height: calc(var(--logo-h) * var(--s, 1));
  width: auto; object-fit: contain;
  margin-right: clamp(2.5rem, 5vw, 4.5rem);
  /* COLOR PLENO: el color ES la prueba. Nada de grayscale ni hover-only.
     Los logos van recortados con alfa real (flood fill desde los bordes, para no
     comerse los contornos negros de MrBeast). Nada de mix-blend-mode: `screen`
     dejaba ver una caja gris en cuanto el webp metía ruido en los bordes. */
  filter: none; opacity: 1;
}
@keyframes marquee { to { transform: translateX(-50%); } }
@media (prefers-reduced-motion: reduce) { .marquee__track { animation: none; flex-wrap: wrap; justify-content: center; } }

/* ---------- Encabezados de sección ---------- */
/* El título ocupa lo que necesita: forzarlo a 42ch lo partía en 2 líneas sin
   motivo y comía alto. El límite de lectura va en el PÁRRAFO, que es quien lo
   necesita — no en el titular. (Juan, 16-jul) */
.section-head { margin: 0 0 var(--gap-s); }
.section-head .section-intro { max-width: 52ch; }
/* Centrado (Juan, 17-jul). Que el header de la web vaya a la izquierda no obliga
   al resto: una sección cuyo contenido es un ticker que cruza toda la pantalla
   pide un titular centrado — el eje del contenido es el centro, no el margen. */
.section-head--centro { text-align: center; }
.section-head--centro .section-intro { max-width: 52ch; margin-inline: auto; }
.section-title { font-size: var(--fs-h2); font-weight: var(--fw-black); line-height: var(--lh-h2); letter-spacing: var(--ls-h2); text-wrap: balance; }
.section-intro { color: var(--muted); font-size: var(--fs-lead); margin: 1rem 0 0; }

/* ---------- Proceso: REJILLA 3x2, como en brioxbaker.com (Juan, 16-jul) ----------
   Lo tenía así y funciona: 6 pasos a la vez, se abarcan de un vistazo y ocupan la
   mitad de alto que el zig-zag (que se comía el 40% de la página). Foto arriba,
   número, título, texto. Todas las tarjetas al MISMO alto. */
.process { padding: var(--gap-m) 0; }
.process__list {
  list-style: none; margin: 0; padding: 0;
  display: grid; grid-template-columns: repeat(3, minmax(0, 1fr));
  gap: clamp(1rem, 2vw, 1.6rem);
}
.step {
  display: flex; flex-direction: column;
  /* Negro CÁLIDO, no un blanco translúcido: rgba(255,255,255,.022) sobre un fondo
     tostado da un gris FRÍO que desentona (Juan, 16-jul: "ese color no es negro,
     es grisáceo"). Y sin borde: el propio bloque ya se separa por su tono. */
  background: #100c08;
  border-radius: var(--r-media);
  overflow: hidden;
}
.step__media { aspect-ratio: 16/11; overflow: hidden; }
.step__media img { width: 100%; height: 100%; object-fit: cover; transition: transform .8s var(--ease); }
.step:hover .step__media img { transform: scale(1.05); }
.step__body { padding: clamp(1rem, 1.8vw, 1.4rem); display: flex; flex-direction: column; gap: .3rem; }
/* el número acompaña al título, no compite con él */
.step__no {
  font-size: var(--fs-hud); font-weight: var(--fw-black);
  color: var(--gold); letter-spacing: .12em;
}
.step__title { font-size: var(--fs-h3); font-weight: var(--fw-black); letter-spacing: var(--ls-h3); color: var(--gold); margin: 0; }
.step__text { color: var(--muted); font-size: var(--fs-small); font-weight: var(--fw-reg); margin: .25rem 0 0; line-height: 1.5; }
@media (max-width: 900px) { .process__list { grid-template-columns: repeat(2, minmax(0, 1fr)); } }
@media (max-width: 560px) { .process__list { grid-template-columns: 1fr; } }

/* ---------- Comparador (respeta el formato vertical de la foto) ---------- */
.compare { padding: var(--gap-s) 0; }
/* DOS comparadores hermanos: el mismo gesto, dos panes (Juan, 16-jul) */
.cmp__duo { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: clamp(.8rem, 2vw, 1.6rem); }
@media (max-width: 760px) { .cmp__duo { grid-template-columns: 1fr; } }
.cmp {
  /* RATIO NATIVO de las fotos. Forzar otro recortaba un 18% y, al recortar, el
     rótulo del fondo dejaba de coincidir entre las dos → se rompía la ilusión de
     que es EL MISMO pan, que es justo lo que demuestra el slider.
     (Juan, 16-jul: "si no, no tiene sentido".) */
  position: relative; margin: 0; aspect-ratio: 1400 / 1524;
  overflow: hidden; background: #000; touch-action: pan-y; user-select: none;
  container-type: inline-size; border-radius: var(--r-media);
}
.cmp__img { position: absolute; inset: 0; width: 100%; height: 100%; object-fit: contain; }
/* Las dos fotos ocupan EXACTAMENTE la misma caja y la de delante se RECORTA con
   clip-path. Antes la capa `before` medía 50% y su imagen se redimensionaba con
   ella (360px contra 720px) → el rótulo del fondo salía dos veces y a distinto
   tamaño: se rompía la ilusión de que es el mismo pan. Con clip-path no hay
   redimensionado posible: es literalmente la misma foto recortada. */
.cmp__before {
  position: absolute; inset: 0; z-index: 2;
  clip-path: inset(0 calc(100% - var(--cut, 50%)) 0 0);
}
/* El corte: solo una línea de luz. SIN asa redonda y SIN input (Juan, 17-jul:
   "que no tenga el usuario que darle, así que sacamos ese círculo del medio").
   Va solo, para siempre → un asa sería mentir: promete algo que no se puede tocar.

   La línea va de ARRIBA ABAJO, entera. Aquí NO aplica lo de disolver los bordes:
   esta línea no es un borde decorativo, es la frontera entre el pan y la burger.
   Degradada por los extremos parecía que no llegaba y el corte perdía el sentido
   (Juan, 17-jul: "no va la línea hasta el final, así no tiene sentido"). */
.cmp__handle {
  position: absolute; top: 0; bottom: 0; left: 50%; z-index: 3;
  width: 1.5px; transform: translateX(-50%); pointer-events: none;
  background: rgba(254, 179, 0, .92);
}

/* ---------- Galería: COLLAGE, no rejilla ----------
   Lando no pone una cuadrícula: dispersa las fotos a tamaños distintos con su
   etiqueta de archivo encima y mucho aire. Es un tablón, no una tabla. La
   etiqueta va FUERA de la foto (dentro sería una pastilla flotante). */
/* Cada foto a su tamaño y su altura: el desnivel ES el diseño */
@media (max-width: 760px) {
  /* En móvil no se centra todo: se escalonan a la izquierda */
}

/* La Zona VIP se eliminó de toda la web (Juan, 16-jul). */

/* ---------- TICKER DE TEXTO: ORO ENCENDIDO, NO LINGOTE ----------
   Historia de este bloque, para no repetirla: Juan pidió "metalizado 3D dorado" y
   se hizo un lingote — degradado de 7 paradas, cursiva, biselado. Su veredicto:
   "te quedó feísimo, es muy poco premium" (17-jul). Y tenía razón: ese efecto es
   de plantilla de los 2000. El bisel y la cursiva son lo que lo delatan.

   Ahora: el eslogan de la marca dicho BAJITO. Más pequeño, oro limpio, y un glow
   cálido que hace que la letra parezca ENCENDIDA en vez de estampada. Lo premium
   aquí es la contención — un eslogan no necesita gritar para que se lea.
   Ver [[briox-voz-marca]]: el texto es su eslogan real, no se toca. */
.strip {
  overflow: hidden;
  padding: clamp(1rem, 1.8vw, 1.5rem) 0;
  /* Sin fondo propio: una banda con color de fondo sería una CAJA, y las cajas
     están prohibidas. El grid del fondo se ve a través y la tira flota. */
}
.strip__track {
  display: flex; width: max-content;
  animation: marquee 46s linear infinite;   /* más lento: es un susurro, no un anuncio */
}
.strip__track span {
  flex: none;
  /* PEQUEÑO (Juan, 17-jul). Cabe en la escala del HUD, no en la del titular. */
  font-size: clamp(.95rem, 1.5vw, 1.35rem);
  font-weight: var(--fw-semi);
  text-transform: uppercase;
  letter-spacing: .16em;      /* el aire entre letras es lo que lo hace caro */
  padding-right: clamp(2.5rem, 5vw, 4.5rem);
  color: var(--gold-2);
  /* EL GLOW: dos halos del MISMO oro, uno ceñido y otro amplio. Nunca blanco —
     un halo blanco sobre casi-negro ensucia; el oro sobre oro es luz de verdad.
     Va en text-shadow y no en filter: filter:blur crea una capa nueva por cada
     span y en un ticker de 4 copias eso se nota. */
  text-shadow:
    0 0 4px rgba(254, 179, 0, .55),
    0 0 18px rgba(254, 179, 0, .28);
}
/* El separador entre repeticiones: un punto, no un guion. Discreto. */
.strip__track span::after {
  content: "·";
  margin-left: clamp(2.5rem, 5vw, 4.5rem);
  color: rgba(254, 179, 0, .38);
  text-shadow: none;
}
@media (prefers-reduced-motion: reduce) { .strip__track { animation: none; } }

/* ---------- CHAMPIONS: ticker infinito, sin barra de scroll (Juan, 16-jul) ---------- */
.champs { padding: var(--gap-m) 0 var(--gap-s); }
.champs__marquee {
  overflow: hidden;
  -webkit-mask-image: linear-gradient(90deg, transparent, #000 5%, #000 95%, transparent);
  mask-image: linear-gradient(90deg, transparent, #000 5%, #000 95%, transparent);
}
.champs__track {
  display: flex; width: max-content;
  gap: clamp(.8rem, 1.6vw, 1.4rem);
  animation: marquee 44s linear infinite;
}
.champ { flex: none; margin: 0; width: clamp(240px, 27vw, 360px); }
.champ img { width: 100%; height: auto; border-radius: var(--r-media); }
@media (prefers-reduced-motion: reduce) { .champs__track { animation: none; } }

/* ---------- FUEGO: el brioche ardiendo, sin caja ----------
   `mix-blend-mode: screen` = modo TRAMA. Su fórmula solo SUMA luz: donde el vídeo
   es negro (valor 0) no suma nada y se ve la página; donde hay fuego, quema. Como
   el vídeo está rodado sobre negro puro, su fondo se evapora y queda el pan
   flotando. Cero bordes, cero rectángulo — sin tocar un solo píxel del vídeo.

   `isolation: isolate` NO se pone a propósito: el blend tiene que mezclarse con
   el fondo de la PÁGINA (y con la rejilla dorada, que asoma entre las llamas).
   Si se aislara, se mezclaría solo con la sección y volvería el rectángulo. */
.fuego {
  position: relative;
  display: grid; place-items: center;
  overflow: hidden;
  /* HERO, no un vídeo puesto ahí por poner (Juan, 17-jul). Ocupa el ancho entero
     y manda en la pantalla. El alto lo pone el propio vídeo al llenar el ancho. */
  width: 100vw; margin-left: calc(50% - 50vw);
}
/* EL APAGÓN. El modo trama SUMA lo que hay debajo... y debajo estaba la rejilla
   dorada: se veía A TRAVÉS de las llamas (Juan, 17-jul: "tiene el grid por
   encima"). No era que el grid estuviera encima — es que el vídeo lo estaba
   dejando pasar. Así que aquí se apaga la rejilla del todo, con un óvalo enorme
   y difuminado: negro absoluto bajo el fuego, y a los lados se funde con la
   página sin dejar canto. */
.fuego::before {
  content: ""; position: absolute; inset: -10% -5%; z-index: 0;
  background: radial-gradient(ellipse 62% 66% at 50% 50%,
    #000 0%, #000 46%, rgba(8,6,5,.86) 68%, transparent 92%);
}
.fuego__v {
  position: relative; z-index: 1;
  width: 100%; height: auto; display: block;
  /* El negro del vídeo se evapora y queda el pan ardiendo flotando. */
  mix-blend-mode: screen;
  /* LOS BORDES SE DISUELVEN, no se cortan (Juan, 17-jul: "acaba de golpe").
     El elipse de antes no bastaba y aquí está el porqué, que importa: el vídeo v1
     era negro PURO en los bordes (medido: rgb(1,0,0)) y el modo trama lo hacía
     desaparecer solo. El v2 tiene brasa ambiente llenando TODO el encuadre → ya no
     hay negro que evaporar y el rectángulo del vídeo se veía entero.
     Solución: dos degradados cruzados que matan los CUATRO lados antes de llegar
     al borde. `intersect` los multiplica: un píxel solo se ve si los dos lo dejan.
     Regla: si el material cambia, la máscara se revisa. Una máscara calculada para
     un vídeo no vale para otro. */
  -webkit-mask-image:
    linear-gradient(to bottom, transparent 0%, #000 20%, #000 78%, transparent 100%),
    linear-gradient(to right, transparent 0%, #000 14%, #000 86%, transparent 100%);
  mask-image:
    linear-gradient(to bottom, transparent 0%, #000 20%, #000 78%, transparent 100%),
    linear-gradient(to right, transparent 0%, #000 14%, #000 86%, transparent 100%);
  -webkit-mask-composite: source-in;
  mask-composite: intersect;
}
/* Si el sistema pide menos movimiento, el vídeo se para y queda su primer frame.
   No se esconde: la imagen sigue contando lo mismo, solo que quieta. */
@media (prefers-reduced-motion: reduce) {
  .fuego__v { animation: none; }
}

/* ---------- MAPA: las rutas salen de Galicia ---------- */
.mapa { padding: var(--gap-s) 0 var(--gap-m); overflow: hidden; }
/* El MAPA es el protagonista: se lleva el doble de sitio que el texto y sangra
   fuera del contenedor. El texto lo acompaña. (Juan, 16-jul) */
/* El orbe manda, pero no se come la pantalla. A 1.52fr salía a 900x900 — el 63%
   del viewport — y dejaba el texto en 287px, asfixiado (Juan, 17-jul: "arregla el
   mapa que ahora lo hiciste gigante"). Es la lección de siempre: "que tenga
   fuerza" no es "que sea enorme". La fuerza se la da ser lo único que se mueve en
   una sección oscura, no ocupar más metros. */
.mapa__grid { display: grid; grid-template-columns: minmax(280px, .72fr) minmax(0, 1.28fr); gap: clamp(1.5rem, 3vw, 3rem); align-items: center; }
/* El MAPA manda, el texto acompaña (Juan, 17-jul: "tiene que tener más fuerza el
   mapa que el texto, el texto aquí es gigante; queremos más impacto visual antes
   que una web cargadísima de textos").
   El titular baja de la escala de sección a la de un rótulo, y el párrafo se
   queda en tamaño de lectura. El protagonista es Europa encendiéndose. */
.mapa__copy .section-title {
  font-size: clamp(1.5rem, 2.4vw, 2.1rem);
  line-height: 1.1;
}
.mapa__copy .section-intro { font-size: clamp(.9rem, 1.05vw, 1rem); }
/* El grid se ancla a la IZQUIERDA y llega al borde derecho: así el mapa sangra sin
   límite y el texto sigue en el mismo eje que el resto de la web.
   (Con `margin-inline:auto` + margen negativo el grid medía más que el viewport y
   el centrado lo empujaba a x=-77 → el texto se pegaba al borde. Medido.) */
.mapa__grid {
  max-width: none; margin-inline: 0;
  padding-left: max(var(--pad), calc(50vw - var(--maxw) / 2 + var(--pad)));
  padding-right: 0;
}
.mapa__copy .section-intro { max-width: 46ch; }
/* Sin caja: el mapa NO es una foto pegada, es Europa asomando de la oscuridad.
   Una máscara elíptica deshace los cuatro bordes contra el fondo (Juan, 16-jul:
   "que se funda más con el entorno, ahí veo los bordes"). Nada de border-radius:
   un rectángulo redondeado seguiría siendo un rectángulo. */
.mapa__viz { position: relative; }
/* ---------- EL ORBE ----------
   CUADRADO siempre: una esfera en una caja rectangular deja aire muerto a los
   lados. `aspect-ratio` lo garantiza sin una línea de JS.

   Y con TOPE. Sin él crecía con su columna hasta 900x900 — el 63% de la pantalla —
   y hacía la sección más alta que el viewport: para ver el planeta entero había
   que hacer scroll DENTRO de la sección, que es exactamente lo que mata el efecto.
   `min(62vh, 640px)` lo ata a la ALTURA de la pantalla, no al ancho: así en un
   portátil bajo no se sale, y en un monitor grande no se desmadra.
   La lección: "que tenga fuerza" no es "que sea enorme" (Juan, 17-jul: "arregla
   el mapa que ahora lo hiciste gigante"). Cabe, o no impresiona. */
.orbe {
  display: block;
  width: 100%; max-width: min(78vh, 780px);
  height: auto; margin-inline: auto;
  aspect-ratio: 1 / 1;
  /* BORDES DIFUMINADOS (Juan, 17-jul: "quiero ver la vista del mapa agrandada y
     los bordes difuminados"). El mapa no acaba: se disuelve en la página.
     Esto es LO que lo convierte de "un cuadrado con un globo" en "una ventana al
     mapa". El lienzo es un rectángulo — la máscara hace que nadie lo sepa. */
  -webkit-mask-image: radial-gradient(ellipse 76% 76% at 50% 50%,
    #000 0%, #000 42%, rgba(0,0,0,.86) 60%, rgba(0,0,0,.45) 78%, transparent 95%);
  mask-image: radial-gradient(ellipse 76% 76% at 50% 50%,
    #000 0%, #000 42%, rgba(0,0,0,.86) 60%, rgba(0,0,0,.45) 78%, transparent 95%);
  /* Aparece cuando los datos están: sin esto se vería un cuadrado negro medio
     segundo y luego, de golpe, el planeta. */
  opacity: 0; transition: opacity .9s var(--ease);
}
.orbe.is-listo { opacity: 1; }
/* Si los datos no cargan, la sección NO se queda con un agujero negro: se esconde
   el lienzo y el texto se queda solo, que sigue contando lo mismo. */
.orbe.is-fallido { display: none; }
/* Los puntos ya son transparentes entre sí → el fondo de la web SE VE a través.
   Cero bordes, cero rectángulo. Un velo suave los apaga en los extremos. */
/* BORDES INFINITOS (Juan, 16-jul: "que parezca infinito, sin bordes"): dos
   máscaras multiplicadas — una elipse que apaga el centro hacia fuera, y un
   marco que mata los 4 lados mucho antes de llegar al borde. Ningún píxel del
   mapa toca el límite de su caja, así que no hay borde que ver. */
/* UNA sola elipse, generosa. Antes eran tres máscaras multiplicadas y entre las
   tres se comían el mapa: las lineales mataban todo lo que cayera fuera del
   18-82% horizontal... y CANARIAS vive en el 3-20%. O sea, se dibujaba y la
   máscara la borraba (por eso la ruta iba a la nada — no era que faltara: es que
   estaba tapada).

   Aquí no hacen falta más máscaras: los puntos YA son sueltos y translúcidos, y
   una costa punteada no forma un canto recto. La elipse solo apaga las esquinas
   para que Europa emerja de la oscuridad en vez de estar pegada en una caja. */
/* HUD de sala de control: los datos flotan SOBRE el mapa, como en un cockpit.
   Cifras reales de la web de Briox — nada inventado. */
/* El barrido del radar: una franja de luz recorre Europa y se va. Solo transform. */
@keyframes barrido {
  0%   { transform: translateX(-120%); }
  55%  { transform: translateX(340%); }
  100% { transform: translateX(340%); }
}
@media (prefers-reduced-motion: reduce) { .mapa__scan { display: none; } }

/* LAS RUTAS, en dos capas:
   1) el trazo base, tenue y permanente — la red existe siempre;
   2) un PULSO de luz que la recorre sin parar — es un envío viajando.
   Antes la línea se dibujaba una vez y se quedaba muerta (Juan, 16-jul:
   "llega un punto que se paran"). Ahora la red respira para siempre. */
@keyframes dibuja { to { stroke-dashoffset: 0; } }

/* el pulso: un guión corto de luz que viaja por el mismo trazado, en bucle */
@keyframes viaja {
  0%   { stroke-dashoffset: var(--len, 900); }
  100% { stroke-dashoffset: calc(var(--len, 900) * -1); }
}
@media (prefers-reduced-motion: reduce) { .pulso { display: none; } }

@keyframes enciende {
  from { opacity: 0; transform: scale(.2); transform-box: fill-box; transform-origin: center; }
  60%  { opacity: 1; transform: scale(1.5); transform-box: fill-box; transform-origin: center; }
  to   { opacity: 1; transform: scale(1); transform-box: fill-box; transform-origin: center; }
}

@keyframes ping {
  0%   { opacity: .9; transform: scale(.35); }
  70%  { opacity: 0;  transform: scale(2.2); }
  100% { opacity: 0;  transform: scale(2.2); }
}
@media (prefers-reduced-motion: reduce) {
  .mapa__viz .ruta { stroke-dashoffset: 0; animation: none; }
  .mapa__viz .ciudad { opacity: 1; animation: none; }
  .mapa__viz .origen__halo { animation: none; }
}

/* ---------- APP ---------- */
.app { padding: var(--gap-m) 0 var(--gap-s); }
.app__grid { display: grid; grid-template-columns: minmax(0, 1fr) minmax(0, 1fr); gap: clamp(2rem, 5vw, 4rem); align-items: center; }
.app__kicker { color: var(--gold); font-weight: var(--fw-semi); font-size: var(--fs-lead); margin: 0 0 .4rem; }

/* ---------- EL IPHONE: CSS 3D, no una foto ----------
   Todo son cajas: chasis, pantalla, notch. La escala vive en una sola variable
   (--u) → el móvil entero crece o mengua cambiando un número, sin descuadrarse. */
/* container-type: el móvil mide su escala contra ESTA caja, no contra la ventana.
   Antes --u salía de vw → en un teléfono de 390px el mockup pedía 402px y se salía
   (lo tapaba overflow-x:hidden, pero se veía cortado). Ahora encaja siempre. */
.app__phone { display: flex; flex-direction: column; align-items: center; justify-content: center; perspective: 1600px; container-type: inline-size; }
.iphone {
  /* 1u ≈ 1pt del iPhone real. 196u = ancho del móvil = 100cqw → u = 0.5102cqw:
     así el mockup SIEMPRE cabe en su columna y todo lo de dentro escala con él.
     Tope 1.85: a 2.9 el móvil salía de 495x1075px — más alto que media pantalla.
     Un iPhone se mira, no se habita. */
  --u: min(1.85px, 0.5102cqw);
  width: calc(196 * var(--u));
  transform-style: preserve-3d;
  transform: rotateY(-17deg) rotateX(6deg) rotateZ(-1.5deg);
  will-change: transform;
}
.iphone__body {
  position: relative;
  padding: calc(4 * var(--u));
  border-radius: calc(30 * var(--u));
  /* el titanio: el borde se ilumina arriba-izquierda y se apaga abajo */
  background: linear-gradient(148deg, #e6d9c4 0%, #8d7f6b 22%, #40382e 48%, #b9a customa 60%, #6d6154 78%, #e8dcc8 100%);
  background: linear-gradient(148deg, #e6d9c4 0%, #8d7f6b 22%, #40382e 48%, #6d6154 78%, #e8dcc8 100%);
  box-shadow:
    0 calc(30 * var(--u)) calc(50 * var(--u)) rgba(0, 0, 0, .75),
    0 calc(6 * var(--u)) calc(14 * var(--u)) rgba(0, 0, 0, .5),
    inset 0 0 0 1px rgba(255, 255, 255, .18);
}
.iphone__screen {
  position: relative;
  aspect-ratio: 196 / 415;
  border-radius: calc(26 * var(--u));
  background: #08080a;
  overflow: hidden;
  box-shadow: inset 0 0 0 1px rgba(0, 0, 0, .9);
}
.iphone__notch {
  position: absolute; top: calc(9 * var(--u)); left: 50%;
  transform: translateX(-50%);
  width: calc(58 * var(--u)); height: calc(15 * var(--u));
  border-radius: calc(9 * var(--u));
  background: #000; z-index: 3;
}

/* ---------- LA APP, DE VERDAD: explorable dentro del iPhone ----------
   La pantalla no es un dibujo: son las CATEGORÍAS y los PRODUCTOS reales del
   catálogo (snapshot horneado en app-demo.js). Se toca, se entra, se vuelve.
   Los precios NO se publican: son B2B → van bajo llave, y esa llave es el
   mejor motivo para descargar la app. */

/* El móvil está de escaparate (girado). Al tocarlo/pasar por encima se endereza:
   mirar de frente es lo que permite USARLO. Solo transform → compositor. */
/* Nunca más ancho que su columna: al apilar la pista debajo (columna) se perdió el
   encogido que daba el flex en fila, y el móvil se desbordaba. */
.iphone { max-width: 100%; transition: transform .6s var(--ease); }
.app__phone.is-live .iphone { transform: rotateY(0deg) rotateX(0deg) rotateZ(0deg); }

.ui {
  position: absolute; inset: 0;
  padding: calc(26 * var(--u)) calc(7 * var(--u)) 0;
  display: flex; flex-direction: column; gap: calc(3 * var(--u));
}

/* --- Barra superior: el back flota a la izquierda para que el logo NO se mueva --- */
.ui__bar { position: relative; display: flex; align-items: center; justify-content: space-between; padding: 0 calc(2 * var(--u)) calc(3 * var(--u)); }
.ui__logo { font-size: calc(8 * var(--u)); font-weight: var(--fw-med); color: var(--gold); letter-spacing: .02em; }
.ui__logo b { color: #fff; font-weight: var(--fw-black); }
.ui__cart { width: calc(8 * var(--u)); height: calc(8 * var(--u)); border: 1px solid var(--gold); border-radius: calc(2 * var(--u)); flex: none; }
/* --- Sub-barra: "‹ CATEGORÍA" = volver y saber dónde estás, en un solo control.
       (La app real aún no muestra el nombre de la categoría — hallazgo de la
       auditoría; aquí ya se enseña como debe ser.) --- */
.ui__sub { padding: 0 calc(2 * var(--u)) calc(1 * var(--u)); }
.ui[data-screen="home"] .ui__sub { display: none; }
.ui__back {
  display: inline-flex; align-items: center; gap: calc(1.6 * var(--u));
  background: none; border: 0; padding: calc(1 * var(--u)) 0; cursor: pointer;
  color: var(--gold); transition: transform .18s var(--ease);
}
.ui__back svg { width: calc(6 * var(--u)); height: calc(6 * var(--u)); fill: none; stroke: currentColor; stroke-width: 2.4; stroke-linecap: round; stroke-linejoin: round; flex: none; }
.ui__back span { font-size: calc(6.4 * var(--u)); font-weight: var(--fw-black); color: #fff; text-transform: uppercase; letter-spacing: .01em; line-height: 1; }
.ui__back:active { transform: scale(.96); }

/* --- Escenario: las pantallas se cruzan deslizando (solo transform/opacity) --- */
.ui__stage { position: relative; flex: 1; overflow: hidden; }
.ui__view {
  position: absolute; inset: 0; overflow-y: auto; overscroll-behavior: contain;
  scrollbar-width: none; -ms-overflow-style: none;
  display: grid; align-content: start;
  transition: opacity .26s var(--ease), transform .26s var(--ease);
}
.ui__view::-webkit-scrollbar { display: none; }
.ui[data-screen="home"] .ui__view--home { opacity: 1; transform: none; }
.ui[data-screen="home"] .ui__view--cat  { opacity: 0; transform: translateX(12%); pointer-events: none; }
.ui[data-screen="cat"]  .ui__view--home { opacity: 0; transform: translateX(-9%); pointer-events: none; }
.ui[data-screen="cat"]  .ui__view--cat  { opacity: 1; transform: none; }

/* --- Tarjeta de CATEGORÍA: la foto manda, el nombre encima --- */
.ui__view--home { gap: calc(4 * var(--u)); padding-bottom: calc(5 * var(--u)); }
.cc {
  position: relative; display: block; width: 100%; padding: 0;
  border: 1px solid var(--line-gold); border-radius: calc(5 * var(--u));
  overflow: hidden; background: var(--surface-1); aspect-ratio: 178 / 74;
  cursor: pointer; transition: transform .18s var(--ease);
}
.cc img { width: 100%; height: 100%; object-fit: cover; display: block; }
/* La foto YA lleva el nombre grabado → NO se superpone texto (se vería repetido).
   Lo único que la foto no dice es cuántos productos hay: eso sí, en una chapa. */
.cc__n {
  position: absolute; right: calc(4 * var(--u)); bottom: calc(4 * var(--u));
  background: rgba(8, 6, 5, .72); border: 1px solid var(--line-gold);
  color: var(--gold); font-size: calc(4.4 * var(--u)); font-weight: var(--fw-semi);
  padding: calc(1.4 * var(--u)) calc(3 * var(--u)); border-radius: 99px;
  backdrop-filter: blur(calc(2 * var(--u)));
}
.cc:active { transform: scale(.98); }

/* --- Tarjeta de PRODUCTO: la foto A LO ANCHO (trae el nombre grabado, si se
       recorta se decapita) + el precio bajo llave como chapa. Mismo idioma que
       las categorías: foto grande, una chapa, nada más. --- */
.ui__view--cat { grid-template-columns: 1fr; gap: calc(4.5 * var(--u)); padding-bottom: calc(5 * var(--u)); }
.pc { position: relative; }
.pc__ph {
  border-radius: calc(4 * var(--u)); overflow: hidden;
  border: 1px solid var(--line-gold); background: var(--surface-1);
  aspect-ratio: 560 / 297;   /* la proporción REAL de las fotos del catálogo */
}
.pc__ph img { width: 100%; height: 100%; object-fit: cover; display: block; }
.pc__lock {
  position: absolute; right: calc(4 * var(--u)); bottom: calc(4 * var(--u));
  display: flex; align-items: center; gap: calc(1.4 * var(--u));
  background: rgba(8, 6, 5, .72); border: 1px solid var(--line-gold);
  color: var(--gold); font-size: calc(4.4 * var(--u)); font-weight: var(--fw-semi);
  padding: calc(1.4 * var(--u)) calc(3 * var(--u)); border-radius: 99px;
  backdrop-filter: blur(calc(2 * var(--u)));
}
.pc__lock svg { width: calc(4.4 * var(--u)); height: calc(4.4 * var(--u)); fill: none; stroke: currentColor; stroke-width: 2; flex: none; }

/* --- Entrada en cascada al revelar la sección (one-shot, no perpetuo) --- */
.js .app__phone[data-reveal] .cc { opacity: 0; transform: translateY(calc(6 * var(--u))); }
.app__phone[data-reveal].in .cc {
  opacity: 1; transform: none;
  transition: opacity .45s var(--ease) calc(.3s + var(--i) * .07s),
              transform .45s var(--ease) calc(.3s + var(--i) * .07s);
}

/* --- Pista: que se sepa que ESTO SE TOCA (se va al primer toque) --- */
.app__hint {
  margin: 1.1rem 0 0; text-align: center;
  font-family: var(--font-mono); font-size: var(--fs-hud); text-transform: uppercase;
  letter-spacing: .08em; color: var(--gold);
  transition: opacity .4s var(--ease);
}
.app__hint.is-gone { opacity: 0; }

.ui__tabs { flex: none; display: flex; justify-content: space-around; padding: calc(4 * var(--u)) 0 calc(3 * var(--u)); border-top: 1px solid rgba(255,255,255,.07); }
.ui__tabs i { width: calc(9 * var(--u)); height: calc(9 * var(--u)); border-radius: 50%; border: 1px solid var(--gold); opacity: .5; }
.ui__tabs i:first-child { background: var(--gold); opacity: 1; }

@media (prefers-reduced-motion: reduce) {
  .js .app__phone[data-reveal] .cc { opacity: 1; transform: none; }
  .iphone, .ui__view, .cc, .app__hint { transition: none; }
}

.app__title {
  font-size: clamp(2.4rem, 5.2vw, 4.6rem);
  font-weight: var(--fw-black); text-transform: uppercase;
  line-height: .92; letter-spacing: var(--ls-hero); margin: 0;
}
.app__title .a { display: block; }
.app__title .a--gold { color: var(--gold); }
.app__note { color: var(--muted); font-size: var(--fs-small); font-weight: var(--fw-semi); margin: 1rem 0 0; }
.app__list {
  list-style: none; margin: clamp(1.5rem, 3vw, 2.2rem) 0 0; padding: 0;
  display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: .6rem 1.2rem;
}
.app__list li {
  font-family: var(--font-mono); font-size: var(--fs-hud); font-weight: 500;
  text-transform: uppercase; letter-spacing: .06em; color: var(--cream);
  border: 1px solid var(--line-gold); border-radius: var(--r-tight);
  padding: .7em .9em;
}

/* ---------- La OLA: el divisor de Shrine, pero vivo ----------
   Dos olas gemelas superpuestas cruzan en sentidos opuestos a velocidades distintas:
   nunca repiten el mismo dibujo, así que el borde "respira" en vez de ser una línea.
   Animan translate (compositor) — no se redibuja el SVG en ningún frame. */
.ola {
  position: absolute; left: 0; right: 0; z-index: 2;
  height: clamp(38px, 5vw, 74px);
  pointer-events: none; overflow: hidden;
}
.ola--top { top: 0; transform: translateY(-99%); }
.ola--bottom { bottom: 0; transform: translateY(99%) scaleY(-1); }
.ola svg {
  position: absolute; top: 0; left: 0;
  width: 200%; height: 100%;
  fill: var(--gold);
}
.ola svg:nth-child(1) { animation: onda 19s linear infinite; }
.ola svg:nth-child(2) { animation: onda 13s linear infinite reverse; opacity: .55; }
@keyframes onda {
  from { transform: translateX(0); }
  to   { transform: translateX(-50%); }
}
@media (prefers-reduced-motion: reduce) { .ola svg { animation: none; } }

/* ---------- FAQ: el muro de oro (único momento invertido de la web) ---------- */
.faq {
  position: relative;
  background: var(--gold); color: var(--ink-invert);
  /* Aire mínimo: la ola ya separa, no hace falta media pantalla en blanco
     (Juan, 16-jul, midiendo su web actual). */
  padding: clamp(1.6rem, 2.6vw, 2.4rem) 0 clamp(2rem, 3vw, 2.8rem);
  margin-top: clamp(2rem, 4vw, 3.2rem);
}
.faq__inner { max-width: 820px; }
.faq__title { font-size: var(--fs-h2); font-weight: var(--fw-black); letter-spacing: var(--ls-h2); text-align: center; margin: 0 0 clamp(1.2rem, 2vw, 1.8rem); }
.faq__list { display: grid; gap: .5rem; }
.qa { border-radius: var(--r-tight); background: rgba(10, 9, 8, .05); overflow: hidden; }
.qa summary {
  list-style: none; cursor: pointer;
  display: flex; align-items: center; justify-content: space-between; gap: 1rem;
  padding: 1.05em 1.2em;
  font-weight: var(--fw-semi); font-size: var(--fs-body);
  transition: background-color .25s var(--ease);
}
.qa summary::-webkit-details-marker { display: none; }
.qa summary:hover { background: rgba(10, 9, 8, .06); }
/* el + gira a x al abrir: el estado se ve, no se adivina */
.qa summary::after {
  content: "+"; flex: none;
  display: grid; place-items: center;
  width: 26px; height: 26px; border-radius: 6px;
  background: rgba(10, 9, 8, .1);
  font-weight: var(--fw-semi); line-height: 1;
  transition: transform .35s var(--ease), background-color .25s var(--ease);
}
.qa[open] summary::after { transform: rotate(135deg); background: var(--ink-invert); color: var(--gold); }
.qa__body { padding: 0 1.2em 1.15em; }
.qa__body p { margin: 0; color: rgba(10, 9, 8, .82); font-size: var(--fs-body); }
.qa__link { font-weight: var(--fw-semi); text-decoration: underline; text-underline-offset: 3px; }
.faq :focus-visible { outline: 2px solid var(--ink-invert); outline-offset: 2px; }

/* ---------- Footer ---------- */
/* padding-top extra = la altura de la ola: si no, la ola de abajo del FAQ cae
   encima del logo del footer (Juan, 16-jul: "el wave come el logo"). */
.site-footer { padding: calc(var(--gap-s) + clamp(38px, 5vw, 74px)) 0 var(--gap-s); }
.footer__inner { display: flex; align-items: center; justify-content: space-between; gap: 1.5rem; flex-wrap: wrap; }
.footer__copy { color: var(--muted); font-size: var(--fs-small); margin: .5rem 0 0; }
.footer__legal { display: flex; gap: clamp(1rem, 2vw, 1.8rem); flex-wrap: wrap; }
.footer__legal a {
  color: var(--gold); font-size: var(--fs-small); font-weight: var(--fw-med);
  transition: color .2s var(--ease);
}
.footer__legal a:hover { color: var(--gold-2); text-decoration: underline; text-underline-offset: 3px; }
.footer__meta { color: var(--muted); margin: 0; }

/* ---------- Móvil: NO se centra todo. La bandera izquierda es la fuerza. ---------- */
@media (max-width: 900px) {
  /* El objeto pasa DETRÁS del titular y sangra por la derecha: sigue siendo
     monumental sin robarle la primera pantalla al mensaje. */
  .hero { min-height: auto; padding-top: clamp(3rem, 9vh, 5rem); }
  .hero__grid { grid-template-columns: 1fr; gap: clamp(1.5rem, 5vw, 2.5rem); }
  .hero__object { justify-self: start; margin-right: 0; margin-left: -8%; }
  .hero__object img { height: clamp(18rem, 46vh, 26rem); }
  .pin { display: none; }          /* sin hover no hay dónde apoyarlos, y estorban */
  .hero__hud { position: static; margin: var(--gap-s) var(--pad) 0; }
  .hero__hud .hud__sep { margin-left: 0; }

  /* Mapa y App: una columna. El mapa NO se encoge — es la prueba de que estáis
     en toda Europa; se le deja el ancho entero. */
  .mapa__grid, .app__grid { grid-template-columns: minmax(0, 1fr); gap: var(--gap-s); }
  .app__phone { order: -1; max-width: 420px; }
  /* En táctil el móvil mira DE FRENTE: girado es un escaparate, y aquí se toca. */
  .iphone { transform: none; }
  .app__list { grid-template-columns: 1fr; }
}

/* --- Nombres de categoría y producto en la app ---
   Van PINTADOS porque las fotos oficiales de la tienda no traen el texto grabado
   (el juego de fotos anterior sí, pero venía con productos inventados). */
.cc__t {
  position: absolute; left: calc(6 * var(--u)); bottom: calc(5 * var(--u));
  display: flex; flex-direction: column; gap: calc(.5 * var(--u));
  font-size: calc(9 * var(--u)); font-weight: var(--fw-black);
  text-transform: uppercase; letter-spacing: -.01em; line-height: 1;
  color: #fff; text-shadow: 0 calc(1 * var(--u)) calc(4 * var(--u)) rgba(0,0,0,.95);
  text-align: left; pointer-events: none;
}
.cc__t em {
  font-size: calc(4.6 * var(--u)); font-weight: var(--fw-med); font-style: normal;
  text-transform: none; letter-spacing: 0; color: var(--gold-2);
}
.pc__n {
  display: block; margin-top: calc(3 * var(--u));
  font-size: calc(5.4 * var(--u)); font-weight: var(--fw-semi);
  color: #fff; line-height: 1.15;
}
