/* =============================================================================
   motion.css — vocabulario de movimiento y paleta de gráficos de sohamiot.com.
   Lo comparten Home (sistema-soham.css + home.css), Industria y Labs (styles.css).

   DOCTRINA: el estado FINAL es el estado por omisión. Sin JavaScript, con
   movimiento reducido, al entrar por un ancla o en un navegador viejo, todo se
   ve terminado. Cuatro clases gobiernan lo demás:
     html.m-listo  — la pone el script de <head> solo si el visitante NO pidió
                     movimiento reducido. Sin ella, ninguna regla de aquí actúa.
     .m-espera     — la pone motion.js SOLO a las piezas [data-m] que al cargar
                     quedan bajo el pliegue: es el estado «aún no dibujado».
     .m-activo     — la pone el IntersectionObserver una sola vez: dispara.
     html.m-fin    — red de seguridad: si motion.js no corre en 3 s, todo al final.
   ============================================================================= */

:root{
  --m-rapido:150ms;  --m-medio:250ms;  --m-largo:400ms;  --m-autoral:600ms;
  --m-salida:cubic-bezier(.16,1,.3,1);
  --m-cierre:cubic-bezier(.4,0,1,1);
  --m-d1:4px; --m-d2:8px; --m-d3:14px;
  --m-escalon:60ms;
  /* styles.css usa --transition-medium en :650 y :835 sin definirla nunca. */
  --transition-medium:var(--m-largo) var(--m-salida);
}

/* Paleta de gráficos por rama. Los SVG solo conocen estas variables y currentColor. */
.theme-smarthome{
  --g-trazo:var(--negro);--g-tenue:var(--linea);--g-texto:var(--texto);
  --g-acento:var(--verde);--g-fondo:var(--arena);
  --g-ok:var(--verde-hover);--g-ok-tenue:var(--verde-tenue);
  --g-alerta:var(--alto);--g-alerta-tenue:var(--alto-tenue);
}
.theme-industry,.theme-labs{
  --g-trazo:#F8FAFC;--g-tenue:rgba(255,255,255,.18);--g-texto:#CBD5E1;
  --g-acento:var(--primary-accent);--g-fondo:rgba(15,23,42,.6);
  --g-ok:#10B981;--g-ok-tenue:rgba(16,185,129,.12);
  --g-alerta:#EF4444;--g-alerta-tenue:rgba(239,68,68,.12);
}

/* ---------------- Gráficos: base sin movimiento ---------------- */
.grafico{display:block;width:100%;height:auto;color:var(--g-trazo);overflow:visible}
.grafico text{fill:var(--g-texto);font-family:inherit}
.grafico .t{
  fill:none;stroke:currentColor;stroke-width:1.25;
  stroke-linecap:round;stroke-linejoin:round;vector-effect:non-scaling-stroke;
}
.grafico .t-tenue{stroke:var(--g-tenue)}
.grafico .t-acento{stroke:var(--g-acento)}
.grafico .t-ok{stroke:var(--g-ok)}
.grafico .t-alerta{stroke:var(--g-alerta)}
.grafico .r-fondo{fill:var(--g-fondo)}
.grafico .r-acento{fill:var(--g-acento)}
.grafico .r-ok{fill:var(--g-ok)}
.grafico .r-alerta{fill:var(--g-alerta)}
/* Las cotas van punteadas. Como el punteado ocupa stroke-dasharray, una cota
   nunca se «dibuja» por dashoffset: aparece por opacidad (.m-aparece). */
.grafico .cota{stroke-dasharray:3 4}
.glifo{width:44px;height:44px;color:var(--g-trazo)}
figure.figura{margin:0}
figure.figura figcaption{margin-top:.75rem;color:var(--g-texto)}

/* Diagramas anchos en telefono. Un viewBox de 960 unidades dentro de un marco de
   327 px cae a escala 0.341: el rotulo de 36 unidades queda en 12.3 px y las
   marcas de hallazgo de index.html en 4.1 x 2.7 px (medido 2026-08-22 a 375 px
   en index, electrico, industry y labs). En vez de encogerlo hasta lo ilegible,
   el grafico conserva un ancho minimo y su marco desplaza en horizontal. El
   marco lleva tabindex="0" porque una region con desplazamiento tiene que
   alcanzarse con teclado (WCAG 2.1.1). */
@media (max-width:699px){
  /* El min-width:0 no es adorno. Sin el, el ancho minimo del SVG sube por la
     cadena como min-content y quien recorta es un ancestro con overflow:hidden:
     medido en industry.html, .hero-visual crecia a 520 px, #hero.hero-section lo
     cortaba a 375 y 169 px del dibujo quedaban inalcanzables, sin barra que
     desplazar. Con el, la figura cede y el marco es quien desplaza. */
  figure.figura,.marco-grafico{min-width:0}
  .marco-grafico{max-width:100%;overflow-x:auto;overscroll-behavior-x:contain}
  .marco-grafico>.grafico{min-width:520px}
  .marco-grafico:focus-visible{outline:2px solid var(--g-acento);outline-offset:3px}
}

