/* NodoSOE — Splash de arranque (Opción B aprobada + rebrand) */
#splash-nodos{
  position:fixed;inset:0;z-index:9999;
  display:flex;align-items:center;justify-content:center;
  background:var(--ink);
  transition:opacity .45s ease, visibility .45s ease;
}
#splash-nodos.splash-hidden{opacity:0;visibility:hidden;pointer-events:none}

#splash-nodos .glow{
  position:absolute;width:260px;height:260px;border-radius:50%;
  background:radial-gradient(circle,rgba(248,116,6,.18),transparent 65%);
  animation:splashGlow 2.6s ease-in-out infinite;
}
@keyframes splashGlow{0%,100%{opacity:.5;transform:scale(1)}50%{opacity:1;transform:scale(1.08)}}

#splash-nodos .mark{position:relative;animation:splashLatido 2.6s ease-in-out infinite}
@keyframes splashLatido{0%,100%{transform:scale(1)}50%{transform:scale(1.045)}}
#splash-nodos .mark svg{display:block;filter:drop-shadow(0 8px 30px rgba(248,116,6,.35))}

#splash-nodos .splash-inner{
  display:flex;flex-direction:column;align-items:center;justify-content:center;gap:30px;
}

#splash-nodos .word{
  color:#fff;font-size:26px;font-weight:800;letter-spacing:.01em;
  opacity:0;animation:splashSube .7s .5s cubic-bezier(.2,.8,.3,1) forwards;
  text-align:center;
}
#splash-nodos .word span{
  background:linear-gradient(135deg,var(--login-accent-soft),#B84E05);
  -webkit-background-clip:text;background-clip:text;color:transparent;
}

#splash-nodos .tag{
  color:rgba(255,255,255,.5);font-size:11.5px;font-weight:600;letter-spacing:.22em;
  text-transform:uppercase;margin-top:8px;text-align:center;
  opacity:0;animation:splashSube .7s .7s cubic-bezier(.2,.8,.3,1) forwards;
}
#splash-nodos .tag-sub{
  color:rgba(255,255,255,.28);font-size:9.5px;font-weight:500;letter-spacing:.18em;
  text-transform:uppercase;margin-top:5px;text-align:center;
  opacity:0;animation:splashSube .7s .85s cubic-bezier(.2,.8,.3,1) forwards;
}
@keyframes splashSube{from{opacity:0;transform:translateY(10px)}to{opacity:1;transform:none}}

#splash-nodos .load{
  width:150px;height:4px;border-radius:3px;background:rgba(255,255,255,.09);overflow:hidden;
  opacity:0;animation:splashSube .5s 1s forwards;
}
/* Sección 3, opción A+D — aviso "Preparando tu taller.../Configurando...":
   vive junto a .load (ya existe, ya se lee como "algo está cargando"),
   se desvanece solo, nunca queda pegado a "LISTO PARA TRABAJAR" durante
   el hold. Insertado por JS SOLO en la ceremonia animada (nunca en el
   splash técnico recurrente, nunca en reduced-motion). Margin negativo
   para acercarlo visualmente a .load pese al gap:30px compartido de
   .splash-inner — sin eso quedaría tan separado del resto como cada
   bloque grande (mark/word/load), en vez de leerse pegado a la barra. */
.splash-prep{
  opacity:0;margin-top:-14px;margin-bottom:-14px;
  font-size:11px;font-weight:600;letter-spacing:.14em;text-transform:uppercase;
  color:rgba(255,255,255,.5);text-align:center;
}
/* QA real (Leo): la v1 (1 sola frase, 1.3s de animación) se apagaba casi
   de inmediato dentro de un hold de ~8s — se sentía como un parpadeo y el
   resto se veía "vacío, solo la barra". Ahora la animación dura CASI todo
   el hold (8.7s, termina 200ms antes de que onDone lo apague a los 9.5s
   en plan-splash.js) — el aviso se queda visible casi todo el tiempo, en
   vez de aparecer y apagarse enseguida. El "parpadeo" a mitad (50.6% ≈
   5000ms, el mismo instante en que plan-splash.js cambia el texto a
   "Configurando...") es un guiño visual de "algo cambió", no una segunda
   entrada/salida completa. */
#splash-nodos.splash-nodos--ceremonia .splash-prep{
  animation:splashPrepEntraSale 8.7s .6s ease-out forwards;
}
@keyframes splashPrepEntraSale{
  0%{opacity:0;transform:translateY(6px)}
  5%{opacity:1;transform:none}
  49%{opacity:1}
  50.6%{opacity:.12}
  52%{opacity:1}
  97%{opacity:1}
  100%{opacity:0}
}
#splash-nodos .load i{
  display:block;height:100%;width:42%;border-radius:3px;
  background:linear-gradient(90deg,var(--login-accent),var(--login-accent-soft));
  animation:splashCarga 1.4s 1.1s ease-in-out infinite;
}
@keyframes splashCarga{0%{transform:translateX(-110%)}100%{transform:translateX(380%)}}

@media (prefers-reduced-motion: reduce){
  #splash-nodos .glow, #splash-nodos .mark, #splash-nodos .load i{animation:none}
  #splash-nodos .word, #splash-nodos .tag, #splash-nodos .tag-en, #splash-nodos .load{
    animation:none;opacity:1;transform:none;
  }
}

/* ── PlanSplash — ceremonia de activación de plan (Fase UX-1A.3, escalada
   en el cierre de QA real) ────────────────────────────────────────────
   Se agrega ENCIMA del splash de siempre (misma A, mismo wordmark, mismo
   fondo) — nunca es un segundo splash aparte. Solo el nivel Gratis está
   implementado hoy (ver js/modules/plan-splash.js); estas reglas son
   genéricas a `.splash-placa`/`.splash-perfil` para que un futuro nivel
   Pro/Industrial las reutilice sin CSS muerto adicional (más intensidad =
   mismo mecanismo, otro tono/duración).

   DIRECCIÓN DE ARTE — "placa troquelada, a escala real": el concepto (navy +
   aluminio + naranja, golpe seco sin rebote) quedó aprobado por QA, pero el
   mismo QA encontró que todavía se leía como "una etiqueta bajo el loader":
     1. la placa era demasiado pequeña para leerse a distancia normal;
     2. el destello (.splash-corte) era un flash de ~320ms atrapado en la
        esquina de la placa — si el usuario parpadeaba, se lo perdía casi
        entero;
     3. la ceremonia entera (~500ms de movimiento, ~1.6s de hold) se sentía
        contenida para una activación que ocurre UNA SOLA VEZ.
   Esta versión no cambia el concepto, lo escala:
     - el destello pasó de un brillo local a un recorrido de energía en
        diagonal, cruza el logo y termina de cruzar justo cuando estampa la
        placa — hay origen, recorrido y destino, no solo el destino (ver
        más abajo, `.splash-perfil`, la implementación por capas definitiva:
        el brillo vive en el canto de 4 perfiles de aluminio, no en una
        viga/rayo independiente cruzando el vacío);
     - la placa creció de badge (14px/11.5px) a letrero real, con jerarquía
        invertida: "TRABAJA" es ahora el titular dominante (clamp 32-46px),
        "PLAN GRATIS" el kicker que lo enmarca;
     - se agregó un remate secundario con las 3 capacidades reales de
        Gratis (mismo copy ya auditado como factual en onboarding.js), que
        aparecen durante el hold final, sin competir con el titular.
   Sigue siendo un solo golpe por elemento — nunca rebote/elástico, nunca
   partículas/glitch/confeti: personalidad mecánica, precisa, industrial.

   ITERACIÓN "más grande" (histórico, REVERTIDO más abajo): una ronda
   pidió escalar también el logo/wordmark/lema con transform:scale() (no
   solo la placa). Quedó como lección aprendida, no como código activo:
   una primera pasada de esa misma ronda usó tamaños reales (width/height
   del logo, font-size del wordmark) y el navegador reveló un layout shift
   real de -19px (#splash-nodos centra .splash-inner con
   align-items/justify-content:center, así que agrandar la CAJA de sus
   hijos re-centra todo el bloque) — cambiar a transform:scale() lo
   arregló porque no toca la caja de layout. Ese mecanismo se mantuvo
   varias rondas hasta que QA real contra el splash diario mostró que el
   crecimiento SÍ generaba otro problema (ver el bloque de abajo,
   "REVERTIDO"): con más escala, la caja de layout (sin cambiar) ya no
   alcanzaba a separar visualmente el wordmark de la línea de abajo. */
/* REVERTIDO a pedido explícito (QA real): una ronda anterior pidió
   agrandar logo/wordmark/lema con transform:scale() dentro de la
   ceremonia. Como scale() crece visualmente sin mover la caja de layout
   que ya existía entre estos elementos (pensada para su tamaño normal),
   el resultado en desktop terminó con "Aluminero" prácticamente tocando
   la línea de abajo ("TRABAJA CON PRECISIÓN...") — se veía amontonado.
   Se revierte por completo: logo/wordmark/lema de la ceremonia usan
   exactamente el mismo tamaño y las mismas animaciones (splashSube) que
   el splash técnico recurrente de siempre — sin regla propia aquí, caen
   al comportamiento base. Placa/perfiles/capacidades NO se tocan (se
   negociaron y aprobaron aparte, no tienen equivalente en el splash
   diario). */

/* position:absolute a propósito (QA visual: insertar la placa como hijo
   flex normal empujaba/recentraba el logo y el wordmark ~48px hacia arriba
   en el instante mismo de insertarla — layout shift real, antes de que la
   placa siquiera empezara su propia animación). Al sacarla del flujo, el
   resto de #splash-nodos nunca se mueve: la placa simplemente aparece bajo
   el contenido ya existente, sin desplazar nada. `top:100%` es relativo a
   .splash-inner (ver abajo, position:relative), así que sigue funcionando
   sin importar la altura real del bloque de arriba — se reverificó que
   sigue sin desplazar nada con el tamaño nuevo, mucho mayor (ver QA visual). */
/* z-index:1 (QA real, sección "cola larga" del perfil derecho en mobile,
   ver @media max-width:600px más abajo): esa cola ahora se extiende por
   DEBAJO del logo/wordmark/lema a propósito — sin esto, .splash-perfil
   (hermano posterior en el DOM, mismo nivel de stacking) pintaría ENCIMA
   de .splash-inner en cualquier zona donde se crucen. */
#splash-nodos .splash-inner{position:relative;z-index:1}

/* ── CAPA 2+3 — Perfiles de aluminio (asset XL real) + brillo en su canto
   ─────────────────────────────────────────────────────────────────────
   Asset XL real provisto por Leo (icons/splash-perfil-xl.png, PNG con
   transparencia real verificada a nivel de píxel — 70% transparente, 0%
   opaco de fondo). Reemplaza a los dos assets cortos anteriores
   (splash-perfil-izquierdo/derecho.png): mismo asset reutilizado para
   ambos lados, SIN reflejar — corrección explícita tras QA: reflejar el
   derecho (scaleX(-1)) producía un "techo/V" simétrico sobre el logo, que
   se rechazó junto con la X de la ronda anterior. Ambos perfiles
   conservan la MISMA diagonal ↗ del asset (por eso tampoco hay
   transform:rotate() — el ángulo ya viene dibujado en el PNG); se
   diferencian solo por top/left/right, quedando cada uno como acento
   lateral independiente (esquina superior-izquierda / superior-derecha),
   sin converger ni tocarse.
   Tamaño corregido tras QA real: "perfil XL" se refiere a que el ASSET
   tiene longitud suficiente para recortarse, no a que deba mostrarse
   gigante — la ronda anterior (120vw) ocupaba ~20-30% del ancho visible y
   competía con el logo. El grosor perpendicular real del canto en el PNG
   fuente es ~16% del ancho de la propia imagen (medido a pixel); con
   width:62vw el grosor visible en pantalla resulta ~10vw, dentro del
   8-12% pedido — gran parte del largo del asset queda fuera del viewport
   a propósito, solo se ve el tramo necesario para enmarcar. */
