/* ============================================================
   BUYDEPA PRESENTATIONS · MOTION SYSTEM
   ============================================================

   Lenguaje de movimiento para presentaciones Buydepa.
   Filosofía: "calm confidence" — refined, never flashy.

   3 niveles de intensidad (declarar en <body data-motion="...">):
     • still   → 0 animación. Default para PDF export.
     • subtle  → reveals al cargar slide, sin loops. Para directorio en pantalla.
     • lively  → reveals + KPI count-up + bar grow + hover lift.
                 Para decks comerciales / interno / live demos.

   USO en HTML:
     <body data-motion="subtle">
       <section class="slide">
         <p class="slide__eyebrow reveal">CAPA 1 · …</p>
         <h1 class="slide__title reveal" data-stagger="1">…</h1>
         <p class="slide__subtitle reveal" data-stagger="2">…</p>
       </section>

   El JS controller (scripts/slide-controller.js) agrega .visible a
   cada .slide cuando entra al viewport, disparando los reveals.

   ============================================================ */

:root {
  /* ─── Easings ─── */
  /* ease-out-expo · entrada sofisticada, "se asienta" */
  --byd-ease-out: cubic-bezier(0.16, 1, 0.3, 1);
  /* ease-in-out estándar · transiciones bidireccionales */
  --byd-ease-inout: cubic-bezier(0.65, 0, 0.35, 1);
  /* ease-out-quart · más sobrio que expo, para body/secundarios */
  --byd-ease-quart: cubic-bezier(0.25, 1, 0.5, 1);
  /* ease-in-out-back · sutil overshoot · usar solo en 1 elemento hero por deck */
  --byd-ease-back: cubic-bezier(0.34, 1.56, 0.64, 1);

  /* ─── Durations ─── */
  --byd-dur-fast: 200ms;       /* hover, micro-interactions */
  --byd-dur-normal: 480ms;     /* entrada de elementos */
  --byd-dur-slow: 720ms;       /* títulos, números grandes */
  --byd-dur-bar: 900ms;        /* crecimiento de barras de chart */
  --byd-dur-count: 1400ms;     /* count-up de KPIs */
  --byd-dur-sweep: 600ms;      /* sweep de eyebrow / section divider */

  /* ─── Stagger ─── */
  --byd-stagger: 90ms;         /* cadencia entre hermanos */
  --byd-stagger-tight: 60ms;   /* listas largas (6+ items) */
  --byd-stagger-loose: 140ms;  /* 2-3 hero elements */

  /* ─── Travel distance ─── */
  --byd-travel-sm: 12px;       /* body, captions */
  --byd-travel-md: 24px;       /* títulos, cards */
  --byd-travel-lg: 40px;       /* big numbers, hero */
}

/* ============================================================
   BASE · .reveal hidden state
   ============================================================
   Cualquier elemento con .reveal arranca oculto. Cuando el slide
   padre recibe .visible (por el IntersectionObserver), reveals
   se ejecutan en cascada.
   ============================================================ */

[data-motion="subtle"] .reveal,
[data-motion="lively"] .reveal {
  opacity: 0;
  transform: translateY(var(--byd-travel-md));
  transition:
    opacity var(--byd-dur-normal) var(--byd-ease-out),
    transform var(--byd-dur-normal) var(--byd-ease-out);
  will-change: opacity, transform;
}

[data-motion="subtle"] .slide.visible .reveal,
[data-motion="lively"] .slide.visible .reveal {
  opacity: 1;
  transform: translateY(0);
}

/* Variantes de reveal — agregar después de .reveal: */
.reveal--fade { transform: none !important; }
.reveal--up   { transform: translateY(var(--byd-travel-md)); }
.reveal--down { transform: translateY(calc(-1 * var(--byd-travel-md))); }
.reveal--left { transform: translateX(calc(-1 * var(--byd-travel-md))); }
.reveal--right{ transform: translateX(var(--byd-travel-md)); }
.reveal--scale{ transform: scale(0.96); }

