/* ==========================================================================
   SECCION 03 — BEYOND THE SHOWROOM
   Catalogo -> respiracion obsidiana -> fotografia contenida -> full bleed.

   UNA sola fotografia cambiando su relacion con el viewport. No hay capas,
   ni separacion coche/fondo, ni parallax, ni 3D: la velocidad ya esta en la
   fotografia. El codigo solo interpola su geometria.

   NO modifica app.js, hero.js, hero.css, style.css, catalog.css, catalog.js,
   header.css ni header.js. De catalog.css consume UNICAMENTE --site-container
   y --cat-obsidian, igual que ya hace header.css.
   ========================================================================== */

:root{
  /* ---- CALIBRACION DEL RECORRIDO ----
     air   : respiracion obsidiana entre el catalogo y la fotografia.
     travel: pantallas de pin del sticky. La seccion completa mide
             air + 1 (entrada de la escena) + travel = 2.32 viewports. */
  --beyond-air: 0.12;
  --beyond-travel: 1.20;

  /* Relacion natural del asset: 1672 / 941. Vive aqui porque la caja de
     recorte y el reduced-motion la necesitan sin pasar por JS. */
  --beyond-ar: 1.77683;

  --beyond-ink: #F4F2ED;

  /* Manrope entra sola en cuanto exista localmente. Sin fuentes remotas. */
  --beyond-font: 'Manrope', 'Segoe UI Variable Display', 'Segoe UI',
                 system-ui, -apple-system, 'Helvetica Neue', Arial, sans-serif;

  /* ---- POSICIONES VERTICALES ----
     Porcentajes de la altura del stage, medidos sobre la composicion
     aprobada. Son TOPS DE CAJA; la correccion em de abajo compensa la
     distancia entre el borde de caja y la altura de mayuscula. Cambiar
     cualquiera de estos cuatro valores recoloca su linea sin tocar nada mas. */
  --beyond-y-eyebrow: 5.84%;
  --beyond-y-title:  19.98%;
  --beyond-y-rule:   33.70%;
  --beyond-y-sub:    36.56%;
}

/* ==========================================================================
   1. SECCION Y PISTA
   El obsidian es el mismo del catalogo: sin este valor compartido apareceria
   un escalon visible contra el #000 de body.
   ========================================================================== */