.splash-perfil{position:absolute;pointer-events:none;z-index:0}
.splash-perfil img{display:block;width:100%;height:auto}
.splash-perfil--izq{top:15%;left:-40%;width:62vw;max-width:820px}
.splash-perfil--der{top:15%;right:-40%;width:62vw;max-width:820px}
/* Alargados sobre su propio eje diagonal (QA real: con el tamaño de
   arriba se veían como "pedazos flotantes" — un extremo terminaba dentro
   del viewport en vez de perderse fuera de cuadro). Estirar el ancho/alto
   del box (o un scale() uniforme) habría engrosado el canto también, que
   es justo lo que NO se pidió — por eso el estiramiento es SOLO a lo largo
   de la diagonal real del PNG (33.69°, exacta por la proporción 1536:1024
   del asset): rotar hasta alinear esa diagonal con el eje X, escalar solo
   en X, rotar de regreso. El grosor perpendicular queda intacto. El
   transform-origin ancla el extremo que YA estaba fuera del viewport (para
   que no se mueva) y estira el otro extremo (el que se veía flotando)
   hasta perderse fuera de cuadro también. */
.splash-perfil--izq{transform-origin:0% 100%;transform:rotate(-33.69deg) scaleX(1.8) rotate(33.69deg)}
.splash-perfil--der{transform-origin:100% 0%;transform:rotate(-33.69deg) scaleX(1.8) rotate(33.69deg)}
/* Corrección SOLO mobile (QA real a 375×812 y 320×700): los valores de
   arriba están calibrados contra la relación de aspecto ancha de desktop
   (1280×800) — en un viewport angosto y alto, `top` (relativo a la ALTURA
   completa del viewport) y el alargamiento de abajo hacían que el perfil
   derecho cruzara literalmente encima del logo. Desktop no se toca: este
   bloque solo reduce el ancho base y el factor de alargamiento para que
   el mismo look "largo, diagonal, saliendo de cuadro" quede confinado a
   la franja superior, sin invadir logo/wordmark/lema/placa/capacidades.
   El derecho se había ocultado por completo en una ronda anterior porque
   seguía tapando texto/logo — QA real de seguimiento probó reactivarlo
   con `top` más alto (3% en vez de 8%, sube ambos perfiles) y bien más
   angosto (42vw en vez de 58vw, SOLO el derecho): así vuelve a mostrar
   los dos, verificado sin tocar logo/wordmark/lema/placa/capacidades en
   320×700, 375×812, 505×743, 600×700 y 600×850 (el rango real de anchos
   de esta franja, no solo un tamaño). El izquierdo puede quedarse más
   ancho porque su lateral (arranca en left:-30%) tiene más margen antes
   de llegar al centro que el derecho con este mismo alto. */
@media (max-width:600px){
  /* Historial (ver commits db66e97, 49b39bc, 9ed363e): izq/der pasaron por
     un par simétrico corto, luego por una cola derecha larga+difuminada
     ("ambiental", opacity/blur reducidos) confinada detrás del contenido.
     QA real de seguimiento (Leo, celular): esa cola difuminada, sumada al
     fundido de brillo que se coló aquí desde PC (ver @media min-width:601px
     arriba — ya corregido), hacía que las barras se sintieran "opacas,
     perdidas". Pidió lo contrario: AMBAS brillantes (como el look
     original, sin blur/opacity reducidos) y AMBAS largas "de extremo a
     extremo". A este alcance (scaleX igual en ambas) las dos diagonales
     se cruzan detrás del logo — decisión CONSCIENTE y confirmada por Leo
     viendo la captura real ("me gusta el cruce, déjalo así"), que
     reemplaza la regla histórica "nunca cruzarse en X" documentada más
     arriba — esa regla nació de rechazar un asset REFLEJADO (scaleX(-1),
     un techo/V simétrico), no de rechazar dos diagonales SIN reflejar que
     coinciden por alcance; el logo (z-index:1 sobre .splash-inner) tapa
     el punto de cruce, así que nunca se lee como una forma nueva rara. */
  .splash-perfil--izq,.splash-perfil--der{max-width:none;width:42vw;transform:rotate(-33.69deg) scaleX(4) rotate(33.69deg)}
  /* QA real de seguimiento (Leo, celular, captura con zoom): a scaleX(3.2)
     se veía la PUNTA del asset (su extremo tallado en el propio PNG) como
     un corte limpio flotando en el aire, cerca del logo — "esa barra
     parece recortada". No es un recorte del contenedor: es la punta REAL
     del bar, que a esta escala ya no alcanzaba a esconderse detrás del
     logo ni a salir de cuadro. Confirmado en el navegador que scaleX(3.2)
     deja la punta visible y scaleX(4)+ la esconde de nuevo (pasa detrás
     del logo) — se sube a 4 para dar margen. Si una ronda futura alarga
     esto más, revisar de nuevo que la punta siga oculta, no asumir que
     "más grande siempre es más seguro". */
  /* top:7% en el izquierdo (vs. 3% en el derecho) es a propósito — pedido
     explícito de Leo en una ronda aparte ("baja la primera barra de la
     izquierda un poco"), no relacionado con el resto de este bloque. */
  .splash-perfil--izq{top:7%;left:-30%}
  .splash-perfil--der{top:3%;right:-30%;transform-origin:100% 0%}
}
/* El brillo recorre el canto REAL del perfil: `.splash-perfil-glow` usa la
   MISMA imagen como mask-image, así que cualquier cosa que se mueva dentro
   de él solo se ve donde el propio PNG tiene píxeles (el metal/canto) —
   nunca un rectángulo, nunca se sale de la silueta real. Dentro, el
   recorrido en sí (::after) reutiliza la técnica ya probada de la ronda
   CSS anterior (barrido horizontal simple, left:-45%→100%) — un
   degradado animado con background-position resultó invisible en QA real
   (frames congelados a 50/150/200ms mostraban naranja-sobre-naranja, sin
   diferencia perceptible); un barrido blanco-caliente en movimiento franco
   sí se nota como un destello puntual recorriendo el canto. */
.splash-perfil-glow{
  position:absolute;inset:0;overflow:hidden;
  -webkit-mask-image:var(--perfil-mask);-webkit-mask-size:100% 100%;-webkit-mask-repeat:no-repeat;
  mask-image:var(--perfil-mask);mask-size:100% 100%;mask-repeat:no-repeat;
}
.splash-perfil-glow::after{
  content:"";position:absolute;top:0;left:-45%;width:45%;height:100%;
  background:linear-gradient(100deg,transparent,rgba(255,255,255,.98),transparent);
  opacity:0;
}
.splash-perfil--izq .splash-perfil-glow,
.splash-perfil--der .splash-perfil-glow{--perfil-mask:url(../icons/splash-perfil-xl.png)}
#splash-nodos.splash-nodos--ceremonia .splash-perfil--izq .splash-perfil-glow::after{animation:splashPerfilBrillo .4s ease-out .05s forwards}
#splash-nodos.splash-nodos--ceremonia .splash-perfil--der .splash-perfil-glow::after{animation:splashPerfilBrillo .4s ease-out .28s forwards}
@keyframes splashPerfilBrillo{
  0%{left:-45%;opacity:0}
  15%{opacity:1}
  85%{opacity:1}
  100%{left:100%;opacity:0}
}
/* Reduced-motion: los perfiles se crean siempre (nunca ausentes — ver JS),
   sin brillo animado — solo el asset estático (que ya trae su propio
   resplandor naranja permanente dibujado en el PNG). */
/* QA real (Leo, captura de PC): el resplandor naranja del PNG (arriba) es
   permanente por diseño, pero se queda igual de intenso toda la ceremonia
   — pidió que se apague con el tiempo, para que la composición se sienta
   más tranquila hacia el final. Se atenúa (brightness+saturate) el propio
   <img>, no el brillo suelto — es lo único que puede afectar el naranja
   horneado en los píxeles. Se queda en su punto más brillante durante la
   parte "activa" del hold (coincide con "Preparando tu taller...") y
   empieza a apagarse después, terminando justo antes de que la ceremonia
   se cierre — mismo patrón de temporización que .splash-prep. Solo en la
   ceremonia animada — reduced-motion no anima nada, se queda con el brillo
   fijo de siempre.
   QA real de seguimiento (Leo, celular): este fundido se había dejado sin
   escopar a ancho — en mobile, para cuando aparecía "Configurando...",
   las barras ya se veían apagadas/perdidas ("opaco"), algo que Leo NUNCA
   pidió ahí (solo lo pidió viendo PC). Se limita a min-width:601px —
   mobile se queda con el brillo fijo de siempre, igual que reduced-motion. */
@media (min-width:601px){
  #splash-nodos.splash-nodos--ceremonia .splash-perfil img{
    animation:splashPerfilApagado 8.7s .6s ease-in forwards;
  }
}
@keyframes splashPerfilApagado{
  0%{filter:none}
  55%{filter:none}
  100%{filter:brightness(.4) saturate(.3)}
}

/* Impacto del logo sincronizado con el paso del brillo por el tramo
   central de la secuencia de perfiles (izquierdo → derecho, ver arriba,
   ahora termina a .28+.4=.68s) — una sola pasada extra sobre su latido
   normal en bucle, no se acumula con él. */
#splash-nodos.splash-nodos--ceremonia .mark{animation:splashLatido 2.6s ease-in-out infinite,splashImpacto .22s .2s ease-out 1}
@keyframes splashImpacto{0%{transform:scale(1)}50%{transform:scale(1.16)}100%{transform:scale(1)}}

/* Placa — asset real (icons/splash-placa-vacia.png, PNG con transparencia
   real provisto por Leo). YA NO se dibuja en CSS (nada de clip-path,
   gradientes de metal, remaches ni borde animado — todo eso ya viene en
   el PNG); el HTML solo posiciona la imagen y superpone el texto real
   (PLAN GRATIS / LISTO PARA TRABAJAR nunca van rasterizados). */
.splash-placa{
  /* QA real contra TARGET: width:max-content (y luego width:100%) eran
     ambos un bug — el contenedor real (.splash-inner) mide ~399px (lo que
     ocupa el splash técnico de siempre), así que un % de su ancho colapsaba
     la placa a ~400px sin importar max-width. `vw` ignora al padre y mide
     contra el VIEWPORT real, por eso resuelve al tamaño real pedido ("no
     quiero que vuelva a quedar pequeña"). */
  position:absolute;left:50%;top:100%;margin-top:12px;z-index:2;
  width:min(94vw,660px);
  display:flex;flex-direction:column;align-items:center;gap:8px;
  opacity:0;transform:translateX(-50%) scale(.9);
  animation:splashPlacaGolpe .3s .68s cubic-bezier(.16,1,.3,1) forwards;
}
.splash-placa-plate{
  position:relative;width:100%;aspect-ratio:1291/347;
  display:flex;flex-direction:column;align-items:center;justify-content:center;
  padding:0 15%;
}
.splash-placa-img{
  position:absolute;inset:0;width:100%;height:100%;z-index:0;pointer-events:none;
  /* Activación: el metal no llega "ya encendido" — el resplandor del
     propio PNG se intensifica justo cuando termina la secuencia de
     perfiles (.68s) y se asienta a su brillo permanente. */
  filter:brightness(1) drop-shadow(0 0 0 rgba(248,116,6,0));
  animation:splashPlacaActiva .4s .68s ease-out forwards;
}
@keyframes splashPlacaActiva{
  0%{filter:brightness(1) drop-shadow(0 0 0 rgba(248,116,6,0))}
  40%{filter:brightness(1.35) drop-shadow(0 0 20px rgba(248,116,6,.7))}
  100%{filter:brightness(1.08) drop-shadow(0 0 10px rgba(248,116,6,.4))}
}
/* Kicker — "PLAN GRATIS" sigue enmarcando al titular (misma jerarquía
   confirmada en rondas anteriores incluso comparando contra esta misma
   referencia), pero ya NO diminuto (pedido explícito): sube de un tope de
   19px a 24px — presencia real, sin volverse el elemento dominante. */
