/* ==========================================================================
   BRIGHTLOOP — CURSOR Y MOVIMIENTO
   --------------------------------------------------------------------------
   La capa expresiva del sistema. Dos cosas, y ninguna decorativa por
   decorar:

   1. CURSOR — un triángulo macizo, sin trazo ni borde, en rojo Japón. Sigue
      al puntero con una inercia mínima y reacciona a lo que hay debajo:
      es el único elemento de la página que responde en tiempo real.
   2. MOVIMIENTO — gestos cortos, uno por elemento y con un motivo:
      dirección, jerarquía o respuesta al puntero. Nada que se mueva solo
      para llamar la atención.
   3. RITMO DE SECCIÓN — la sección que se está leyendo va a plena luz y las
      vecinas se apagan. Es lo que hace que pasar de una a otra se note sin
      necesidad de una línea, un icono ni un cambio de color.

   Ni un valor de color literal: todo sale de tokens.css.
   Todo el movimiento muere con «reducir movimiento» (E3).
   ========================================================================== */


/* ==========================================================================
   1. CURSOR
   Un solo triángulo relleno. La punta ES la coordenada del puntero, así que
   el vértice va en el (0,0) del viewBox y no hay que compensar nada.
   ========================================================================== */

.bl-cursor {
  position: fixed;
  inset-block-start: 0;
  inset-inline-start: 0;
  z-index: 200;
  display: none;
  width: var(--cursor-size);
  pointer-events: none;
  opacity: 0;
  transition: opacity var(--dur-fast) var(--ease-in-out);
  will-change: translate;
}
.bl-cursor[data-on='true'] { opacity: 1; }
.bl-cursor[data-out='true'] { opacity: 0; }

/* Sólo con ratón: en táctil no hay puntero al que seguir, y en un lápiz el
   cursor del sistema es el que sabe dónde está la punta. */
@media (hover: hover) and (pointer: fine) {
  html[data-cursor='on'] .bl-cursor { display: block; }

  /* El descendiente hace falta: hay componentes (el deslizador del panel,
     los botones) que declaran su propio cursor y taparían al nuestro. */
  html[data-cursor='on'],
  html[data-cursor='on'] * { cursor: none; }
}

.bl-cursor__arrow {
  display: block;
  width: 100%;
  height: auto;
  fill: var(--cursor-color);
  stroke: none;                      /* macizo, sin borde: es la regla */
  transform-origin: 0 0;
  /* Ni halo ni cambio de tamaño al pasar por encima de algo pulsable: el
     puntero dice dónde estás, no hace de efecto. Lo único que se mantiene
     es el color, y ni siquiera cambia. */
}

/* ==========================================================================
   4. MOVIMIENTO DE INTERFAZ
   ========================================================================== */

/* --- Cabecera: se comprime y se vuelve traslúcida al bajar ---------------- */
.site-header {
  transition: background-color var(--dur-base) var(--ease-out),
              border-color var(--dur-base) var(--ease-out);
}
html[data-scrolled='true'] .site-header {
  background-color: color-mix(in srgb, var(--surface-page) 84%, transparent);
  -webkit-backdrop-filter: blur(12px) saturate(1.4);
          backdrop-filter: blur(12px) saturate(1.4);
  border-block-end-color: var(--border-strong);
}

/* --- Navegación: el subrayado crece desde la izquierda -------------------- */
.site-nav a {
  position: relative;
  padding-block-end: 2px;
}
.site-nav a::after {
  content: '';
  position: absolute;
  inset-block-end: 0;
  inset-inline-start: 0;
  width: 100%;
  height: 1px;
  background-color: currentColor;
  opacity: 0;
  transition: opacity var(--dur-fast) var(--ease-in-out);
}
.site-nav a:hover::after { opacity: 1; }

/* --- Filas: el hover repinta, y nada más ---------------------------------
   Se marca el borde y el texto secundario sube a primario. Nada se mueve de
   sitio: desplazar una fila al pasar por encima hace que la página parezca
   inestable justo cuando se está intentando leer. */