.beyond{
  position:relative;
  background:var(--cat-obsidian, #080808);
  color:var(--beyond-ink);
  font-family:var(--beyond-font);
  font-synthesis:none;
  -webkit-font-smoothing:antialiased;
}
.beyond-air{height:calc(var(--beyond-air) * 100svh);pointer-events:none}

/* La altura de la pista ES la duracion de la escena. Bajo reduced-motion la
   regla no aplica y la seccion colapsa a su alto natural: cero scroll muerto. */
.beyond-track{position:relative}
@media not (prefers-reduced-motion: reduce){
  .beyond-track{height:calc((1 + var(--beyond-travel)) * 100svh)}
}

/* ==========================================================================
   2. STAGE
   Caja de recorte. El ancho es 100% del flujo normal, NUNCA 100vw: 100vw
   incluye la barra de scroll y produciria desbordamiento horizontal.
   ========================================================================== */
.beyond-stage{
  position:sticky;
  top:0;
  height:100svh;
  overflow:hidden;
  isolation:isolate;
}

/* Sonda de medida: resuelve --site-container a pixeles sin duplicar el valor
   en JS. Si manana cambia el raíl del sitio, esta seccion lo sigue sola. */
.beyond-rail{
  position:absolute;
  top:0;left:0;
  width:var(--site-container, min(92vw, 1680px));
  height:0;
  visibility:hidden;
  pointer-events:none;
}

/* ==========================================================================
   3. FOTOGRAFIA
   Tamano fijo escrito por beyond.js (imgW x imgH). Lo unico que cambia por
   frame es transform: sin reflow, sin re-rasterizado, compositor puro.

   transform-origin izquierda: el recorte residual del full bleed sale
   INTEGRO por la derecha —pared oscura sin landmarks— y la salida luminosa
   del tunel, la fuga y la carretera se conservan al 100%.
   ========================================================================== */
.beyond-photo{
  position:absolute;
  left:0;
  top:0;
  display:block;
  /* La caja ya tiene la relacion natural del asset; cover garantiza que un
     redondeo de subpixel nunca llegue a deformar la fotografia. */
  object-fit:cover;
  object-position:0% 55%;
  transform-origin:left center;
  will-change:transform;
  user-select:none;
  -webkit-user-drag:none;
}

/* ==========================================================================
   3b. EDGE DISSOLVE — BEYOND TRANSITION V1.3 (CONTINUOUS EXPAND)
   Mascara sobre el CONTENEDOR, nunca sobre el transform de la foto: los
   CUATRO bordes del rectangulo visible estan fundidos con el obsidian de
   .beyond durante la llegada Y durante la expansion. Dos degradados
   lineales (vertical x horizontal) intersectados: las esquinas salen
   fundidas por producto. Ni radial ni elipse ni viñeta.
   Existe mientras beyond.js marca data-beyond-edge="on", es decir mientras
   algun borde siga dentro de la pantalla; en full bleed (q >= .62) no hay
   mascara y la foto se pinta intacta.
   Variables (px, beyond.js, en cada frame):
     --beyond-edge-top/-right/-bottom/-left : rectangulo visible de la foto
                                              dentro del stage
     --beyond-fe-top/-right/-bottom/-left   : ancho del fundido de cada borde
                                              (0 = ese borde ya alcanzo el
                                              limite de la pantalla)
   En el borde el alfa es siempre 0 y la rampa usa paradas smoothstep
   (0,.104,.352,.648,.896,1): sin linea de arranque. Fuera del rectangulo no
   hay contenido, solo obsidian.
   ========================================================================== */
.beyond-stage[data-beyond-edge="on"]{
  --bx-t:  var(--beyond-edge-top, 0px);
  --bx-r:  var(--beyond-edge-right, 100%);
  --bx-b:  var(--beyond-edge-bottom, 100%);
  --bx-l:  var(--beyond-edge-left, 0px);
  --bx-ft: var(--beyond-fe-top, 0px);
  --bx-fr: var(--beyond-fe-right, 0px);
  --bx-fb: var(--beyond-fe-bottom, 0px);
  --bx-fl: var(--beyond-fe-left, 0px);
  --bx-v: linear-gradient(to bottom,
    rgb(0 0 0 / 0)    var(--bx-t),
    rgb(0 0 0 / .104) calc(var(--bx-t) + var(--bx-ft) * .2),
    rgb(0 0 0 / .352) calc(var(--bx-t) + var(--bx-ft) * .4),
    rgb(0 0 0 / .648) calc(var(--bx-t) + var(--bx-ft) * .6),
    rgb(0 0 0 / .896) calc(var(--bx-t) + var(--bx-ft) * .8),
    #000 calc(var(--bx-t) + var(--bx-ft)),
    #000 calc(var(--bx-b) - var(--bx-fb)),
    rgb(0 0 0 / .896) calc(var(--bx-b) - var(--bx-fb) * .8),
    rgb(0 0 0 / .648) calc(var(--bx-b) - var(--bx-fb) * .6),
    rgb(0 0 0 / .352) calc(var(--bx-b) - var(--bx-fb) * .4),
    rgb(0 0 0 / .104) calc(var(--bx-b) - var(--bx-fb) * .2),
    rgb(0 0 0 / 0)    var(--bx-b));
  --bx-h: linear-gradient(to right,
    rgb(0 0 0 / 0)    var(--bx-l),
    rgb(0 0 0 / .104) calc(var(--bx-l) + var(--bx-fl) * .2),
    rgb(0 0 0 / .352) calc(var(--bx-l) + var(--bx-fl) * .4),
    rgb(0 0 0 / .648) calc(var(--bx-l) + var(--bx-fl) * .6),
    rgb(0 0 0 / .896) calc(var(--bx-l) + var(--bx-fl) * .8),
    #000 calc(var(--bx-l) + var(--bx-fl)),
    #000 calc(var(--bx-r) - var(--bx-fr)),
    rgb(0 0 0 / .896) calc(var(--bx-r) - var(--bx-fr) * .8),
    rgb(0 0 0 / .648) calc(var(--bx-r) - var(--bx-fr) * .6),
    rgb(0 0 0 / .352) calc(var(--bx-r) - var(--bx-fr) * .4),
    rgb(0 0 0 / .104) calc(var(--bx-r) - var(--bx-fr) * .2),
    rgb(0 0 0 / 0)    var(--bx-r));
  -webkit-mask-image:var(--bx-v), var(--bx-h);
          mask-image:var(--bx-v), var(--bx-h);
  -webkit-mask-composite:source-in;
          mask-composite:intersect;
  -webkit-mask-repeat:no-repeat;
          mask-repeat:no-repeat;
  -webkit-mask-size:100% 100%;
          mask-size:100% 100%;
}

/* ==========================================================================
   4. TEXTO
   Centrado respecto al STAGE, no respecto al centro del archivo: es lo que
   el ojo ve centrado una vez la fotografia sangra y el recorte derecho ya
   ha entrado. Vive FUERA de la caja que escala, asi que nunca se deforma.
   ========================================================================== */
.beyond-copy{
  position:absolute;
  inset:0;
  z-index:2;
  pointer-events:none;
  text-align:center;
}
.beyond-copy > *{
  position:absolute;
  left:50%;
  margin:0;
  transform:translateX(-50%);
  white-space:nowrap;
}

/* Firma editorial de la composicion. NO es el wordmark del concesionario. */
.beyond-eyebrow{
  top:calc(var(--beyond-y-eyebrow) - .14em);
  font-size:clamp(11px, 1.48svh, 17px);
  font-weight:500;
  line-height:1;
  letter-spacing:.5em;
  /* El tracking anade aire a la derecha de la ultima letra; se compensa
     para que el bloque quede opticamente centrado. */
  text-indent:.5em;
  text-transform:uppercase;
}

.beyond-title{
  top:calc(var(--beyond-y-title) - .19em);
  font-size:clamp(34px, 5.17svh, 68px);
  font-weight:300;
  line-height:1.19;
  letter-spacing:.27em;
  text-indent:.27em;
  text-transform:uppercase;
}

.beyond-rule{
  top:var(--beyond-y-rule);
  width:6%;
  height:1px;
  background:rgba(244,242,237,.42);
}

.beyond-sub{
  top:calc(var(--beyond-y-sub) - .14em);
  font-size:clamp(13px, 1.91svh, 22px);
  font-weight:400;
  line-height:1;
  letter-spacing:.3em;
  text-indent:.3em;
  text-transform:uppercase;
}

/* Estado base VISIBLE: sin JS la seccion se lee entera. beyond.js solo
   esconde lo que va a animar, y solo cuando el movimiento esta permitido. */

/* ==========================================================================
   5. REDUCED MOTION
   Sin sticky, sin recorrido y sin recorte: la fotografia entra a ancho
   completo con su alto natural y el texto ya esta puesto. La seccion pasa de
   2.32 viewports a su alto natural.
   ========================================================================== */
@media (prefers-reduced-motion: reduce){
  .beyond-air{height:calc(var(--beyond-air) * 50svh)}
  .beyond-stage{
    position:relative;
    top:auto;
    height:auto;
    aspect-ratio:var(--beyond-ar);
  }
  .beyond-photo{
    position:absolute;
    inset:0;
    width:100%;
    height:100%;
    transform:none;
    object-position:center;
  }
  /* Sin edge dissolve: la foto entra entera, sin estados invisibles. */
  .beyond-stage[data-beyond-edge]{
    -webkit-mask-image:none;
            mask-image:none;
  }
}

/* ==========================================================================
   6. DEBUG — solo con #debug en la URL.
   Abajo a la IZQUIERDA para no pisar #hero-debug, que vive a la derecha.
   ========================================================================== */
#beyond-debug{
  position:fixed;
  left:14px;
  bottom:14px;
  z-index:9999;
  width:248px;
  padding:12px 14px;
  background:rgba(8,8,8,.86);
  border:1px solid #2a2a2a;
  color:#F4F2ED;
  font:11px/1.55 ui-monospace, SFMono-Regular, Consolas, monospace;
  letter-spacing:.02em;
  pointer-events:none;
  white-space:pre;
}
#beyond-debug b{color:#C8B89A;font-weight:600}
#beyond-debug .beyond-debug-rail{
  position:relative;
  display:block;
  height:16px;
  margin:9px 0 3px;
  border-top:1px solid #3a3a3a;
}
#beyond-debug .beyond-debug-tick{
  position:absolute;
  top:0;
  width:1px;
  height:5px;
  background:#5a5a5a;
}
#beyond-debug .beyond-debug-tick span{
  position:absolute;
  top:6px;
  left:50%;
  transform:translateX(-50%);
  font-size:8px;
  color:#8A8A86;
  letter-spacing:0;
}
#beyond-debug .beyond-debug-head{
  position:absolute;
  top:-3px;
  width:1px;
  height:11px;
  background:#F4F2ED;
}