.splash-placa-plan{
  position:relative;z-index:1;
  font-size:clamp(17px,3vw,24px);font-weight:800;letter-spacing:.16em;text-transform:uppercase;
  color:#2a1c10;text-shadow:0 1px 0 rgba(255,255,255,.3);
}
/* Titular — copy definitivo "LISTO PARA TRABAJAR" (antes "TRABAJA"; ver
   plan-splash.js para el porqué y el NBSP entre LISTO/PARA). Color oscuro
   (antes blanco): sobre el metal real de la placa, un texto oscuro es el
   que de verdad se lee — el blanco quedaba lavado contra el brillo del
   PNG. */
.splash-placa-accion{
  position:relative;z-index:1;
  font-size:clamp(20px,4.6vw,34px);font-weight:800;letter-spacing:.005em;
  text-transform:uppercase;color:#241811;line-height:1.05;margin:4px 0 0;
  text-shadow:0 1px 0 rgba(255,255,255,.25);
}
@keyframes splashPlacaGolpe{0%{opacity:0;transform:translateX(-50%) scale(.9)}100%{opacity:1;transform:translateX(-50%) scale(1)}}
/* Brillo cruzando el metal recién estampado — un solo paso, arranca justo
   cuando la placa termina de asentarse (.68s+.3s=.98s). transform nada más. */
.splash-placa-plate::before{
  content:"";position:absolute;inset:0;pointer-events:none;z-index:1;
  background:linear-gradient(115deg,transparent 30%,rgba(255,255,255,.42) 48%,transparent 66%);
  transform:translate3d(-130%,0,0);
  animation:splashPlacaBrillo .4s .98s cubic-bezier(.4,0,.2,1) forwards;
}
@keyframes splashPlacaBrillo{0%{transform:translate3d(-130%,0,0)}100%{transform:translate3d(130%,0,0)}}

/* Capacidades reales de Gratis — remate secundario en 3 columnas (ícono +
   etiqueta de hasta 2 líneas), NUNCA cards/botones (sección 10) — flotan
   limpiamente sobre el fondo, nunca compiten con el titular (fuente/peso
   mucho menores, separadas por un filete superior). Aparecen escalonadas
   ~1.05-1.6s, justo después de que la placa ya se asentó (.98s) — la
   sensación es "la energía llegó → la placa se formó → las herramientas
   se encienden una a una", no todo de golpe. */
.splash-placa-caps{
  display:flex;justify-content:center;gap:30px;
  padding-top:10px;border-top:1px solid rgba(255,255,255,.14);
}
.splash-placa-cap{
  display:flex;flex-direction:column;align-items:center;gap:5px;max-width:96px;
  opacity:0;transform:translateY(6px);animation:splashCapAparece .3s ease-out forwards;
}
.splash-placa-cap svg{width:23px;height:23px;color:var(--login-accent-soft)}
.splash-placa-cap span{
  font-size:11px;font-weight:700;letter-spacing:.05em;text-transform:uppercase;
  color:rgba(255,255,255,.62);line-height:1.3;
}
.splash-placa-cap:nth-child(1){animation-delay:1.05s}
.splash-placa-cap:nth-child(2){animation-delay:1.2s}
.splash-placa-cap:nth-child(3){animation-delay:1.35s}
@keyframes splashCapAparece{to{opacity:1;transform:translateY(0)}}

/* ── Barra de progreso ceremonial — Gratis (microajuste, Leo) ───────────
   MISMO PRINCIPIO que la barra de la Celebración PRO V2 (.splash-flujo-
   progreso), pero clase/selector COMPLETAMENTE distintos a propósito —
   cero posibilidad de que un cambio aquí toque esa barra o viceversa. El
   scope de abajo (:not(.splash-nodos--identidad-pro)) excluye
   explícitamente cualquier composición PRO (celebración o splash diario),
   que sí usan esa clase — esta barra es EXCLUSIVA de renderPlaca()
   (Gratis). Mismo lenguaje visual que ya tenía .load en este lugar (línea
   delgada, mismo footprint) para no alterar el layout que ya existía. */
#splash-nodos.splash-nodos--ceremonia:not(.splash-nodos--identidad-pro) .load,
#splash-nodos.splash-nodos--ceremonia-reducida:not(.splash-nodos--identidad-pro) .load{display:none}
.splash-placa-progreso{
  display:flex;align-items:center;gap:8px;
}
.splash-placa-progreso-pista{
  width:150px;height:4px;border-radius:3px;background:rgba(255,255,255,.09);overflow:hidden;
}
.splash-placa-progreso-fill{
  width:0%;height:100%;border-radius:3px;
  background:linear-gradient(90deg,var(--login-accent),var(--login-accent-soft));
  /* Ventana total aquí es ~0.68s (vs ~14s en PRO) — transición más corta
     para que nunca "persiga" al tick (ver PROGRESO_TICK_MS=20ms en
     plan-splash.js), misma lógica que la barra de PRO. */
  transition:width .05s linear;
}
.splash-placa-progreso-pct{
  font-size:10px;font-weight:700;letter-spacing:.04em;
  color:rgba(255,255,255,.55);
  /* Ancho mínimo fijo — igual que en PRO — para que "9%→10%" y "99%→100%"
     nunca desplacen el layout. */
  min-width:2.6em;text-align:left;font-variant-numeric:tabular-nums;
}
@media (prefers-reduced-motion: reduce){
  .splash-placa-progreso-fill{transition:none}
}

/* Móvil (375px de referencia, sección 12): la placa ya escala sola vía
   aspect-ratio/max-width, esto solo ajusta márgenes y las capacidades para
   que no se sientan apretadas contra el borde. */
@media (max-width:600px){
  .splash-placa{margin-top:10px;gap:8px}
  .splash-placa-caps{gap:12px;padding-top:10px}
  .splash-placa-cap{max-width:76px}
  .splash-placa-cap svg{width:18px;height:18px}
  .splash-placa-cap span{font-size:9.5px}
}
/* Pantallas móviles muy bajas (320×700, sección 12): el ahorro de arriba
   (~600px) no basta — la placa completa (con las 3 capacidades) terminaba
   ~10px por debajo del viewport en la verificación real a 320×700. Se
   recorta un poco más el padding/márgenes verticales de la placa SOLO en
   esta franja de altura, sin tocar el tamaño de fuente/iconos. */
@media (max-height:700px){
  .splash-placa{margin-top:6px;gap:6px}
  .splash-placa-caps{padding-top:8px}
  /* PROTOTIPO aviso "Preparando tu taller...": en 600x700 (el borde bajo
     ya cubierto arriba) el elemento nuevo empujaba la placa ~3px fuera del
     viewport (antes de agregarlo, ese caso ya pasaba justo). Apretar SOLO
     el margen de .splash-prep no alcanza sin arriesgar que se pegue a
     "Tecnología de NodoSOE" (verificado: con -26px llegan a solaparse
     visualmente) — se reparte el ajuste entre el gap general de
     .splash-inner y un margen más moderado, verificado en navegador real
     con 10px de aire arriba (vs. tag-sub) y ~7px de aire abajo (vs. el
     borde del viewport). */
  #splash-nodos .splash-inner{gap:22px}
  .splash-prep{margin-top:-12px;margin-bottom:-12px}
}
/* QA real (captura de escritorio a pantalla completa, con barra de tareas):
   una ventana ANCHA pero BAJA (alto real de navegador ~650-700px una vez
   descontados barra de tareas/chrome del navegador) dejaba las 3
   capacidades fuera de cuadro — el bloque de arriba solo recorta lo
   suficiente para la placa ya pequeña de mobile, nunca fue pensado para el
   tamaño de escritorio (mucho más alto). `min-width` lo separa de mobile
   (que ya tiene su propio ajuste) para no duplicar/pisar esos valores. */
@media (max-height:750px) and (min-width:601px){
  #splash-nodos .splash-inner{gap:4px}
  #splash-nodos .tag{margin-top:2px}
  #splash-nodos .tag-sub{margin-top:1px}
  /* QA real de Leo (captura en un navegador maximizado normal, ~1439x719
     tras descontar barra de marcadores/toolbar/taskbar): con gap:4px de
     arriba, el margen negativo BASE de .splash-prep (-14px, pensado para
     el gap:30px normal) dejaba un espacio de 4-14=-10px — el aviso quedaba
     literalmente encimado con "Tecnología de NodoSOE". Aquí sobra alto de
     sobra (la placa nunca se acerca a desbordar en esta franja), así que
     en vez de apretar más se afloja: margen POSITIVO, no negativo — deja
     ~10px de aire arriba y abajo, verificado en navegador real. */
  .splash-prep{margin-top:6px;margin-bottom:6px}
  /* Ya se exprimió casi todo el margen/gap disponible sin tocar el tamaño
     de la placa que se aprobó — faltaba un pequeño remanente, así que el
     ancho de la placa (y con eso su alto, ligado por aspect-ratio) se
     reduce un poco SOLO en esta franja rara (ancho de escritorio + alto
     corto). Sigue siendo la misma placa, solo ~9% más chica únicamente
     aquí — nunca en el tamaño de escritorio normal ya aprobado. */
  .splash-placa{margin-top:0;gap:0;width:min(94vw,600px)}
  .splash-placa-caps{padding-top:2px}
}

/* prefers-reduced-motion: PlanSplash.show() usa esta clase en vez de
   --ceremonia — sin brillo animado en los perfiles, sin impacto: la placa
   (ya a su tamaño definitivo, con su resplandor final) y las 3 capacidades
   aparecen COMPLETAS de una vez, igual que el resto del splash arriba. */
/* transform mantiene translateX(-50%) — sigue absoluta y centrada, solo sin
   la escala/entrada animada (perder el translateX la desalinearía a la
   izquierda). El brillo del PNG toma su estado FINAL asentado (100% del
   keyframe de activación), no el estado inicial apagado. */
#splash-nodos.splash-nodos--ceremonia-reducida .splash-placa{
  animation:none;opacity:1;transform:translateX(-50%);
}
#splash-nodos.splash-nodos--ceremonia-reducida .splash-placa-img{
  animation:none;filter:brightness(1.08) drop-shadow(0 0 10px rgba(248,116,6,.4));
}
#splash-nodos.splash-nodos--ceremonia-reducida .splash-placa-plate::before{animation:none;display:none}
#splash-nodos.splash-nodos--ceremonia-reducida .splash-placa-cap{animation:none;opacity:1;transform:none}

@media (prefers-reduced-motion: reduce){
  /* Bajo reduced-motion, PlanSplash.show() nunca agrega .splash-nodos--
     ceremonia (usa --ceremonia-reducida en su lugar) — este bloque es un
     cinturón de seguridad adicional por si esa clase llegara a coexistir. */
  #splash-nodos.splash-nodos--ceremonia .splash-perfil-glow{display:none}
  #splash-nodos.splash-nodos--ceremonia .mark{animation:none}
  .splash-placa{animation:none;opacity:1;transform:translateX(-50%)}
  .splash-placa-img{animation:none;filter:brightness(1.08) drop-shadow(0 0 10px rgba(248,116,6,.4))}
  .splash-placa-plate::before{animation:none;display:none}
  .splash-placa-cap{animation:none;opacity:1;transform:none}
  .splash-flujo{animation:none;opacity:1;transform:translateX(-50%)}
  .splash-flujo-estacion{animation:none;opacity:1}
  .splash-identidad-v2{animation:none;opacity:1;transform:none}
  .splash-identidad-v2-brillo{display:none}
}