.row-item {
  transition: border-color var(--dur-base) var(--ease-out);
}
.row-item > * { transition: color var(--dur-base) var(--ease-out); }
@media (hover: hover) and (pointer: fine) {
  .row-item:hover {
    border-block-end-color: var(--border-strong);
  }
  .row-item:hover .t-secondary { color: var(--text-primary); }
}

/* --- Tarjetas planas del método: el filete superior se refuerza ----------- */
.tile { transition: border-color var(--dur-base) var(--ease-out); }
@media (hover: hover) and (pointer: fine) {
  .tile:hover { border-block-start-color: var(--text-primary); }
}

/* --- Límites: al pasar, la linea sube a primario ------------------------- */
.limits li { transition: color var(--dur-base) var(--ease-out); }
.limits svg { transition: color var(--dur-base) var(--ease-out); }
@media (hover: hover) and (pointer: fine) {
  .limits li:hover { color: var(--text-primary); }
  .limits li:hover svg { color: var(--text-primary); }
}


/* ==========================================================================
   5. RITMO DE SECCIÓN
   --------------------------------------------------------------------------
   Una sección encendida y el resto en penumbra. Tres decisiones detrás:

   · Se apaga el CONTENIDO (`> .shell`), nunca la sección. Bajarle la opacidad
     a la sección entera volvería translúcido el fondo de tinta de
     «Resultados» y dejaría ver el papel de la sección de al lado por debajo.
   · Sólo opacidad. Ni desenfoque —cuesta caro y se ve barato— ni
     desplazamiento: mover de sitio lo que hay alrededor de lo que estás
     leyendo marea.
   · Lento a propósito (`--dur-slow`): a la velocidad de un hover el cambio
     parpadearía en cada scroll corto.
   ========================================================================== */

/* La transición sólo existe una vez repartido el primer estado: en la carga,
   ver las secciones de abajo apagarse solas parece un error de pintura. */
html[data-sections='on'][data-settled='true'] main > section > .shell {
  transition: opacity var(--dur-section) var(--ease-veil);
}
html[data-sections='on'] main > section[data-in='false'] > .shell {
  opacity: var(--section-dim);
}

/* El hero es la portada: mientras se ve, se ve entero. Apagarlo al bajar dos
   dedos hacía que la página pareciera estar cargando todavía. */
html[data-sections='on'] .hero[data-in='false'] > .shell { opacity: var(--section-dim-hero); }

/* Anclaje suave al cambiar de sección. `proximity` y no `mandatory`: sólo
   ayuda cuando ya te has parado cerca de un borde, y nunca secuestra el
   scroll en mitad de una sección larga. El desfase de la cabecera pegajosa
   ya está en `scroll-padding-top` (base.css §1). */
@media (min-height: 34rem) {
  html[data-snap='on'] { scroll-snap-type: y proximity; }
  html[data-snap='on'] main > section { scroll-snap-align: start; }
}


/* ==========================================================================
   6. ENTRADA AL LLEGAR — cuatro formas, una a la vez
   --------------------------------------------------------------------------
   Cada bloque aparece una vez, cuando su sección llega. Cuál de las cuatro
   se usa lo dice `data-reveal-style` en el <html>, y el panel de diseño lo
   cambia en vivo (Movimiento en el scroll). El nombre de la animación viaja
   en una custom property, así que cambiar de estilo es cambiar una variable
   y no reescribir la regla.

     velo      la pieza se destapa de arriba abajo, con 8 px de subida
     cortina   se descubre de izquierda a derecha, sin moverse de sitio
     respiro   crece desde el 96,5%, anclada por su esquina inferior
     escalon   el clásico: 12 px de subida y opacidad

   Tres cosas que no son gratuitas:

   · `animation` y no `transition`: varias de estas piezas —las tarjetas de
     servicio, las citas— ya tienen su propia `transition` para el hover, y
     una segunda declaración se la comería entera.
   · Al terminar, js/motion.js pone `data-shown='done'` y la animación
     desaparece: nada se queda con un `clip-path` puesto para siempre, que es
     lo que recortaría después la sombra de una tarjeta al pasar por encima.
   · El recorte se sale 8% por los lados (`-8%`) para no cortar sombras ni
     anillos de foco mientras dura.

   El estado de partida vive detrás de `html[data-reveal='on']`, atributo que
   escribe js/motion.js al arrancar. Sin JavaScript no hay nada oculto.
   ========================================================================== */

