/* Brand values — split-column infinite slider.
   Everything is namespaced `values-*`; the source pack used bare .slide,
   .copy, .column and .overlay, which are far too generic for this page. */
:root {
  --vl-bg: #0a0a0b;
  --vl-ink: #f4efe8;
}

.values {
  position: relative;
  z-index: 6;
  width: 100%;
  height: 100svh;
  /* La cortina de entrada desplaza las columnas, así que durante ese tramo
     queda a la vista una franja del fondo de la sección. Medido: arriba de
     .values lo que se ve es el body (#141414) y esta sección es #0a0a0b —
     diez puntos más oscura—, de modo que esa franja se leía como un escalón
     negro recortado, no como parte de la composición.

     El degradado arranca en el tono de arriba y baja al propio en ~340px: lo
     que asome durante la entrada es ahora continuación de lo anterior. Una
     vez las columnas cierran, el degradado queda tapado y no se ve nunca. */
  background-color: var(--vl-bg);
  background-image: linear-gradient(
    180deg,
    #141414 0px,
    rgba(20, 20, 20, 0) 340px
  );
  color: var(--vl-ink);
  font-family: var(--ov-font-display);
  overflow: hidden;
}

.values-stage {
  position: absolute;
  inset: 0;
  display: flex;
  overflow: hidden;
}

.values-col {
  flex: 1;
  position: relative;
  height: 100%;
  overflow: hidden;
  will-change: transform;
}

.values-slide {
  position: absolute;
  inset: 0;
  overflow: hidden;
}

.values-slide img {
  width: 100%;
  height: 100%;
  object-fit: cover;
  display: block;
}

.values-slide .values-overlay {
  position: absolute;
  inset: 0;
  background: rgba(0, 0, 0, 0.55);
  pointer-events: none;
}

/* The copy is a full-viewport-wide layer anchored to the outer edge of each
   column. The left column clips it to its left half and the right column to
   its right half, so the two halves recompose one centred headline that
   splits apart as the columns reveal in opposite directions. */
.values-copy {
  position: absolute;
  top: 0;
  /* 200% del propio slide —que mide lo que la columna— y NO 100vw.

     Las dos columnas son flex:1 dentro de .values-stage, así que juntas miden
     el ancho del CONTENIDO. `100vw`, en cambio, incluye la barra de scroll:
     la capa de texto salía ~15px más ancha que las dos columnas juntas, y la
     mitad derecha —anclada a right:0— quedaba desplazada esa diferencia
     respecto de la izquierda. El resultado era que se perdían caracteres
     justo en la costura: "ESPACIO & LUZ" se leía "ESPAC & LUZ" y "pensado",
     "psado". No era la animación, era la barra de scroll.

     200% del slide siempre equivale exacto a las dos columnas, haya barra o
     no, así que las dos mitades recomponen la palabra sin junta visible. */
    width: 200%;
  height: 100%;
  pointer-events: none;
}

/* Plato de lectura.

   El texto se apoyaba directamente sobre la fotografía. Con cuatro fotos
   distintas debajo, el mismo rótulo caía unas veces sobre cielo claro y otras
   sobre madera oscura, y el velo plano de .values-overlay no basta: oscurece
   por igual toda la columna, así que subirlo para salvar la foto más clara
   apagaba las otras tres.

   Este es un velo centrado y local, del tamaño del bloque de texto: le da
   fondo propio donde hace falta y se desvanece antes de tocar los bordes, de
   modo que la fotografía sigue leyéndose alrededor.

   Va en ::before del propio .values-copy —y no como una capa aparte— porque
   así hereda su misma deriva vertical: cualquier otra capa se quedaría quieta
   mientras el texto se mueve, y el fondo se despegaría de lo que sostiene.
   Al ser el primer hijo, se pinta por debajo de tags, título y nota sin
   necesidad de z-index. */
.values-copy::before {
  content: "";
  position: absolute;
  left: 50%;
  top: 50%;
  transform: translate(-50%, -50%);
  width: min(76%, 980px);
  height: min(62%, 480px);
  background: radial-gradient(
    ellipse at center,
    rgba(10, 10, 11, 0.7) 0%,
    rgba(10, 10, 11, 0.5) 46%,
    rgba(10, 10, 11, 0) 74%
  );
  pointer-events: none;
}

/* Promoted only while the slider is actually running — values.js adds
   .is-running when the pin engages. These two selectors cover an image and a
   100vw-wide copy layer per slide, and the section keeps several buffered
   slides alive at a time, so leaving the hint on permanently had Safari
   allocating and rasterising every one of them on the frames the section
   scrolls into view. The slides that cannot be seen are hidden outright in
   values.js; this keeps the ones that can from being promoted any earlier
   than they need to be. */
.values.is-running .values-slide img,
.values.is-running .values-copy {
  will-change: transform;
}

.values-left .values-copy { left: 0; }
.values-right .values-copy { right: 0; }

.values-title {
  position: absolute;
  top: 50%;
  left: 50%;
  transform: translate(-50%, -50%);
  text-transform: uppercase;
  font-size: clamp(2.5rem, 10vw, 13rem);
  font-weight: 700;
  letter-spacing: -0.03em;
  line-height: 1;
  white-space: nowrap;
}

.values-tags {
  position: absolute;
  top: 32.5%;
  left: 50%;
  transform: translateX(-50%);
  text-align: center;
  text-transform: uppercase;
  font-size: clamp(0.7rem, 1.05vw, 1.1rem);
  font-weight: 500;
  letter-spacing: 0.12em;
  line-height: 1.9;
  opacity: 0.88;
  white-space: nowrap;
}