/* ══════════ ALUMINERO PRO V2 — kit de assets metálicos (Leo) ══════════
   Reemplaza el prototipo "estructura ensamblada" (panel+riel+tornillos+
   postes, todo CSS) por la estructura pedida: tarjeta metálica REAL
   (icons/splash-flujo-tarjeta.webp) → conector naranja → tarjeta → ... →
   placa oscura REAL (icons/splash-flujo-placa.webp) con "PLAN PRO / TU
   TALLER, ORGANIZADO" en HTML encima (nunca horneado en el PNG). La
   MISMA tarjeta se reutiliza 4 veces (Clientes/Cotizaciones/Agenda/
   Proyectos) — icono/título/descripción siguen siendo HTML/CSS reales
   sobre ella, nunca 4 imágenes distintas. Sin panel/riel/gantry/tornillos:
   "los 4 cuadros metálicos son los protagonistas" (Leo). Reutiliza el
   mismo hueco bajo el logo que .splash-placa (position:absolute, top:100%
   de .splash-inner). Sin .splash-perfil (firma exclusiva de Gratis). */
.splash-flujo{
  position:absolute;left:50%;top:100%;margin-top:8px;z-index:2;
  width:min(94vw,900px);
  display:flex;flex-direction:column;align-items:center;gap:12px;
  opacity:0;transform:translateX(-50%) scale(.96);
  animation:splashFlujoEntra .4s .2s cubic-bezier(.16,1,.3,1) forwards;
}
@keyframes splashFlujoEntra{to{opacity:1;transform:translateX(-50%) scale(1)}}

/* Ajuste de jerarquía (Leo): este slot es EXCLUSIVO del storytelling
   transitorio (inicio + 4 estaciones, ver escribirTexto en plan-splash.js)
   — "PLAN PRO ACTIVADO" ya no se repite aquí, así que al terminar la
   secuencia se apaga con un fade suave (opacity, ver JS) en vez de
   quedarse congelado con el último status. */
.splash-flujo-eyebrow{
  font-size:10.5px;font-weight:700;letter-spacing:.1em;text-transform:uppercase;
  color:rgba(255,255,255,.5);text-align:center;
  transition:opacity .3s ease;
}
/* Typewriter sin recentrado (Leo, última afinación, sección 5): el bug era
   que .splash-flujo-status-texto crecía letra por letra DENTRO de un
   contenedor centrado — cada letra nueva cambiaba el ancho del propio
   texto, y como está centrado, el BLOQUE ENTERO se recorría en X en cada
   letra. Arreglo con la técnica de "ghost" de medida: .splash-flujo-
   status-medida es invisible (visibility:hidden, nunca display:none —
   así sigue ocupando espacio) y JS le pone el texto FINAL de la fase
   ANTES de empezar a escribir (ver plan-splash.js) — eso fija el ancho de
   .splash-flujo-status-wrap (inline-block) desde el primer instante,
   igual que si la frase ya estuviera completa. .splash-flujo-status-texto
   se dibuja ENCIMA (position:absolute, mismo ancho/alto), así que puede
   crecer letra por letra SIN afectar el tamaño del wrap que lo contiene
   — el bloque centrado nunca se mueve mientras se escribe. Funciona con
   cualquier frase (nunca depende de un texto específico ni de espacios
   manuales). */
.splash-flujo-status-wrap{position:relative;display:inline-block;vertical-align:top}
.splash-flujo-status-medida{visibility:hidden;white-space:nowrap;display:inline-block}
.splash-flujo-status-texto{
  position:absolute;left:0;top:0;width:100%;
  text-align:left;white-space:nowrap;overflow:hidden;
}
/* Puntos animados (Leo, "alargar la construcción" sección 3): ancho FIJO
   (nunca el texto natural de "..."/".."/".") para que crecer/encoger los
   puntos nunca desplace ni recentre la frase de al lado — inline-block
   angosto, alineado a la izquierda dentro de su propia caja. */
.splash-flujo-status-puntos{
  display:inline-block;width:1.2em;text-align:left;vertical-align:top;
}

/* ── Barra de progreso ceremonial (microajuste, Leo) ────────────────────
   Reemplaza a .load SOLO durante la Celebración PRO V2 (ver el scope de
   abajo, .splash-nodos--ceremonia.splash-nodos--identidad-pro — nunca
   Gratis, nunca el Splash Diario PRO, que usa --identidad-pro-diaria, una
   clase DISTINTA): .load es una barra INDETERMINADA que se recorre en
   bucle cada 1.4s (splashCarga) — estirada sobre una ceremonia de ~14s se
   ve "demasiado rápida/llamativa" (QA real, Leo). Esta es una barra
   DETERMINADA (JS empuja %, ver plan-splash.js) que representa el avance
   de TODA la ceremonia, nunca de una operación real. Misma línea visual
   que .load (150px×4px) para no alterar el layout que ya existía en ese
   lugar. */
#splash-nodos.splash-nodos--identidad-pro.splash-nodos--ceremonia .load,
#splash-nodos.splash-nodos--identidad-pro.splash-nodos--ceremonia-reducida .load{display:none}
.splash-flujo-progreso{
  display:flex;align-items:center;gap:8px;
}
.splash-flujo-progreso-pista{
  width:150px;height:4px;border-radius:3px;background:rgba(255,255,255,.09);overflow:hidden;
}
.splash-flujo-progreso-fill{
  width:0%;height:100%;border-radius:3px;
  background:linear-gradient(90deg,var(--login-accent),var(--login-accent-soft));
  /* .15s: suficiente para que cada tick de 100ms (JS) se vea como avance
     continuo, nunca un salto — nunca más largo que el propio tick, o el
     relleno se quedaría "persiguiendo" al número. */
  transition:width .15s linear;
}
.splash-flujo-progreso-pct{
  font-size:10px;font-weight:700;letter-spacing:.04em;
  color:rgba(255,255,255,.55);
  /* Ancho mínimo fijo (3 dígitos + "%") para que el bloque completo nunca
     cambie de tamaño total al pasar de "9%" a "100%" — mismo principio que
     .splash-flujo-status-puntos de arriba. */
  min-width:2.6em;text-align:left;font-variant-numeric:tabular-nums;
}
@media (prefers-reduced-motion: reduce){
  .splash-flujo-progreso-fill{transition:none}
}

/* Fila — --tarjeta-w en un solo lugar (mismo patrón que --icono-size en
   la versión anterior): cada tarjeta y el layout entero derivan de esta
   variable, así nunca se desalinean entre sí al achicarla en los tiers
   de mobile/altura corta de abajo. Base = desktop (fila horizontal);
   @media max-width:600px la vuelve columna vertical. */
.splash-flujo-fila{
  --tarjeta-w:150px;
  display:flex;flex-direction:row;align-items:center;justify-content:center;
  gap:8px;width:100%;
}

/* Tarjeta — el asset (461×433, transparencia real) SOLO aporta el
   material/fondo; encima, icono/título/descripción son HTML/CSS reales
   (nitidez, responsive, accesibilidad y copy editable, ver Leo). Ancho
   fijo por --tarjeta-w + aspect-ratio EXACTO del asset (461/433): nunca
   se estira ni se deforma, cero salto de layout aunque el <img> tarde en
   cargar. */
/* Motor de animación por CLASES, no por animation-delay fijo (Leo, última
   afinación: "construye el timeline a partir de mediciones reales del
   typewriter" — con delays fijos en CSS, cambiar la duración de una frase
   en JS desincroniza todo). plan-splash.js encadena el timeline en tiempo
   real y agrega .activa/.activo/.pulso/.respira exactamente cuando cada
   hito ocurre — la animación arranca en cero desde ahí, siempre en fase
   con el status/texto real, sin importar cuánto tardó lo anterior. */
.splash-flujo-tarjeta{
  position:relative;flex:0 0 auto;width:var(--tarjeta-w);aspect-ratio:461/433;
  opacity:0;transform:translateY(-6px) scale(.94);
}
.splash-flujo-tarjeta.activa{
  animation:
    splashFlujoTarjetaAsienta .3s ease-out forwards,
    splashFlujoTarjetaImpacto .5s ease-out forwards;
}
/* Selector COMPUESTO a propósito (.activa.pulso, no solo .pulso): la
   propiedad `animation` no se "suma" entre 2 reglas que matchean el mismo
   elemento — la última en el CSS gana y REEMPLAZA la lista completa. Con
   una regla `.pulso` separada, al agregar esa clase se perdía la animación
   de asienta/impacto (que sostenía opacity:1/transform:none vía forwards)
   y la tarjeta "saltaba" de vuelta a su estado inicial (opacity:0) un
   instante antes de aplicar el pulso — bug real encontrado en QA visual.
   Repetir las 3 animaciones juntas aquí es inofensivo: asienta/impacto ya
   están en su 100% (mismo resultado visual), solo se re-declaran para que
   seguir sosteniendo ese estado no dependa de una regla distinta. */
.splash-flujo-tarjeta.activa.pulso{
  animation:
    splashFlujoTarjetaAsienta .3s ease-out forwards,
    splashFlujoTarjetaImpacto .5s ease-out forwards,
    splashFlujoTarjetaPulso .4s ease-out forwards;
}
/* "Asienta" con un golpe seco (overshoot muy breve al 70%, nunca rebote
   elástico) — la sensación de CLAC/LOCK que pidió Leo, toda en CSS. */
@keyframes splashFlujoTarjetaAsienta{
  0%{opacity:0;transform:translateY(-6px) scale(.94)}
  70%{opacity:1;transform:translateY(1px) scale(1.02)}
  100%{opacity:1;transform:translateY(0) scale(1)}
}
/* Jerarquía de brillo (Leo, storyboard "fase final"): la tarjeta que se
   ACTIVA es la protagonista de ese instante — brillo/reflejo breve al
   asentar (mismo animation-delay que splashFlujoTarjetaAsienta, JS usa el
   mismo número en ms, ver escribirTexto/setTimeout en plan-splash.js) —
   y después queda encendida SUAVEMENTE, nunca al máximo de forma
   permanente. drop-shadow (no box-shadow) porque .splash-flujo-tarjeta-img
   es la que tiene la silueta real con esquinas redondeadas del asset. */
@keyframes splashFlujoTarjetaImpacto{
  0%{filter:brightness(1) drop-shadow(0 0 0 rgba(248,116,6,0))}
  30%{filter:brightness(1.45) drop-shadow(0 0 12px rgba(248,116,6,.85))}
  100%{filter:brightness(1.04) drop-shadow(0 0 3px rgba(248,116,6,.3))}
}
/* Pulso final "muy contenido" (Leo) — una sola vez, cuando las 4 ya están
   conectadas (Proyectos termina su impacto en ~5.3s, "sistema completo" a
   los 6s) — nunca vuelve a poner las 4 tarjetas al brillo máximo de la
   activación, solo un realce breve por encima del reposo que dejó
   splashFlujoTarjetaImpacto. */