html[data-reveal='on'] [data-reveal] { opacity: 0; }
html[data-reveal='on'] [data-reveal][data-shown] { opacity: 1; }

html[data-reveal='on'] [data-reveal][data-shown='true'] {
  animation: var(--reveal-anim, bl-velo) var(--dur-reveal) var(--ease-veil) both;
  animation-delay: calc(var(--reveal-i, 0) * var(--reveal-step));
}

html[data-reveal-style='cortina'] { --reveal-anim: bl-cortina; }
html[data-reveal-style='respiro'] { --reveal-anim: bl-respiro; }
html[data-reveal-style='escalon'] { --reveal-anim: bl-escalon; }

/* El respiro necesita saber por dónde agarra: la esquina de abajo a la
   izquierda, que es donde empieza a leerse el bloque. */
html[data-reveal-style='respiro'] [data-reveal][data-shown='true'] {
  transform-origin: 0% 100%;
}

@keyframes bl-velo {
  0%   { opacity: 0; clip-path: inset(0 -8% 100% -8%); translate: 0 8px; }
  55%  { opacity: 1; }
  100% { opacity: 1; clip-path: inset(0 -8% -8% -8%); translate: 0 0; }
}

@keyframes bl-cortina {
  0%   { opacity: 0; clip-path: inset(-8% 100% -8% -8%); }
  30%  { opacity: 1; }
  100% { opacity: 1; clip-path: inset(-8% -8% -8% -8%); }
}

@keyframes bl-respiro {
  from { opacity: 0; scale: 0.965; }
  to   { opacity: 1; scale: 1; }
}

@keyframes bl-escalon {
  from { opacity: 0; translate: 0 var(--reveal-shift); }
  to   { opacity: 1; translate: 0 0; }
}

/* La regla del kicker se dibuja de izquierda a derecha con la sección. Es el
   único gesto que señala el cambio de sección de forma explícita, y dura lo
   que dura la entrada del propio titular. El selector se conforma con que el
   atributo exista: cuando pasa a 'done' la animación no debe reiniciarse. */
html[data-reveal='on'] .section-kicker[data-shown]::after {
  animation: bl-rule var(--dur-reveal) var(--ease-veil) both;
  animation-delay: calc(var(--reveal-i, 0) * var(--reveal-step) + 120ms);
  transform-origin: left center;
}
@keyframes bl-rule {
  from { scale: 0 1; }
  to   { scale: 1 1; }
}

/* --- Movimiento reducido: nada de esto ocurre (E3) ------------------------
   base.css ya deja las animaciones en 0.01 ms, pero eso no basta aquí: sin
   estas dos reglas, un bloque al que todavía no le ha llegado el turno se
   quedaría invisible, y las secciones vecinas, apagadas. Con movimiento
   reducido la página se ve entera y a plena luz, que es lo que se espera. */
@media (prefers-reduced-motion: reduce) {
  html[data-reveal='on'] [data-reveal] { opacity: 1; animation: none; }
  html[data-reveal='on'] .section-kicker[data-shown]::after { animation: none; scale: 1 1; }
  html[data-sections='on'] main > section > .shell { opacity: 1; }
  html[data-snap='on'] { scroll-snap-type: none; }
}

/* Lo mismo con contraste alto: apagar contenido es bajar contraste, y ahí
   eso no se negocia. */
@media (prefers-contrast: more) {
  html[data-sections='on'] main > section > .shell { opacity: 1; }
}