/* ---------------- Movimiento: solo bajo html.m-listo ---------------- */
@media (prefers-reduced-motion:no-preference){

  /* P1 «trazo»: path con pathLength="1". Dos disparadores:
     (a) bajo el pliegue: .m-espera → .m-activo, por transición;
     (b) en portada (.m-portada): keyframes desde el primer cuadro pintado. */
  .m-listo .m-espera .m-trazo{stroke-dasharray:1;stroke-dashoffset:1}
  .m-listo .m-espera.m-activo .m-trazo{
    stroke-dashoffset:0;
    transition:stroke-dashoffset var(--m-autoral) var(--m-salida) var(--m-retardo,0ms);
  }
  .m-listo .m-portada .m-trazo{
    stroke-dasharray:1;
    animation:m-dibuja var(--m-autoral) var(--m-salida) var(--m-retardo,0ms) both;
  }
  @keyframes m-dibuja{from{stroke-dashoffset:1}to{stroke-dashoffset:0}}

  /* P2 «aparece»: nodos y rótulos que llegan al final de su trazo. */
  .m-listo .m-espera .m-aparece{opacity:0}
  .m-listo .m-espera.m-activo .m-aparece{
    opacity:1;transition:opacity var(--m-medio) var(--m-salida) var(--m-retardo,0ms);
  }
  .m-listo .m-portada .m-aparece{
    animation:m-asoma var(--m-medio) var(--m-salida) var(--m-retardo,0ms) both;
  }
  @keyframes m-asoma{from{opacity:0}to{opacity:1}}

  /* P3 «entrada»: un bloque sube 14 px una vez. Solo listas que entran como
     lista; nunca cada sección. Escalonado total ≤ 300 ms. */
  .m-listo .m-espera .m-entrada,
  .m-listo .m-espera.m-entrada{opacity:.001;transform:translateY(var(--m-d3))}
  .m-listo .m-espera.m-activo .m-entrada,
  .m-listo .m-espera.m-entrada.m-activo{
    opacity:1;transform:none;
    transition:opacity var(--m-largo) var(--m-salida) var(--m-retardo,0ms),
               transform var(--m-largo) var(--m-salida) var(--m-retardo,0ms);
  }

  /* P7 «diagrama»: fases. La hoja de cada página declara qué oculta cada
     [data-fase]; aquí solo la transición compartida de lo que cambia. */
  .m-listo [data-m="diagrama"][data-fase] .fase{
    transition:opacity var(--m-medio) var(--m-salida),
               transform var(--m-medio) var(--m-salida),
               fill var(--m-medio) var(--m-salida),
               stroke-dashoffset var(--m-autoral) var(--m-salida);
  }

  /* P8 «panel»: display none → block con transición. Donde no hay soporte de
     allow-discrete el panel aparece de golpe, que es el estado actual. */
  .m-panel{
    opacity:0;transform:translateY(calc(-1 * var(--m-d1)));
    transition:opacity var(--m-rapido) var(--m-cierre),
               transform var(--m-rapido) var(--m-cierre),
               display var(--m-rapido) allow-discrete;
  }
  .m-panel.m-abierto{
    opacity:1;transform:none;
    transition:opacity var(--m-medio) var(--m-salida),
               transform var(--m-medio) var(--m-salida),
               display var(--m-medio) allow-discrete;
  }
  @starting-style{
    .m-panel.m-abierto{opacity:0;transform:translateY(calc(-1 * var(--m-d1)))}
  }

  /* P5 «estado» en bandas: solo con puntero que flota; la foto no se mueve. */
  @media (hover:hover){
    .m-banda .banda-txt{transition:transform var(--m-rapido) var(--m-salida)}
    .m-banda:hover .banda-txt,
    .m-banda:focus-visible .banda-txt{transform:translateY(calc(-1 * var(--m-d1)))}
    .m-banda .ancla{transition:border-color var(--m-rapido) ease}
    .m-banda:hover .ancla,
    .m-banda:focus-visible .ancla{border-bottom-color:#fff}
  }
}

/* ---------------- Estado: vale con y sin movimiento ---------------- */
.form-response-msg{
  opacity:1;padding:.75rem 1rem;border-radius:12px;
  transition:opacity var(--m-medio) var(--m-salida);
}
.form-response-msg:empty{opacity:0;padding:0}
.form-response-msg.ok{color:var(--g-ok);background:var(--g-ok-tenue)}
.form-response-msg.error{color:var(--g-alerta);background:var(--g-alerta-tenue)}
[aria-busy="true"]{cursor:progress}
.sh-btn[disabled],.btn[disabled]{opacity:.55}
.theme-smarthome [data-m-control][aria-pressed="true"]{
  background:var(--negro);border-color:var(--negro);color:#fff;
}
.theme-industry [data-m-control][aria-pressed="true"],
.theme-labs [data-m-control][aria-pressed="true"]{
  background:var(--primary-accent);border-color:var(--primary-accent);color:#0B0F19;
}

/* ---------------- Redes de seguridad ---------------- */
.m-pausa,.m-pausa *{animation-play-state:paused!important}
.m-fin .m-trazo{animation:none!important;transition:none!important;stroke-dashoffset:0!important}
.m-fin .m-aparece,.m-fin .m-entrada,.m-fin [data-fase] .fase{
  animation:none!important;transition:none!important;opacity:1!important;transform:none!important;
}
@media (prefers-reduced-motion:reduce){
  *,*::before,*::after{
    animation-duration:.01ms!important;animation-iteration-count:1!important;
    transition-duration:.01ms!important;scroll-behavior:auto!important;
  }
}