.values-note {
  position: absolute;
  top: 63%;
  left: 50%;
  transform: translateX(-50%);
  text-align: center;
  font-size: clamp(0.85rem, 1.1vw, 1.05rem);
  line-height: 1.5;
  opacity: 0.78;
  white-space: nowrap;
}

/* ── Chrome ──────────────────────────────────────────────────────────── */
.values-grain {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  z-index: 3;
  opacity: 0.05;
  mix-blend-mode: overlay;
  pointer-events: none;
}

.values-corner {
  position: absolute;
  width: 14px;
  height: 14px;
  z-index: 4;
  pointer-events: none;
}
.values-corner::before,
.values-corner::after {
  content: "";
  position: absolute;
  background: rgba(244, 239, 232, 0.3);
}
.values-corner::before { width: 1px; height: 14px; left: 50%; top: 0; transform: translateX(-50%); }
.values-corner::after { width: 14px; height: 1px; top: 50%; left: 0; transform: translateY(-50%); }
.values-corner-tl { top: 32px; left: 32px; }
.values-corner-br { bottom: 32px; right: 32px; }

/* Tipografía en .sec-eyebrow (style.css). Aquí solo la colocación. */
.values-eyebrow {
  position: absolute;
  top: 40px;
  left: 50%;
  transform: translateX(-50%);
  z-index: 4;
  margin: 0;
  /* Al estar posicionado con left:50%, la caja sólo dispone del tramo que va
     de ahí al borde derecho —195px en un teléfono de 390—, así que el nombre
     se partía en dos líneas mientras los otros cuatro índices ocupaban una.
     max-content la deja medirse por su contenido; el max-width impide que
     eso se convierta en desbordamiento lateral. */
  width: max-content;
  max-width: calc(100vw - 2.5rem);
}

.values-progress {
  position: absolute;
  bottom: 74px;
  left: 50%;
  transform: translateX(-50%);
  z-index: 4;
  width: min(360px, 46vw);
  height: 1px;
  background: rgba(244, 239, 232, 0.18);
}
.values-progress i {
  display: block;
  height: 100%;
  width: var(--vl-step, 25%);
  background: var(--vl-ink);
  transform-origin: left;
  transition: transform 0.6s cubic-bezier(0.65, 0, 0.35, 1);
}

.values-counter {
  position: absolute;
  bottom: 42px;
  left: 50%;
  transform: translateX(-50%);
  z-index: 4;
  margin: 0;
  font-size: 11px;
  letter-spacing: 0.2em;
  color: rgba(244, 239, 232, 0.45);
}
.values-counter b { color: var(--vl-ink); font-weight: 600; }

@media (max-width: 640px) {
  .values-corner { display: none; }
  .values-tags { top: 26%; line-height: 1.7; }
  .values-note { top: 68%; white-space: normal; width: 80vw; }
}

/* ── Arrival, on the compositor ───────────────────────────────────────── */
/* The two columns part like a curtain as the section scrolls in. That motion
   used to be a GSAP scrub, and it trembled in Safari no matter what was done
   to the layers underneath it.
   
   The reason is structural, not a bug to be found: a scrubbed tween is
   computed on the main thread from a scroll position the compositor has
   already moved past, so the columns are always applying last frame's offset
   to this frame's scroll. Blink hides it; Safari, which scrolls further ahead
   of the main thread, does not. Nothing done inside that model removes the
   gap — it can only be made less visible.
   
   A scroll-driven CSS animation is a different model. The timeline is the
   scroll position itself, evaluated by the compositor alongside the scroll,
   so the columns and the page move on the same frame by construction. There
   is no phase error left to see.
   
   The GSAP path stays as the fallback in values.js for engines without this;
   the @supports condition here and the CSS.supports() test there are
   deliberately the same string so exactly one of the two can ever run. */
/* 16%, no 100%.

   Con el recorrido completo cada columna empezaba fuera de su caja, así que
   la franja de fondo descubierta llegaba a medir media pantalla — es el
   bloque negro que se veía al entrar. La geometría es: franja = recorrido x
   (lo que le falta a la sección para entrar), y con 100% eso alcanza ~455px
   en el peor momento; con 16% no pasa de ~125px, y encima ahora funde con el
   degradado de .values en vez de recortarse contra él.

   El gesto se conserva: las dos columnas siguen partiendo en direcciones
   opuestas, sólo que la amplitud es de acento y no de telón completo.

   Si se cambia este valor hay que cambiar TAMBIÉN el yPercent del camino de
   respaldo en values.js — son la misma animación para motores distintos. */
@keyframes vl-arrive-up { from { transform: translateY(16%); } }
@keyframes vl-arrive-down { from { transform: translateY(-16%); } }

@supports (animation-timeline: view()) {
  @media (prefers-reduced-motion: no-preference) {
    /* Named and declared on the section rather than on each column, because
       the columns are what move: a view() timeline on a subject that is being
       translated by its own animation feeds back on itself. The section's own
       box is untouched by the arrival, so it is the stable reference. */
    .values {
      view-timeline: --vl-arrival block;
    }

    .values-left,
    .values-right {
      animation-timeline: --vl-arrival;
      /* `entry` spans exactly the stretch the old scrub covered: from the
         section's top edge reaching the bottom of the viewport, to the
         section sitting fully in view — which for a 100svh section is the
         moment the pin engages. */
      animation-range: entry;
      animation-duration: 1ms;
      animation-timing-function: linear;
      /* `backwards` matters: without it the columns sit at their resting
         position until the timeline is first evaluated, so the curtain is
         already open on the frame the section appears. */
      animation-fill-mode: both;
    }
    .values-left { animation-name: vl-arrive-up; }
    .values-right { animation-name: vl-arrive-down; }
  }
}