[data-motion="subtle"] .slide.visible .reveal--scale,
[data-motion="lively"] .slide.visible .reveal--scale {
  transform: scale(1);
}

[data-motion="subtle"] .slide.visible .reveal--left,
[data-motion="subtle"] .slide.visible .reveal--right,
[data-motion="lively"] .slide.visible .reveal--left,
[data-motion="lively"] .slide.visible .reveal--right {
  transform: translateX(0);
}

/* ============================================================
   STAGGER · cascada de delays
   ============================================================
   Aplicar con data-stagger="N" (1..12) o con :nth-child fallback.
   Preferimos atributo explícito para evitar ambigüedad cuando
   hay wrappers intermedios.
   ============================================================ */

.reveal[data-stagger="1"]  { transition-delay: calc(1 * var(--byd-stagger)); }
.reveal[data-stagger="2"]  { transition-delay: calc(2 * var(--byd-stagger)); }
.reveal[data-stagger="3"]  { transition-delay: calc(3 * var(--byd-stagger)); }
.reveal[data-stagger="4"]  { transition-delay: calc(4 * var(--byd-stagger)); }
.reveal[data-stagger="5"]  { transition-delay: calc(5 * var(--byd-stagger)); }
.reveal[data-stagger="6"]  { transition-delay: calc(6 * var(--byd-stagger)); }
.reveal[data-stagger="7"]  { transition-delay: calc(7 * var(--byd-stagger)); }
.reveal[data-stagger="8"]  { transition-delay: calc(8 * var(--byd-stagger)); }
.reveal[data-stagger="9"]  { transition-delay: calc(9 * var(--byd-stagger)); }
.reveal[data-stagger="10"] { transition-delay: calc(10 * var(--byd-stagger)); }
.reveal[data-stagger="11"] { transition-delay: calc(11 * var(--byd-stagger)); }
.reveal[data-stagger="12"] { transition-delay: calc(12 * var(--byd-stagger)); }

/* Fallback :nth-child para casos rápidos */
.reveal-group > .reveal:nth-child(1) { transition-delay: calc(1 * var(--byd-stagger)); }
.reveal-group > .reveal:nth-child(2) { transition-delay: calc(2 * var(--byd-stagger)); }
.reveal-group > .reveal:nth-child(3) { transition-delay: calc(3 * var(--byd-stagger)); }
.reveal-group > .reveal:nth-child(4) { transition-delay: calc(4 * var(--byd-stagger)); }
.reveal-group > .reveal:nth-child(5) { transition-delay: calc(5 * var(--byd-stagger)); }
.reveal-group > .reveal:nth-child(6) { transition-delay: calc(6 * var(--byd-stagger)); }

/* ============================================================
   SIGNATURE · eyebrow sweep
   ============================================================
   El "tell" de marca Buydepa en presentaciones. Cuando un slide
   entra, el eyebrow tiene una línea Byzantine que crece de
   izquierda a derecha bajo el texto. Solo en eyebrow del slide
   principal (no en cards internas).
   ============================================================ */

[data-motion="subtle"] .slide__eyebrow,
[data-motion="lively"] .slide__eyebrow {
  position: relative;
  display: inline-block;
  padding-bottom: 12px;
}

[data-motion="subtle"] .slide__eyebrow::after,
[data-motion="lively"] .slide__eyebrow::after {
  content: "";
  position: absolute;
  left: 0;
  bottom: 0;
  height: 2px;
  width: 100%;
  background: currentColor;
  transform-origin: left center;
  transform: scaleX(0);
  transition: transform var(--byd-dur-sweep) var(--byd-ease-out);
  transition-delay: 150ms;
}

[data-motion="subtle"] .slide.visible .slide__eyebrow::after,
[data-motion="lively"] .slide.visible .slide__eyebrow::after {
  transform: scaleX(1);
}