@keyframes splashFlujoTarjetaPulso{
  0%{filter:brightness(1.04) drop-shadow(0 0 3px rgba(248,116,6,.3))}
  45%{filter:brightness(1.15) drop-shadow(0 0 7px rgba(248,116,6,.5))}
  100%{filter:brightness(1.04) drop-shadow(0 0 3px rgba(248,116,6,.3))}
}
.splash-flujo-tarjeta-img{
  position:absolute;inset:0;width:100%;height:100%;object-fit:contain;
  z-index:0;pointer-events:none;
}
.splash-flujo-tarjeta-contenido{
  position:relative;z-index:1;width:100%;height:100%;box-sizing:border-box;
  display:flex;flex-direction:column;align-items:center;justify-content:center;gap:3px;
  padding:9% 8%;text-align:center;
}
.splash-flujo-icono{display:flex;color:var(--login-accent);filter:drop-shadow(0 1px 1px rgba(0,0,0,.35))}
.splash-flujo-icono svg{width:20px;height:20px}
.splash-flujo-nombre{
  font-size:9.5px;font-weight:800;letter-spacing:.02em;text-transform:uppercase;
  color:#1c2128;
}
.splash-flujo-sub{
  font-size:7.5px;font-weight:600;color:rgba(28,33,40,.62);line-height:1.2;
}

/* Microchispas (Leo, última afinación sección 7: "quiero que se puedan
   VER... no convertirlo en soldadura exagerada"): representan el instante
   de contacto, no un efecto continuo — 4 puntos fijos en las esquinas
   (mismo lugar que los remaches reales del asset), cada uno vuela una
   distancia corta (--dx/--dy). Duración subida a .65s (antes .5s, dentro
   del rango .55-.75s pedido). Disparadas por la clase .activa de la
   TARJETA (no animation-delay fijo — ver plan-splash.js, el timeline ahora
   se encadena en tiempo real) con un offset relativo pequeño (.15s, "el
   pequeño impacto antes de la chispa") + un ligero escalonado por chispa
   ("partículas con diferente duración para evitar que parezca un flash
   único", pedido explícito) — nunca simultáneas al 100%. Nunca se crean en
   reduced-motion (ver renderFlujo) ni en HTML si reducido=true — esto es
   un refuerzo, no la única barrera. */
.splash-flujo-chispa{
  position:absolute;width:3px;height:3px;border-radius:50%;pointer-events:none;
  background:radial-gradient(circle,#fff,var(--login-accent) 55%,transparent 100%);
  opacity:0;
}
.splash-flujo-tarjeta.activa .splash-flujo-chispa{
  animation:splashFlujoChispa .65s ease-out forwards;
  animation-delay:.15s;
}
/* nth-last-child (no nth-child): las 4 chispas son siempre los ÚLTIMOS 4
   hijos de .splash-flujo-tarjeta, pero NO los primeros — antes van el
   <img> y el <div> de contenido. Contar desde el final es inmune a eso
   (QA real: con nth-child(1..4) dos chispas quedaban sin top/left/right/
   bottom — coincidían por accidente con el <img> y el contenido, que no
   tienen la clase, así que la regla no les aplicaba nada). El pequeño
   +Nms extra en cada una es el escalonado ("diferente duración") pedido. */
.splash-flujo-chispa:nth-last-child(4){top:9%;left:9%;--dx:-9px;--dy:-9px}
.splash-flujo-chispa:nth-last-child(3){top:9%;right:9%;--dx:9px;--dy:-9px}
.splash-flujo-chispa:nth-last-child(2){bottom:9%;left:9%;--dx:-9px;--dy:9px}
.splash-flujo-chispa:nth-last-child(1){bottom:9%;right:9%;--dx:9px;--dy:9px}
.splash-flujo-tarjeta.activa .splash-flujo-chispa:nth-last-child(4){animation-delay:.15s}
.splash-flujo-tarjeta.activa .splash-flujo-chispa:nth-last-child(3){animation-delay:.19s}
.splash-flujo-tarjeta.activa .splash-flujo-chispa:nth-last-child(2){animation-delay:.22s}
.splash-flujo-tarjeta.activa .splash-flujo-chispa:nth-last-child(1){animation-delay:.17s}
@keyframes splashFlujoChispa{
  0%{opacity:0;transform:translate(0,0) scale(.5)}
  30%{opacity:1;transform:translate(0,0) scale(1)}
  100%{opacity:0;transform:translate(var(--dx),var(--dy)) scale(.3)}
}

/* Conector — línea de energía naranja entre tarjetas, nada más (Leo: "NO
   estructura grande, portal, ring ni maquinaria pesada"). Misma técnica
   de 2 capas ya probada (track oscuro + relleno que avanza vía
   transform), ahora recorriendo cada tramo PROGRESIVAMENTE (--i por
   tramo) en vez de una sola barra continua. */
.splash-flujo-conector{position:relative;flex:0 0 auto;width:36px;height:5px;border-radius:3px;overflow:hidden}
.splash-flujo-conector::before{
  content:"";position:absolute;inset:0;
  background:linear-gradient(90deg,#14171b,#0c0e11);
  box-shadow:inset 0 1px 2px rgba(0,0,0,.6);
}
.splash-flujo-conector-luz{
  position:absolute;inset:0;transform-origin:left center;transform:scaleX(0);
  background:linear-gradient(90deg,rgba(248,116,6,.15),var(--login-accent) 85%,#ffd9ad 100%);
  box-shadow:0 0 8px rgba(248,116,6,.7);
}
/* "Quiero VER cómo la energía viaja" (Leo, última afinación sección 8):
   .65s (antes .35s, dentro del rango .6-.9s pedido) — MISMO número que
   CONECTOR_DURACION en plan-splash.js, así que "el conector termina de
   recorrer" y "la siguiente tarjeta empieza a asentar" son el mismo
   instante exacto, no una coincidencia aproximada. Disparado por la clase
   .activo (JS, timeline encadenado) en vez de animation-delay fijo. */
.splash-flujo-conector.activo .splash-flujo-conector-luz{
  animation:splashFlujoConectorEnergiza .65s ease-out forwards;
}
@keyframes splashFlujoConectorEnergiza{to{transform:scaleX(1)}}

/* Placa inferior — asset real (1210×281, transparencia real), aspect-
   ratio EXACTO para que nunca se deforme al escalar. Texto (PLAN PRO/TU
   TALLER, ORGANIZADO) siempre HTML encima, nunca horneado en el PNG. */
.splash-flujo-placa{
  position:relative;width:100%;max-width:420px;aspect-ratio:1210/281;
  opacity:0;transform:translateY(6px);
}
/* Disparada por JS (clase .activa) en el instante exacto del timeline
   encadenado — ya no un delay fijo, ver plan-splash.js/mostrarPlaca(). */
.splash-flujo-placa.activa{
  animation:splashFlujoPlacaAparece .55s ease-out forwards;
}
/* Último realce (Leo, sección 2 "PLACA FINAL"): mismo criterio de
   flash-y-reposo que las tarjetas (splashFlujoTarjetaImpacto) — un pico de
   brillo/naranja contenido justo cuando aparece, luego se asienta a un
   estado premium estable, nunca queda "quemada" al máximo. */
@keyframes splashFlujoPlacaAparece{
  0%{opacity:0;transform:translateY(6px);filter:brightness(1) drop-shadow(0 0 0 rgba(248,116,6,0))}
  55%{opacity:1;transform:none;filter:brightness(1.22) drop-shadow(0 0 16px rgba(248,116,6,.55))}
  100%{opacity:1;transform:none;filter:brightness(1.03) drop-shadow(0 0 4px rgba(248,116,6,.3))}
}
.splash-flujo-placa-img{
  position:absolute;inset:0;width:100%;height:100%;object-fit:contain;
  z-index:0;pointer-events:none;
}
.splash-flujo-placa-texto{
  position:absolute;inset:0;z-index:1;
  display:flex;flex-direction:column;align-items:center;justify-content:center;
  text-align:center;padding:0 13%;box-sizing:border-box;
}
/* Leo, sección 7-8: "PLAN PRO ACTIVADO" ya no es un kicker discreto, es el
   remate del status (ver escribirTexto en plan-splash.js) — debe leerse
   claro de inmediato, nunca gris apagado sobre el fondo oscuro de la
   placa. Color naranja claro (no blanco puro) para diferenciarlo de "TU
   TALLER, ORGANIZADO" (blanco, abajo), que sigue siendo el mensaje
   principal. */
.splash-flujo-plan{
  font-size:clamp(10px,2vw,13px);font-weight:800;letter-spacing:.13em;text-transform:uppercase;
  color:var(--login-accent-soft);text-shadow:0 0 10px rgba(248,116,6,.45);
  min-height:1.1em;
}
/* Pulso final MUY suave (Leo): "debe respirar lentamente", nunca flash ni
   láser — solo el halo del propio texto oscila entre 10px/.45 (el mismo
   valor estático de arriba, para que no haya salto al empezar) y 16px/.62.
   Clase .respira (JS) en vez de delay fijo — arranca en el instante exacto
   en que termina de escribirse "PLAN PRO ACTIVADO", sin importar cuánto
   tardó el resto del timeline en llegar ahí. */
.splash-flujo-plan.respira{
  animation:splashFlujoPlanRespira 2.1s ease-in-out infinite;
}
@keyframes splashFlujoPlanRespira{
  0%,100%{text-shadow:0 0 10px rgba(248,116,6,.45)}
  50%{text-shadow:0 0 16px rgba(248,116,6,.62)}
}
.splash-flujo-accion{
  font-size:clamp(13px,3.4vw,20px);font-weight:800;letter-spacing:.005em;text-transform:uppercase;
  color:#fff;line-height:1.05;margin-top:2px;
  text-shadow:0 1px 2px rgba(0,0,0,.5),0 0 8px rgba(255,255,255,.3);
}

@media (max-width:600px){
  /* Mismo criterio ya aprobado antes (Leo, sección 7): en mobile la fila
     se vuelve columna vertical — nunca 4 tarjetas horizontales diminutas
     en teléfono. */
  .splash-flujo-fila{--tarjeta-w:112px;flex-direction:column;gap:7px}
  .splash-flujo-conector{width:5px;height:18px}
  .splash-flujo-conector-luz{transform-origin:top center;transform:scaleY(0)}
  @keyframes splashFlujoConectorEnergiza{to{transform:scaleY(1)}}
  .splash-flujo-icono svg{width:16px;height:16px}
  .splash-flujo-nombre{font-size:8.5px}
  .splash-flujo-sub{font-size:7px}
  .splash-flujo-eyebrow{font-size:9px}
  .splash-flujo{gap:7px;margin-top:6px}
  .splash-flujo-placa{max-width:280px}
}
/* Responsive por ALTURA, no solo por ancho (Leo, sección 8): SIEMPRE en
   este orden — primero espacios/gaps, recién al final tamaños — nunca un
   transform:scale() global sobre toda la ceremonia. 3 tiers probados
   contra teléfono bajo/medio/alto reales, no solo un tamaño. La fila de
   tarjetas es mucho más baja que el riel/panel anterior, así que estos
   tiers tienen bastante más margen que antes. */
@media (max-width:600px) and (max-height:850px){
  /* Umbral a 850 (no 800) a propósito: QA real encontró overflow de ~72px
     en 390×844 ("medio") con el tamaño base de mobile — 4 tarjetas reales
     (icono+título+descripción) apiladas son más altas que el riel/panel
     anterior, así que el tier intermedio ahora también cubre esa altura. */
  #splash-nodos.splash-nodos--identidad-pro .splash-inner{gap:8px}
  .splash-flujo{gap:5px;margin-top:4px}
  .splash-flujo-fila{--tarjeta-w:100px;gap:5px}
  .splash-flujo-conector{height:14px}
  .splash-flujo-eyebrow{font-size:8.5px}
  .splash-flujo-sub{display:none}
}
@media (max-width:600px) and (max-height:700px){
  .splash-flujo-fila{--tarjeta-w:84px;gap:4px}
  .splash-flujo-conector{height:10px}
  /* Antes display:none — pero el status dinámico (Leo, storytelling) ya no
     es decorativo, es la mitad de la narrativa ("ORGANIZANDO TUS
     CLIENTES…" etc). Se achica en vez de esconderse, verificado que sigue
     cabiendo sin overflow incluso en el tier más bajo (375×667). */
  .splash-flujo-eyebrow{font-size:7px;min-height:9px}
  .splash-flujo-nombre{font-size:7.5px}
}

#splash-nodos.splash-nodos--ceremonia-reducida .splash-flujo{animation:none;opacity:1;transform:translateX(-50%)}
#splash-nodos.splash-nodos--ceremonia-reducida .splash-flujo-tarjeta{animation:none;opacity:1;transform:none;filter:none}
#splash-nodos.splash-nodos--ceremonia-reducida .splash-flujo-conector-luz{animation:none;transform:scaleX(1)}
#splash-nodos.splash-nodos--ceremonia-reducida .splash-flujo-placa{animation:none;opacity:1;transform:none;filter:none}
#splash-nodos.splash-nodos--ceremonia-reducida .splash-flujo-plan{animation:none}
#splash-nodos.splash-nodos--ceremonia-reducida .splash-flujo-chispa{display:none}
#splash-nodos.splash-nodos--ceremonia-reducida .splash-identidad-v2{animation:none;opacity:1;transform:none}
#splash-nodos.splash-nodos--ceremonia-reducida .splash-identidad-v2-brillo{display:none}
@media (max-width:600px){
  #splash-nodos.splash-nodos--ceremonia-reducida .splash-flujo-conector-luz{transform:scaleY(1)}
}

/* ══════════ Identidad V2 — SOLO ceremonia PRO ══════════
   Leo: "PRO debe sentirse claramente como una evolución de nivel". Esta
   ronda reemplaza el tratamiento 100% CSS (A simulada + gradiente en
   .word + insignia "— PRO —" generada, ver historial en git) por el
   ASSET REAL entregado por Leo (icons/splash-identidad-pro-v2.webp: A
   metálica + wordmark Aluminero + PRO, ya combinados en un solo gráfico,
   transparencia real verificada a nivel de píxel). .mark/.word
   (compartidos con Gratis/splash técnico) se OCULTAN aquí, nunca se
   borran del DOM — .tag/.tag-sub (el eslogan del día) se quedan
   exactamente igual, debajo del asset. Todo escopado a
   #splash-nodos.splash-nodos--identidad-pro, que SOLO renderFlujo()
   agrega — nunca coexiste con el splash técnico recurrente ni con la
   ceremonia Gratis. La lógica de "usar V2 en el splash diario cuando la
   organización YA es PRO" queda deliberadamente pendiente (Leo, fase de
   identidad por plan) — aquí solo se prueba vía el botón QA.

   NOTA PARA CUANDO SE IMPLEMENTE (Leo, QA en teléfono real — NO implementar
   todavía): el tamaño de esta identidad en la CELEBRACIÓN (ver tiers de
   mobile más abajo, y clamp(188px,22vw,272px) en desktop) es chico a
   propósito — es una necesidad exclusiva de esta ceremonia larga, donde
   compite por espacio vertical con 4 tarjetas + placa. El futuro SPLASH
   DIARIO/login de PRO (cuando exista, fuera de esta celebración) NO debe
   heredar este tamaño reducido: ahí la identidad debe tener un
   protagonismo MUCHO MAYOR, aproximadamente equivalente al tamaño visual
   que hoy tiene la identidad de Gratis en su splash diario (#splash-nodos
   .mark/.word, ver arriba en este archivo — sin ceremonia debajo, esa
   identidad es la única protagonista de la pantalla). */
/* QA visual real (teléfono real, Leo): "demasiado espacio vacío
   superior". Causa: #splash-nodos centra VERTICALMENTE .splash-inner
   (align-items:center) — pero .splash-inner solo mide el bloque de
   identidad, NUNCA el panel de PRO (position:absolute, ver .splash-flujo),
   así que el centrado real deja tanto espacio arriba como abajo de ese
   bloque chico, sin saber que la composición completa (identidad + panel)
   es mucho más alta y termina apretada abajo. Se ancla arriba
   (align-items:flex-start) SOLO para la ceremonia PRO, con un padding-top
   que se recorta en los mismos tiers de altura de abajo — nunca toca el
   centrado de Gratis ni del splash técnico recurrente. */
#splash-nodos.splash-nodos--identidad-pro{align-items:flex-start;padding-top:9vh}
#splash-nodos.splash-nodos--identidad-pro .mark,
#splash-nodos.splash-nodos--identidad-pro .word{display:none}

/* aspect-ratio EXACTO del asset (1536×1024 = 3:2) — así el contenedor
   nunca depende de que la imagen ya haya cargado para reservar su alto
   real (cero salto de layout) y .splash-identidad-v2-brillo (el barrido,
   ver abajo) siempre queda perfectamente alineado con la silueta real,
   sin importar a qué ancho se muestre en cada tier de abajo. width:100%
   + height:auto en la <img> preserva el aspect-ratio real del archivo —
   NUNCA se estira en un solo eje. */
.splash-identidad-v2{
  position:relative;width:clamp(188px,22vw,272px);aspect-ratio:916/614;
  opacity:0;transform:translateY(-6px);
  animation:splashIdentidadV2Entra .5s .15s cubic-bezier(.16,1,.3,1) forwards;
}
@keyframes splashIdentidadV2Entra{to{opacity:1;transform:none}}
.splash-identidad-v2 img{display:block;width:100%;height:100%;object-fit:contain}
/* Barrido — "breve recorrido/reflejo naranja o metálico, después queda
   completamente estable" (pedido explícito de Leo, nunca un giro/zoom/
   rebote). Mismo mecanismo YA probado en este archivo para .splash-perfil
   -glow: un div hermano recortado a la silueta REAL del asset vía
   mask-image (nunca un rectángulo), con un solo barrido de luz adentro —
   se apaga solo y no vuelve a jugar. */
.splash-identidad-v2-brillo{
  position:absolute;inset:0;overflow:hidden;pointer-events:none;
  -webkit-mask-image:url(../icons/splash-identidad-pro-v2.webp);-webkit-mask-size:contain;-webkit-mask-repeat:no-repeat;-webkit-mask-position:center;
  mask-image:url(../icons/splash-identidad-pro-v2.webp);mask-size:contain;mask-repeat:no-repeat;mask-position:center;
}
.splash-identidad-v2-brillo::after{
  content:"";position:absolute;top:0;left:-55%;width:45%;height:100%;
  background:linear-gradient(100deg,transparent,rgba(255,255,255,.9),transparent);
  opacity:0;
  animation:splashIdentidadV2Brillo .55s .45s ease-out forwards;
}
@keyframes splashIdentidadV2Brillo{
  0%{left:-55%;opacity:0}
  15%{opacity:1}
  85%{opacity:1}
  100%{left:115%;opacity:0}
}
#splash-nodos.splash-nodos--identidad-pro .tag{color:rgba(255,255,255,.62);margin-top:10px}
#splash-nodos.splash-nodos--identidad-pro .tag-sub{color:var(--login-accent-soft);opacity:.85}

@media (max-width:600px){
  /* Leo: "en mobile debe ser considerablemente más compacto... sin volver
     a provocar el problema anterior de altura" — primero se recortan
     gaps/separación (ver .splash-inner/.splash-identidad-v2 abajo), el
     tamaño del asset baja MODERADAMENTE, nunca un transform:scale()
     global sobre toda la ceremonia. */
  /* 11.5vh (antes 13vh) — QA real (time-machine) encontró overflow real de
     ~5px en 428×926 con 13vh + el logo/tagline agrandados de esta ronda;
     11.5vh lo corrige con margen de sobra (~9px) y de paso le da más aire
     a 390×844 (~23px), sin tocar tarjetas ni placa. */
  #splash-nodos.splash-nodos--identidad-pro{padding-top:11.5vh}
  #splash-nodos.splash-nodos--identidad-pro .splash-inner{gap:8px}
  /* Leo (última afinación, QA en teléfono real): +22% MÁS sobre el tamaño
     ya aprobado en la ronda anterior — financiado recortando padding-top/
     gaps (ver arriba y tiers de abajo), NUNCA achicando tarjetas ni placa.
     Explícitamente NO aplica al futuro splash diario PRO (ver nota junto a
     --identidad-pro más abajo: ese debe ser bastante más grande todavía,
     a la escala de Gratis). */
  .splash-identidad-v2{width:clamp(159px,42.7vw,215px)}
  /* Tagline compacto (Leo, sección 10): "TRABAJA CON PRECISIÓN. DECIDE CON
     CLARIDAD." de lado a lado le robaba protagonismo al logo. max-width
     fuerza el wrap natural del navegador justo en el espacio entre las 2
     oraciones (nunca un <br> a mano ni tocar el texto de index.html,
     compartido con Gratis) — 2 líneas equilibradas, nunca 1 sola línea
     microscópica. Escopado a #splash-nodos--identidad-pro: el splash
     diario de Gratis (.tag sin este selector) sigue en una sola línea,
     sin cambios. */
  /* max-width medido en navegador (no un valor redondo cualquiera): a
     9.5px, "TRABAJA CON PRECISIÓN." mide ~166px y agregar " DE" ya
     necesita ~187px — 175px cae justo en medio, así que el wrap SIEMPRE
     cae después del punto, nunca a mitad de "DECIDE" (QA real: con 280px
     el navegador metía "DECIDE CON" en la primera línea, un corte feo). */
  #splash-nodos.splash-nodos--identidad-pro .tag{
    margin-top:6px;font-size:9.5px;max-width:175px;margin-left:auto;margin-right:auto;line-height:1.5;
  }
  #splash-nodos.splash-nodos--identidad-pro .tag-sub{margin-top:4px;font-size:7.5px}
}
@media (max-width:600px) and (max-height:800px){
  #splash-nodos.splash-nodos--identidad-pro{padding-top:9vh}
  /* +22% (mismo criterio en los 3 tiers de esta sección). */
  .splash-identidad-v2{width:clamp(133px,34.9vw,165px)}
  #splash-nodos.splash-nodos--identidad-pro .tag-sub{display:none}
}
@media (max-width:600px) and (max-height:700px){
  /* Tier más bajo: mismo +22% — el margen real (medido en navegador) es el
     que decide si se sostiene o hay que recortar más gaps/padding-top,
     nunca el logo (Leo: "NO reduzcas nuevamente el logo salvo que exista
     overflow real demostrado"). */
  #splash-nodos.splash-nodos--identidad-pro{padding-top:13vh}
  #splash-nodos.splash-nodos--identidad-pro .splash-inner{gap:4px}
  .splash-identidad-v2{width:clamp(107px,27.4vw,132px)}
  /* Mismo criterio de medición que el tier de arriba: a 8.5px, "TRABAJA
     CON PRECISIÓN." mide ~153px y +"DE" ya pide ~172px — 160px fuerza el
     mismo corte limpio después del punto. */
  #splash-nodos.splash-nodos--identidad-pro .tag{font-size:8.5px;margin-top:4px;max-width:160px}
}

/* ══════════ PRO V2 — escala desktop ══════════
   Puesto al FINAL del archivo a propósito (mismo patrón que el resto de
   overrides de altura de arriba): misma especificidad que las reglas
   base/mobile, así que solo gana por orden de cascada — cero
   !important, cero riesgo de filtrarse a mobile (min-width:601px es
   mutuamente excluyente con las @media max-width:600px de arriba). */
@media (min-width:601px){
  .splash-flujo{gap:16px;margin-top:12px}
  .splash-flujo-fila{--tarjeta-w:176px;gap:10px}
  .splash-flujo-conector{width:42px;height:6px}
  .splash-flujo-icono svg{width:26px;height:26px}
  .splash-flujo-nombre{font-size:12.5px}
  .splash-flujo-sub{font-size:10px}
  .splash-flujo-eyebrow{font-size:13px}
  .splash-flujo-placa{max-width:620px}
  .splash-flujo-plan{font-size:clamp(14px,2vw,17px)}
  .splash-flujo-accion{font-size:clamp(20px,3.6vw,28px)}
  #splash-nodos.splash-nodos--identidad-pro{padding-top:6.5vh}
}

/* ══════════ SISTEMA VISUAL PRO (rediseño visual PRO, 2026-10-06) ══════════
   Lenguaje común de las experiencias PRO: navy muy oscuro + cuadrícula
   técnica casi invisible + naranja Aluminero como ÚNICO acento + blanco para
   lo principal y gris frío para lo secundario. Sin texturas metálicas, sin
   placas, sin partículas. Hoy lo usa el Splash Diario PRO; la Celebración de
   Primera Activación lo reutilizará (Checkpoint B).

   Primitivas (marcado en plan-splash.js: proCuadricula/proMarca/proModos/
   proProgreso):
     .pro-grid · .pro-brand · .pro-modes (+ .pro-bridge) · .pro-progress

   Toda la entrada es opacity/transform (compositor, sin layout/reflow). Los
   tokens viven en el scope .splash-nodos--pro — no se tocan los de :root
   (ni --ink, que el dark mode no redefine a propósito). */
#splash-nodos.splash-nodos--pro{
  --pro-navy:#0A1828;--pro-navy-hi:#0F2338;
  --pro-linea:rgba(132,164,200,.085);          /* cuadrícula: apenas visible */
  --pro-borde:rgba(150,178,210,.30);           /* pills / pistas finas */
  --pro-blanco:#fff;--pro-gris:#A9B8CB;--pro-gris-2:#8496AB;
  --pro-naranja:var(--login-accent);           /* #F87406 */
  --pro-ease:cubic-bezier(.22,.8,.3,1);
  background:radial-gradient(ellipse 80% 70% at 50% 42%,var(--pro-navy-hi) 0%,var(--pro-navy) 62%,#08121F 100%);
  /* Safe areas (notch / barra de gestos) — el bloque nunca queda debajo. */
  padding:env(safe-area-inset-top) env(safe-area-inset-right) env(safe-area-inset-bottom) env(safe-area-inset-left);
  box-sizing:border-box;
}
/* El markup compartido de index.html (A, wordmark, tagline, barra de
   Gratis/técnico) no forma parte de este lenguaje: se oculta, no se edita. */
#splash-nodos.splash-nodos--pro .glow,
#splash-nodos.splash-nodos--pro .splash-inner > :not(.pro-stage){display:none}

/* Cuadrícula: CSS puro, celda grande y regular que escala con el viewport.
   La máscara la desvanece hacia los bordes para que nunca compita con el
   contenido ni se vea "papel cuadriculado" a pantalla completa. */
.pro-grid{
  position:absolute;inset:0;z-index:0;pointer-events:none;
  --pro-celda:clamp(44px,4.6vw,76px);
  background-image:
    linear-gradient(var(--pro-linea) 1px,transparent 1px),
    linear-gradient(90deg,var(--pro-linea) 1px,transparent 1px);
  background-size:var(--pro-celda) var(--pro-celda);
  background-position:center center;
  -webkit-mask-image:radial-gradient(ellipse 75% 70% at 50% 46%,#000 35%,transparent 100%);
  mask-image:radial-gradient(ellipse 75% 70% at 50% 46%,#000 35%,transparent 100%);
  animation:proFundido .7s ease-out both;
}

/* Escena: columna centrada, ancho acotado (nunca desborda en móvil). */
.pro-stage{
  position:relative;display:flex;flex-direction:column;align-items:center;
  width:min(92vw,760px);text-align:center;
  font-family:inherit;
}

/* ── Marca: [A] + Aluminero + PRO ── */
.pro-brand{position:relative;display:flex;flex-direction:column;align-items:center;gap:clamp(14px,2.2vh,22px)}
.pro-brand::before{                             /* brillo naranja contenido, detrás de la A */
  content:"";position:absolute;left:50%;top:0;width:clamp(180px,24vw,360px);aspect-ratio:1;
  transform:translate(-50%,-22%);border-radius:50%;pointer-events:none;
  background:radial-gradient(circle,rgba(248,116,6,.20),transparent 68%);
  animation:proFundido .8s ease-out .1s both;
}
.pro-brand-a{
  position:relative;display:block;
  width:clamp(84px,9vw,152px);height:auto;aspect-ratio:1;
  border-radius:clamp(20px,2.4vw,36px);
  box-shadow:0 10px 34px -10px rgba(248,116,6,.45);
  animation:proSube .5s var(--pro-ease) .15s both;
}
.pro-brand-line{display:flex;align-items:center;justify-content:center;gap:clamp(10px,1.1vw,16px);animation:proSube .5s var(--pro-ease) .42s both}
.pro-brand-word{
  color:var(--pro-blanco);font-weight:800;letter-spacing:-.01em;line-height:1;
  font-size:clamp(34px,3.9vw,64px);
}
.pro-brand-word span{color:var(--pro-naranja)}
.pro-brand-badge{
  color:var(--pro-naranja);font-weight:800;letter-spacing:.07em;line-height:1;
  font-size:clamp(13px,1.5vw,24px);
  padding:.34em .62em;border:2px solid var(--pro-naranja);border-radius:.5em;
}

/* ── Modo Taller ─── Modo Admin ── */
.pro-modes{display:flex;align-items:center;justify-content:center;margin-top:clamp(22px,3.4vh,34px);animation:proSube .5s var(--pro-ease) .72s both}
.pro-mode{
  color:var(--pro-blanco);font-weight:700;text-transform:uppercase;white-space:nowrap;
  font-size:clamp(10.5px,1vw,15px);letter-spacing:.17em;
  padding:.9em 1.7em;border:1px solid var(--pro-borde);border-radius:999px;
  background:rgba(255,255,255,.015);
}
.pro-bridge{                                    /* la línea se "dibuja" de centro a bordes */
  display:block;width:clamp(26px,5.2vw,84px);height:2px;border-radius:2px;
  background:var(--pro-naranja);transform-origin:center;
  animation:proTrazo .45s var(--pro-ease) .9s both;
}

/* ── Lema ── */
.pro-tagline{
  margin:clamp(18px,3vh,28px) 0 0;max-width:30ch;
  color:var(--pro-gris);font-weight:500;line-height:1.35;
  font-size:clamp(14.5px,1.65vw,25px);letter-spacing:.045em;
  animation:proSube .5s var(--pro-ease) 1.08s both;
}

/* ── Progreso ── */
.pro-progress{display:flex;flex-direction:column;align-items:center;margin-top:clamp(26px,4.2vh,40px)}
.pro-progress-track{
  position:relative;width:clamp(210px,22vw,360px);height:6px;border-radius:6px;overflow:hidden;
  background:rgba(255,255,255,.11);
  animation:proFundido .35s ease-out 1.28s both;
}
.pro-progress-fill{
  position:absolute;inset:0;border-radius:6px;background:var(--pro-naranja);
  transform-origin:left center;
  animation:proLlenar 1.5s cubic-bezier(.45,.05,.25,1) 1.32s both;   /* termina a los 2.82s */
}
.pro-progress-label{
  margin:clamp(12px,1.8vh,16px) 0 0;color:var(--pro-gris-2);font-weight:500;
  font-size:clamp(11.5px,1vw,15px);letter-spacing:.08em;
  animation:proFundido .45s ease-out 1.38s both;
}

@keyframes proFundido{from{opacity:0}to{opacity:1}}
@keyframes proSube{from{opacity:0;transform:translateY(10px)}to{opacity:1;transform:none}}
@keyframes proTrazo{from{opacity:0;transform:scaleX(0)}to{opacity:1;transform:scaleX(1)}}
@keyframes proLlenar{from{transform:scaleX(0)}to{transform:scaleX(1)}}

/* ── Móvil: se recompone en vertical, no solo se reduce ── */
@media (max-width:600px){
  .pro-grid{--pro-celda:44px}
  .pro-brand-a{width:clamp(78px,23vw,96px)}
  .pro-brand-word{font-size:clamp(32px,9.4vw,40px)}
  .pro-brand-badge{font-size:13px}
  .pro-modes{margin-top:24px}
  .pro-mode{font-size:10.5px;letter-spacing:.14em;padding:.85em 1.15em}
  .pro-bridge{width:clamp(18px,7vw,32px)}
  .pro-tagline{max-width:19em;font-size:15px;margin-top:20px}
  .pro-progress{margin-top:30px}
  .pro-progress-track{width:min(64vw,240px)}
}
/* Pantallas bajas (móvil horizontal / teléfonos chicos): recortar aire
   vertical antes que el tamaño de la marca. */
@media (max-height:620px){
  .pro-brand-a{width:clamp(60px,14vh,84px)}
  .pro-modes{margin-top:14px}
  .pro-tagline{margin-top:12px}
  .pro-progress{margin-top:16px}
}

/* ── Reduced motion ──
   JS agrega .splash-nodos--ceremonia-reducida; el @media repite lo esencial
   por si la clase no llegara. Todo queda en su estado FINAL (barra al 100%,
   línea trazada, sin desplazamientos) y solo se conserva un fundido corto
   de la escena. */
#splash-nodos.splash-nodos--ceremonia-reducida .pro-grid,
#splash-nodos.splash-nodos--ceremonia-reducida .pro-brand::before,
#splash-nodos.splash-nodos--ceremonia-reducida .pro-brand-a,
#splash-nodos.splash-nodos--ceremonia-reducida .pro-brand-line,
#splash-nodos.splash-nodos--ceremonia-reducida .pro-modes,
#splash-nodos.splash-nodos--ceremonia-reducida .pro-bridge,
#splash-nodos.splash-nodos--ceremonia-reducida .pro-tagline,
#splash-nodos.splash-nodos--ceremonia-reducida .pro-progress-track,
#splash-nodos.splash-nodos--ceremonia-reducida .pro-progress-label{animation:none;opacity:1;transform:none}
#splash-nodos.splash-nodos--ceremonia-reducida .pro-progress-fill{animation:none;transform:scaleX(1)}
#splash-nodos.splash-nodos--ceremonia-reducida .pro-stage{animation:proFundido .2s ease-out both}
@media (prefers-reduced-motion:reduce){
  .pro-grid,.pro-brand::before,.pro-brand-a,.pro-brand-line,.pro-modes,.pro-bridge,
  .pro-tagline,.pro-progress-track,.pro-progress-label{animation:none;opacity:1;transform:none}
  .pro-progress-fill{animation:none;transform:scaleX(1)}
}

/* ══════════ CELEBRACIÓN PRO (rediseño visual PRO, Checkpoint B, 2026-10-07) ══════════
   Mismo sistema pro-* del Splash Diario — NO se modifica ninguna regla de
   arriba; todo lo nuevo vive bajo .pro-stage--celebracion / .pro-hero o con
   clases nuevas. Una sola escena continua:
     marca → modos → progreso (1.2–3.6s) → check + confeti (3.7–5.5s) →
     bienvenida (4.55s) → subtítulo (4.85s) → 4 capacidades (5.2–5.65s) →
     «Comenzar →» (6.2s, visible a los 6.7s).
   La barra y el check comparten .pro-hero (altura fija) y el resto del contenido
   ya ocupa su lugar desde el inicio: nada se desplaza al aparecer. Solo
   opacity/transform (y stroke-dashoffset del SVG, que no provoca layout). */
#splash-nodos.splash-nodos--pro-celebracion{overflow-y:auto;align-items:flex-start}
/* margin:auto centra cuando cabe y deja hacer scroll cuando no (pantallas muy bajas). */
#splash-nodos.splash-nodos--pro-celebracion .splash-inner{margin:auto;padding:clamp(14px,3vh,34px) 0}
#splash-nodos.splash-nodos--pro-celebracion .pro-grid{position:fixed}

.pro-stage--celebracion{width:min(92vw,820px)}
.pro-stage--celebracion .pro-brand-a{width:clamp(68px,6.8vw,108px);border-radius:clamp(16px,1.9vw,28px)}
.pro-stage--celebracion .pro-brand-word{font-size:clamp(30px,3.2vw,52px)}
.pro-stage--celebracion .pro-brand-badge{font-size:clamp(12px,1.3vw,20px)}
.pro-stage--celebracion .pro-modes{margin-top:clamp(16px,2.6vh,28px)}

/* Zona de relevo progreso ↔ check (altura fija: cero salto de layout). */
.pro-hero{
  position:relative;width:100%;height:clamp(84px,13vh,116px);
  margin-top:clamp(12px,2.2vh,24px);
  display:flex;align-items:center;justify-content:center;
}
.pro-hero .pro-progress{position:absolute;inset:0;margin:0;justify-content:center;animation:proSalir .38s ease-in 3.65s forwards}
.pro-hero .pro-progress-track{animation:proFundido .35s ease-out 1.2s both}
.pro-hero .pro-progress-fill{animation:proLlenar 2.25s cubic-bezier(.45,.05,.25,1) 1.35s both}   /* 100% a los 3.6s */
.pro-hero .pro-progress-label{animation:proFundido .45s ease-out 1.3s both}

/* Check: anillo + palomita que se dibujan, brillo contenido y confeti discreto. */
.pro-check{
  --check-d:clamp(68px,10.5vh,100px);
  position:absolute;left:50%;top:50%;width:var(--check-d);aspect-ratio:1;
  transform:translate(-50%,-50%);opacity:0;
  animation:proFundido .2s ease-out 3.7s both;
}
.pro-check svg{position:relative;display:block;width:100%;height:100%;overflow:visible}
.pro-check-anillo{
  fill:rgba(248,116,6,.07);stroke:var(--pro-naranja);stroke-width:5;stroke-linecap:round;
  stroke-dasharray:327;stroke-dashoffset:327;
  transform:rotate(-90deg);transform-origin:60px 60px;
  animation:proDibuja .6s cubic-bezier(.4,.1,.2,1) 3.75s forwards;
}
.pro-check-marca{
  fill:none;stroke:#fff;stroke-width:8;stroke-linecap:round;stroke-linejoin:round;
  stroke-dasharray:70;stroke-dashoffset:70;
  animation:proDibuja .32s ease-out 4.2s forwards;
}
.pro-check-brillo{
  position:absolute;left:50%;top:50%;width:230%;aspect-ratio:1;border-radius:50%;pointer-events:none;
  transform:translate(-50%,-50%) scale(.5);opacity:0;
  background:radial-gradient(circle,rgba(248,116,6,.30),transparent 62%);
  animation:proPulso 1.1s ease-out 4.2s both;
}
.pro-confeti{position:absolute;left:50%;top:50%;width:0;height:0;pointer-events:none}
.pro-confeti-pieza{
  --k:1;
  position:absolute;left:0;top:0;display:block;opacity:0;
  animation:proConfeti 1.25s cubic-bezier(.12,.7,.3,1) calc(4.25s + var(--ret)) both;
}
.pro-confeti-pieza.es-rect{width:7px;height:3.5px;border-radius:1px}
.pro-confeti-pieza.es-punto{width:4.5px;height:4.5px;border-radius:50%}
.pro-confeti-pieza.es-naranja{background:var(--pro-naranja)}
.pro-confeti-pieza.es-blanca{background:rgba(255,255,255,.92)}

/* Bienvenida */
.pro-titulo{
  margin:clamp(10px,1.8vh,20px) 0 0;color:var(--pro-blanco);font-weight:800;
  line-height:1.12;letter-spacing:-.01em;font-size:clamp(23px,2.9vw,46px);
  text-wrap:balance;
  animation:proSube .55s var(--pro-ease) 4.55s both;
}
.pro-titulo span{color:var(--pro-naranja)}
.pro-subtitulo{
  margin:clamp(6px,1vh,12px) 0 0;color:var(--pro-gris);font-weight:500;
  line-height:1.35;letter-spacing:.03em;font-size:clamp(14px,1.4vw,21px);
  text-wrap:balance;
  animation:proSube .5s var(--pro-ease) 4.85s both;
}

/* Capacidades: 4 tarjetas informativas, aparecen en secuencia. */
.pro-caps{
  list-style:none;margin:clamp(16px,2.8vh,30px) 0 0;padding:0;width:100%;
  display:grid;grid-template-columns:repeat(4,1fr);gap:clamp(10px,1.1vw,16px);
}
.pro-cap{
  display:flex;flex-direction:column;align-items:center;justify-content:center;
  gap:clamp(8px,1.2vh,12px);min-height:clamp(78px,12.5vh,112px);padding:10px 8px;
  border:1px solid var(--pro-borde);border-radius:16px;background:rgba(255,255,255,.025);
  animation:proSube .5s var(--pro-ease) both;
}
.pro-cap:nth-child(1){animation-delay:5.2s}
.pro-cap:nth-child(2){animation-delay:5.35s}
.pro-cap:nth-child(3){animation-delay:5.5s}
.pro-cap:nth-child(4){animation-delay:5.65s}
.pro-cap-icono{display:flex;color:var(--pro-naranja)}
.pro-cap-icono svg{width:clamp(24px,2.2vw,34px);height:clamp(24px,2.2vw,34px)}
.pro-cap-nombre{color:var(--pro-blanco);font-weight:600;font-size:clamp(12.5px,1.05vw,15.5px);letter-spacing:.01em}

/* Comenzar → : oculto (visibility) hasta su turno, así no recibe clics ni foco antes. */
.pro-cta{
  display:inline-flex;align-items:center;justify-content:center;gap:10px;
  margin-top:clamp(18px,3.2vh,32px);min-width:clamp(220px,24vw,340px);
  height:clamp(48px,6.4vh,58px);padding:0 28px;border:0;border-radius:14px;
  background:var(--pro-naranja);color:#fff;font:inherit;font-weight:700;
  font-size:clamp(16px,1.3vw,19px);letter-spacing:.02em;cursor:pointer;
  box-shadow:0 12px 30px -12px rgba(248,116,6,.65);
  -webkit-tap-highlight-color:transparent;transition:transform .15s ease,filter .15s ease;
  animation:proMostrar .5s var(--pro-ease) 6.2s both;
}
.pro-cta:hover{filter:brightness(1.07)}
.pro-cta:active{transform:scale(.98)}
.pro-cta:focus-visible{outline:3px solid rgba(255,255,255,.9);outline-offset:3px}
/* Salida de emergencia (plan-splash.js): si las animaciones no corrieron y el botón
   sigue oculto pasado su turno, se muestra tal cual — nunca queda inalcanzable. */
.pro-cta.pro-cta--forzado{animation:none;visibility:visible;opacity:1;transform:none}

@keyframes proSalir{to{opacity:0;transform:scale(.94)}}
@keyframes proDibuja{to{stroke-dashoffset:0}}
@keyframes proPulso{
  0%{opacity:0;transform:translate(-50%,-50%) scale(.5)}
  35%{opacity:1}
  100%{opacity:.35;transform:translate(-50%,-50%) scale(1)}
}
@keyframes proConfeti{
  0%{opacity:0;transform:translate(-50%,-50%) scale(.5) rotate(0deg)}
  12%{opacity:1}
  100%{opacity:0;transform:translate(calc(-50% + var(--dx) * var(--k)),calc(-50% + var(--dy) * var(--k) + 26px)) scale(1) rotate(var(--giro))}
}
@keyframes proMostrar{
  from{visibility:hidden;opacity:0;transform:translateY(10px)}
  to{visibility:visible;opacity:1;transform:none}
}

/* ── Móvil: 2×2, escena recompuesta en vertical ── */
@media (max-width:600px){
  .pro-stage--celebracion .pro-brand-a{width:clamp(60px,18vw,76px)}
  .pro-stage--celebracion .pro-brand-word{font-size:clamp(28px,8.4vw,34px)}
  .pro-stage--celebracion .pro-brand-badge{font-size:12px}
  .pro-stage--celebracion .pro-modes{margin-top:16px}
  .pro-hero{height:clamp(70px,11vh,92px)}
  .pro-check{--check-d:clamp(60px,9.5vh,80px)}
  .pro-confeti-pieza{--k:.62}
  .pro-titulo{font-size:clamp(22px,6.4vw,27px)}
  .pro-subtitulo{font-size:14.5px;max-width:19em}
  .pro-caps{grid-template-columns:repeat(2,1fr);gap:10px;width:min(100%,340px)}
  .pro-cap{min-height:74px}
  .pro-cta{width:min(100%,340px);min-width:0}
}
/* Pantallas bajas: recortar aire vertical y tamaño de tarjetas antes que la marca. */
@media (max-height:700px){
  .pro-stage--celebracion .pro-brand-a{width:clamp(52px,10vh,68px)}
  .pro-stage--celebracion .pro-brand-word{font-size:clamp(26px,5vh,32px)}
  .pro-hero{height:64px;margin-top:8px}
  .pro-check{--check-d:58px}
  .pro-titulo{margin-top:6px}
  .pro-caps{margin-top:12px}
  .pro-cap{min-height:62px;gap:6px;padding:8px}
  .pro-cap-icono svg{width:22px;height:22px}
  .pro-cta{margin-top:14px;height:46px}
}

/* ── Reduced motion: estado final estático (check ya dibujado, sin barra ni
   confeti, todo visible) + el fundido corto de la escena que ya define el
   sistema. El botón queda disponible de inmediato. ── */
#splash-nodos.splash-nodos--ceremonia-reducida .pro-progress{display:none}
#splash-nodos.splash-nodos--ceremonia-reducida .pro-check,
#splash-nodos.splash-nodos--ceremonia-reducida .pro-titulo,
#splash-nodos.splash-nodos--ceremonia-reducida .pro-subtitulo,
#splash-nodos.splash-nodos--ceremonia-reducida .pro-cap,
#splash-nodos.splash-nodos--ceremonia-reducida .pro-cta{animation:none;opacity:1;transform:translate(0,0);visibility:visible}
#splash-nodos.splash-nodos--ceremonia-reducida .pro-check{transform:translate(-50%,-50%)}
#splash-nodos.splash-nodos--ceremonia-reducida .pro-check-anillo,
#splash-nodos.splash-nodos--ceremonia-reducida .pro-check-marca{animation:none;stroke-dashoffset:0}
#splash-nodos.splash-nodos--ceremonia-reducida .pro-check-brillo{animation:none;opacity:.35;transform:translate(-50%,-50%) scale(1)}
#splash-nodos.splash-nodos--ceremonia-reducida .pro-confeti{display:none}
@media (prefers-reduced-motion:reduce){
  .pro-progress{display:none}
  .pro-check,.pro-titulo,.pro-subtitulo,.pro-cap,.pro-cta{animation:none;opacity:1;transform:none;visibility:visible}
  .pro-check{transform:translate(-50%,-50%)}
  .pro-check-anillo,.pro-check-marca{animation:none;stroke-dashoffset:0}
  .pro-check-brillo{animation:none;opacity:.35;transform:translate(-50%,-50%) scale(1)}
  .pro-confeti{display:none}
}