/* ============================================================
   SECTION DIVIDER · sweep horizontal
   ============================================================
   Para slide-section-divider · barra Byzantine crece L→R.
   ============================================================ */

[data-motion="subtle"] .section-divider__bar,
[data-motion="lively"] .section-divider__bar {
  transform-origin: left center;
  transform: scaleX(0);
  transition: transform var(--byd-dur-slow) var(--byd-ease-out);
  transition-delay: 200ms;
}

[data-motion="subtle"] .slide.visible .section-divider__bar,
[data-motion="lively"] .slide.visible .section-divider__bar {
  transform: scaleX(1);
}

/* ============================================================
   KPI · count-up (lively only)
   ============================================================
   Los elementos con .kpi-value cuentan de 0 al valor target.
   El JS controller lee data-target y anima. Aquí solo el
   transform inicial para que se sienta el "asentamiento".
   ============================================================ */

[data-motion="lively"] .kpi-value {
  opacity: 0;
  transform: translateY(var(--byd-travel-lg)) scale(0.92);
  transition:
    opacity var(--byd-dur-slow) var(--byd-ease-out),
    transform var(--byd-dur-slow) var(--byd-ease-out);
}

[data-motion="lively"] .slide.visible .kpi-value {
  opacity: 1;
  transform: translateY(0) scale(1);
}

/* En modo subtle, no contamos pero sí revealamos suave */
[data-motion="subtle"] .kpi-value {
  opacity: 0;
  transform: translateY(var(--byd-travel-md));
  transition:
    opacity var(--byd-dur-normal) var(--byd-ease-out),
    transform var(--byd-dur-normal) var(--byd-ease-out);
}

[data-motion="subtle"] .slide.visible .kpi-value {
  opacity: 1;
  transform: translateY(0);
}

/* ============================================================
   CHART · bar grow-in
   ============================================================
   Aplicar a .bc__bar (chart-templates/bar-chart-vertical).
   Cada barra crece desde el suelo con stagger automático.
   ============================================================ */

[data-motion="lively"] .bc__bar {
  transform-origin: bottom center;
  transform: scaleY(0);
  transition: transform var(--byd-dur-bar) var(--byd-ease-out);
}

[data-motion="lively"] .slide.visible .bc__bar {
  transform: scaleY(1);
}

[data-motion="lively"] .slide.visible .bc__col:nth-child(1) .bc__bar  { transition-delay: 100ms; }
[data-motion="lively"] .slide.visible .bc__col:nth-child(2) .bc__bar  { transition-delay: 160ms; }
[data-motion="lively"] .slide.visible .bc__col:nth-child(3) .bc__bar  { transition-delay: 220ms; }
[data-motion="lively"] .slide.visible .bc__col:nth-child(4) .bc__bar  { transition-delay: 280ms; }
[data-motion="lively"] .slide.visible .bc__col:nth-child(5) .bc__bar  { transition-delay: 340ms; }
[data-motion="lively"] .slide.visible .bc__col:nth-child(6) .bc__bar  { transition-delay: 400ms; }
[data-motion="lively"] .slide.visible .bc__col:nth-child(7) .bc__bar  { transition-delay: 460ms; }
[data-motion="lively"] .slide.visible .bc__col:nth-child(8) .bc__bar  { transition-delay: 520ms; }
[data-motion="lively"] .slide.visible .bc__col:nth-child(9) .bc__bar  { transition-delay: 580ms; }
[data-motion="lively"] .slide.visible .bc__col:nth-child(10) .bc__bar { transition-delay: 640ms; }
[data-motion="lively"] .slide.visible .bc__col:nth-child(11) .bc__bar { transition-delay: 700ms; }
[data-motion="lively"] .slide.visible .bc__col:nth-child(12) .bc__bar { transition-delay: 760ms; }

/* ============================================================
   LINE / AREA · path draw-in (lively only)
   ============================================================
   Para SVG paths con stroke. Requiere setear
   stroke-dasharray y stroke-dashoffset al largo del path
   desde JS (o estimar).
   ============================================================ */

[data-motion="lively"] .line-draw {
  stroke-dasharray: 2000;
  stroke-dashoffset: 2000;
  transition: stroke-dashoffset var(--byd-dur-slow) var(--byd-ease-quart);
  transition-delay: 300ms;
}

[data-motion="lively"] .slide.visible .line-draw {
  stroke-dashoffset: 0;
}

/* ============================================================
   CARDS · hover lift (lively only · live presentations)
   ============================================================ */

[data-motion="lively"] .card {
  transition:
    transform var(--byd-dur-fast) var(--byd-ease-quart),
    box-shadow var(--byd-dur-fast) var(--byd-ease-quart);
}

[data-motion="lively"] .card:hover {
  transform: translateY(-4px);
  box-shadow: 0 12px 32px -8px rgba(33, 77, 216, 0.18);
}

/* ============================================================
   ATMOSPHERE · ambient gradient mesh
   ============================================================
   Background opcional para portadas o slides hero. Usa Magnolia
   + Byzantine en muy baja opacidad. Solo activar con
   .slide--atmosphere o .slide-title.atmosphere
   ============================================================ */

.slide--atmosphere {
  background:
    radial-gradient(ellipse 1200px 800px at 85% 15%, rgba(33, 77, 216, 0.08), transparent 60%),
    radial-gradient(ellipse 1000px 700px at 10% 90%, rgba(247, 245, 255, 1), transparent 60%),
    #ffffff;
}

.slide--atmosphere-dark {
  background:
    radial-gradient(ellipse 1200px 800px at 85% 15%, rgba(33, 77, 216, 0.35), transparent 60%),
    radial-gradient(ellipse 1000px 700px at 10% 90%, rgba(33, 77, 216, 0.15), transparent 60%),
    #0a1230;
}

/* ============================================================
   GRAIN · sutil noise texture
   ============================================================
   Para slides hero o de cierre. Solo se nota a tamaño completo.
   ============================================================ */

.slide--grain::before {
  content: "";
  position: absolute;
  inset: 0;
  pointer-events: none;
  opacity: 0.04;
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='200' height='200' viewBox='0 0 200 200'%3E%3Cfilter id='n'%3E%3CfeTurbulence baseFrequency='0.9' numOctaves='2' stitchTiles='stitch'/%3E%3C/filter%3E%3Crect width='200' height='200' filter='url(%23n)' opacity='1'/%3E%3C/svg%3E");
  z-index: 1;
}

.slide--grain > * { position: relative; z-index: 2; }

/* ============================================================
   REDUCED MOTION · respeto del SO
   ============================================================ */

@media (prefers-reduced-motion: reduce) {
  [data-motion="subtle"] .reveal,
  [data-motion="lively"] .reveal,
  [data-motion="subtle"] .kpi-value,
  [data-motion="lively"] .kpi-value,
  [data-motion="lively"] .bc__bar,
  [data-motion="lively"] .line-draw {
    opacity: 1 !important;
    transform: none !important;
    stroke-dashoffset: 0 !important;
    transition-duration: 0.01ms !important;
  }

  .slide__eyebrow::after,
  .section-divider__bar {
    transform: scaleX(1) !important;
  }
}

/* ============================================================
   PRINT / PDF · siempre still
   ============================================================
   Cuando exportamos, ignoramos data-motion y mostramos todo
   en su estado final.
   ============================================================ */

@media print {
  .reveal,
  .kpi-value,
  .bc__bar,
  .line-draw {
    opacity: 1 !important;
    transform: none !important;
    stroke-dashoffset: 0 !important;
  }
  .slide__eyebrow::after,
  .section-divider__bar {
    transform: scaleX(1) !important;
  }
}
