/* ===========================================================
   GP Home Builder — Efectos 2.0
   Namespace propio `ghb-fx-*`. Los 11 efectos históricos siguen
   viviendo en gp-ai-builder con el prefijo `gpai-fx-*` y no se
   tocan desde acá: hay bloques publicados que los usan.
   =========================================================== */

/* ---- Control global de movimiento ----
   "Apagado" quiere decir: nada se mueve solo. NO apaga lo que responde al
   mouse — el foco que sigue al cursor, el vidrio en profundidad, los botones
   magnéticos y la onda al clic siguen andando, porque ahí el movimiento lo
   pidió la persona. (Si el sistema operativo pide reducir movimiento, eso sí
   congela todo: está más abajo y manda sobre esta opción.)

   1) Lo que se anima en bucle por su cuenta. Incluye ::before/::after, que
      es donde viven la aurora, el brillo, el grano y las partículas — antes
      quedaban animándose igual con la opción en "Apagado". */
.ghb-motion-off [class*="ghb-fx-"],
.ghb-motion-off [class*="ghb-fx-"]::before,
.ghb-motion-off [class*="ghb-fx-"]::after,
.ghb-motion-off [class*="gpai-fx-"],
.ghb-motion-off [class*="gpai-fx-"]::before,
.ghb-motion-off [class*="gpai-fx-"]::after {
    animation: none !important;
}

/* 2) Entradas y scroll cinematográfico: el contenido se muestra ya en su
      lugar definitivo, sin transición ni desplazamiento. */
.ghb-motion-off .ghb-fx-clip-reveal,
.ghb-motion-off .ghb-fx-blur-in,
.ghb-motion-off .ghb-fx-scale-in,
.ghb-motion-off .ghb-fx-split-text,
.ghb-motion-off .ghb-fx-split-text .ghb-word,
.ghb-motion-off .ghb-fx-draw-underline,
.ghb-motion-off .ghb-fx-odometer,
.ghb-motion-off .ghb-fx-parallax-layers,
.ghb-motion-off .ghb-fx-parallax-layers > *,
.ghb-motion-off .ghb-fx-zoom-scroll,
.ghb-motion-off .ghb-fx-hero-sticky,
.ghb-motion-off .ghb-fx-sticky-stack,
.ghb-motion-off .gpai-fx-reveal,
.ghb-motion-off .gpai-fx-stagger,
.ghb-motion-off .gpai-fx-stagger > *,
.ghb-motion-off .gpai-fx-parallax,
.ghb-motion-off .gpai-fx-counter {
    opacity: 1 !important;
    transform: none !important;
    transition: none !important;
    filter: none !important;
    clip-path: none !important;
}

.ghb-motion-suave [class*="ghb-fx-"],
.ghb-motion-suave [class*="gpai-fx-"] {
    animation-duration: 1.6s !important;
    transition-duration: .45s !important;
}

/* Preferencia del sistema: manda siempre, sin importar la opción del admin.
   Acá sí se congela todo, incluidas las respuestas al mouse. */
@media (prefers-reduced-motion: reduce) {
    [class*="ghb-fx-"],
    [class*="ghb-fx-"]::before,
    [class*="ghb-fx-"]::after,
    [class*="gpai-fx-"],
    [class*="gpai-fx-"]::before,
    [class*="gpai-fx-"]::after {
        animation: none !important;
        transition: none !important;
        transform: none !important;
        opacity: 1 !important;
        filter: none !important;
        clip-path: none !important;
    }
}

/* ---- Un solo dueño de la aparición por bloque ----
   El tema `empresa` tiene su propio sistema (`.js .reveal { opacity:0 }` +
   reveal.js). Si un bloque ya trae un efecto de entrada nuestro, apagamos el
   del tema adentro: dos sistemas poniendo opacity:0 y uno solo devolviéndola
   es exactamente cómo se termina con una sección en blanco. */
.ghb-fx-clip-reveal .reveal,
.ghb-fx-blur-in .reveal,
.ghb-fx-scale-in .reveal,
.ghb-fx-split-text .reveal,
.ghb-fx-draw-underline .reveal {
    opacity: 1 !important;
    transform: none !important;
    transition: none !important;
}

/* ===========================================================
   ENTRADA AL SCROLLEAR
   El estado inicial sólo se aplica cuando el JS marcó la página
   como "lista" (html.ghb-fx-ready). Si el JS no carga, nada queda
   invisible — es la lección del doble reveal del tema.
   =========================================================== */

.ghb-fx-ready .ghb-fx-clip-reveal { clip-path: inset(100% 0 0 0); transition: clip-path .9s cubic-bezier(.22,1,.36,1); }
.ghb-fx-ready .ghb-fx-clip-reveal[data-ghb-clip-reveal-from="top"] { clip-path: inset(0 0 100% 0); }
.ghb-fx-ready .ghb-fx-clip-reveal[data-ghb-clip-reveal-from="left"] { clip-path: inset(0 100% 0 0); }
.ghb-fx-ready .ghb-fx-clip-reveal[data-ghb-clip-reveal-from="right"] { clip-path: inset(0 0 0 100%); }
.ghb-fx-clip-reveal.ghb-in { clip-path: inset(0 0 0 0); }

.ghb-fx-ready .ghb-fx-blur-in { opacity: 0; filter: blur(14px); transition: opacity .8s ease, filter .8s ease; }
.ghb-fx-blur-in.ghb-in { opacity: 1; filter: blur(0); }

.ghb-fx-ready .ghb-fx-scale-in { opacity: 0; transform: scale(.94); transition: opacity .7s ease, transform .7s cubic-bezier(.22,1,.36,1); }
.ghb-fx-scale-in.ghb-in { opacity: 1; transform: none; }

/* split-text: el JS parte el título en <span class="ghb-word"> */
.ghb-fx-split-text .ghb-word { display: inline-block; opacity: 0; transform: translateY(.5em); transition: opacity .5s ease, transform .5s cubic-bezier(.22,1,.36,1); }
.ghb-fx-split-text.ghb-in .ghb-word { opacity: 1; transform: none; }

.ghb-fx-draw-underline h1,
.ghb-fx-draw-underline h2,
.ghb-fx-draw-underline h3 { position: relative; display: inline-block; }
.ghb-fx-draw-underline h1::after,
.ghb-fx-draw-underline h2::after,
.ghb-fx-draw-underline h3::after {
    content: ""; position: absolute; left: 0; bottom: -.12em; height: 3px; width: 100%;
    background: var(--ghb-accent, currentColor); transform: scaleX(0); transform-origin: left;
    transition: transform .9s cubic-bezier(.22,1,.36,1) .15s;
}
.ghb-fx-draw-underline.ghb-in h1::after,
.ghb-fx-draw-underline.ghb-in h2::after,
.ghb-fx-draw-underline.ghb-in h3::after { transform: scaleX(1); }

.ghb-fx-odometer { font-variant-numeric: tabular-nums; }

/* ===========================================================
   PROFUNDIDAD Y 3D
   =========================================================== */

.ghb-fx-layered-glass { perspective: 1200px; }
.ghb-fx-layered-glass .ghb-card-i,
.ghb-fx-layered-glass .emp-glass-card {
    background: rgba(255,255,255,.07);
    backdrop-filter: blur(16px) saturate(140%);
    -webkit-backdrop-filter: blur(16px) saturate(140%);
    border: 1px solid rgba(255,255,255,.16);
    box-shadow: 0 18px 50px -20px rgba(0,0,0,.55), inset 0 1px 0 rgba(255,255,255,.12);
    transform-style: preserve-3d;
    transition: transform .25s ease-out;
}
.ghb-fx-layered-glass .ghb-card-i:nth-child(2) { transform: translateZ(calc(var(--ghb-depth, 28px) * -1)); }
.ghb-fx-layered-glass .ghb-card-i:nth-child(3) { transform: translateZ(calc(var(--ghb-depth, 28px) * -2)); }

.ghb-fx-iso-fan { perspective: 1400px; }
.ghb-fx-iso-fan .ghb-cards { transform-style: preserve-3d; }
.ghb-fx-iso-fan .ghb-card-i {
    transform: rotateX(46deg) rotateZ(-38deg) translateZ(0);
    transition: transform .5s cubic-bezier(.22,1,.36,1);
    box-shadow: 14px 20px 34px -18px rgba(0,0,0,.6);
}
.ghb-fx-iso-fan .ghb-card-i:nth-child(2) { transform: rotateX(46deg) rotateZ(-38deg) translateZ(18px); }
.ghb-fx-iso-fan .ghb-card-i:nth-child(3) { transform: rotateX(46deg) rotateZ(-38deg) translateZ(36px); }
.ghb-fx-iso-fan .ghb-card-i:nth-child(4) { transform: rotateX(46deg) rotateZ(-38deg) translateZ(54px); }
.ghb-fx-iso-fan:hover .ghb-card-i { transform: rotateX(0) rotateZ(0) translateZ(0); }

.ghb-fx-carousel-3d { perspective: 1200px; overflow: hidden; }
.ghb-fx-carousel-3d .ghb-cards {
    transform-style: preserve-3d;
    animation: ghbSpin var(--ghb-spin, 26s) linear infinite;
    display: flex; justify-content: center;
}
.ghb-fx-carousel-3d:hover .ghb-cards { animation-play-state: paused; }
.ghb-fx-carousel-3d .ghb-card-i { position: absolute; width: 230px; }
.ghb-fx-carousel-3d .ghb-card-i:nth-child(1) { transform: rotateY(0deg) translateZ(300px); }
.ghb-fx-carousel-3d .ghb-card-i:nth-child(2) { transform: rotateY(60deg) translateZ(300px); }
.ghb-fx-carousel-3d .ghb-card-i:nth-child(3) { transform: rotateY(120deg) translateZ(300px); }
.ghb-fx-carousel-3d .ghb-card-i:nth-child(4) { transform: rotateY(180deg) translateZ(300px); }
.ghb-fx-carousel-3d .ghb-card-i:nth-child(5) { transform: rotateY(240deg) translateZ(300px); }
.ghb-fx-carousel-3d .ghb-card-i:nth-child(6) { transform: rotateY(300deg) translateZ(300px); }
@keyframes ghbSpin { from { transform: rotateY(0); } to { transform: rotateY(360deg); } }

.ghb-fx-flip { perspective: 1000px; }
.ghb-fx-flip .ghb-card-i { transition: transform .6s cubic-bezier(.22,1,.36,1); transform-style: preserve-3d; }
.ghb-fx-flip .ghb-card-i:hover { transform: rotateY(12deg) rotateX(6deg); }

.ghb-fx-depth-hover .ghb-card-i,
.ghb-fx-depth-hover .emp-content-card {
    transition: transform .3s cubic-bezier(.22,1,.36,1), box-shadow .3s ease;
}
.ghb-fx-depth-hover .ghb-card-i:hover,
.ghb-fx-depth-hover .emp-content-card:hover {
    transform: translateY(-8px);
    box-shadow: 0 22px 44px -20px rgba(0,0,0,.45);
}

.ghb-fx-sticky-stack { position: sticky; top: 24px; }

/* ===========================================================
   FONDO Y ATMÓSFERA
   =========================================================== */

.ghb-fx-mesh { position: relative; isolation: isolate; }
.ghb-fx-mesh::before {
    content: ""; position: absolute; inset: 0; z-index: -1; pointer-events: none; opacity: .55;
    background:
        radial-gradient(42% 52% at 18% 22%, var(--ghb-accent, #6c7bff) 0%, transparent 60%),
        radial-gradient(38% 48% at 82% 28%, var(--ghb-accent2, #22b8cf) 0%, transparent 62%),
        radial-gradient(46% 46% at 52% 88%, var(--ghb-accent, #6c7bff) 0%, transparent 58%);
    filter: blur(48px);
}

.ghb-fx-grain { position: relative; isolation: isolate; }
.ghb-fx-grain::after {
    content: ""; position: absolute; inset: 0; pointer-events: none; opacity: .25; mix-blend-mode: overlay;
    background-image: repeating-conic-gradient(rgba(255,255,255,.28) 0% 25%, transparent 0% 50%);
    background-size: 3px 3px;
}

.ghb-fx-aurora { position: relative; overflow: hidden; isolation: isolate; }
.ghb-fx-aurora::before {
    content: ""; position: absolute; inset: -40%; z-index: -1; pointer-events: none; opacity: .5;
    background: conic-gradient(from 0deg, transparent, var(--ghb-accent, #6c7bff), transparent, var(--ghb-accent2, #22b8cf), transparent);
    filter: blur(60px);
    animation: ghbAurora 22s linear infinite;
}
@keyframes ghbAurora { to { transform: rotate(360deg); } }

.ghb-fx-grid-lines { position: relative; isolation: isolate; }
.ghb-fx-grid-lines::before {
    content: ""; position: absolute; inset: 0; z-index: -1; pointer-events: none; opacity: .16;
    background-image:
        linear-gradient(to right, currentColor 1px, transparent 1px),
        linear-gradient(to bottom, currentColor 1px, transparent 1px);
    background-size: 44px 44px;
    mask-image: radial-gradient(ellipse at center, #000 35%, transparent 78%);
    -webkit-mask-image: radial-gradient(ellipse at center, #000 35%, transparent 78%);
}

.ghb-fx-dots { position: relative; isolation: isolate; }
.ghb-fx-dots::before {
    content: ""; position: absolute; inset: 0; z-index: -1; pointer-events: none; opacity: .22;
    background-image: radial-gradient(currentColor 1.2px, transparent 1.2px);
    background-size: 20px 20px;
}

/* spotlight: el JS escribe --mx / --my con la posición del cursor */
.ghb-fx-spotlight { position: relative; isolation: isolate; }
.ghb-fx-spotlight::before {
    content: ""; position: absolute; inset: 0; z-index: -1; pointer-events: none;
    background: radial-gradient(420px circle at var(--mx, 50%) var(--my, 50%), color-mix(in srgb, var(--ghb-accent, #6c7bff) 26%, transparent), transparent 70%);
    transition: background .18s ease-out;
}

/* ===========================================================
   MOVIMIENTO CONTINUO
   =========================================================== */

.ghb-fx-orbit { position: relative; }
.ghb-fx-orbit::after {
    content: ""; position: absolute; width: 10px; height: 10px; border-radius: 50%; top: -5px; left: 50%;
    background: var(--ghb-accent, #6c7bff);
    box-shadow: 0 0 16px 4px var(--ghb-accent, #6c7bff);
    transform-origin: 0 calc(50% + 5px);
    animation: ghbOrbit 9s linear infinite;
    pointer-events: none;
}
@keyframes ghbOrbit { to { transform: rotate(360deg); } }

.ghb-fx-pulse { animation: ghbPulse 2.6s ease-in-out infinite; }
@keyframes ghbPulse { 0%,100% { transform: scale(1); } 50% { transform: scale(1.025); } }

.ghb-fx-conic-border { position: relative; }
.ghb-fx-conic-border::before {
    content: ""; position: absolute; inset: -2px; border-radius: inherit; z-index: -1; pointer-events: none;
    background: conic-gradient(from 0deg, transparent 0deg, var(--ghb-accent, #6c7bff) 70deg, var(--ghb-accent2, #22b8cf) 140deg, transparent 210deg);
    animation: ghbConic 6s linear infinite;
}
@keyframes ghbConic { to { transform: rotate(360deg); } }

.ghb-fx-shimmer { position: relative; overflow: hidden; }
.ghb-fx-shimmer::after {
    content: ""; position: absolute; top: 0; left: -60%; width: 45%; height: 100%; pointer-events: none;
    background: linear-gradient(100deg, transparent, rgba(255,255,255,.22), transparent);
    animation: ghbShimmer 4.2s ease-in-out infinite;
}
@keyframes ghbShimmer { 0% { left: -60%; } 60%, 100% { left: 120%; } }

/* ===========================================================
   INTERACCIÓN
   =========================================================== */

.ghb-fx-magnetic .ghb-btn,
.ghb-fx-magnetic .emp-cta-btn { transition: transform .18s cubic-bezier(.22,1,.36,1); will-change: transform; }

.ghb-fx-ripple { position: relative; overflow: hidden; }
.ghb-fx-ripple .ghb-ripple-dot {
    position: absolute; border-radius: 50%; pointer-events: none;
    background: color-mix(in srgb, var(--ghb-accent, #6c7bff) 40%, transparent);
    transform: translate(-50%, -50%) scale(0);
    animation: ghbRipple .6s ease-out forwards;
}
@keyframes ghbRipple { to { transform: translate(-50%, -50%) scale(1); opacity: 0; } }

.ghb-fx-zoom-img img { transition: transform .5s cubic-bezier(.22,1,.36,1); }
.ghb-fx-zoom-img { overflow: hidden; }
.ghb-fx-zoom-img:hover img { transform: scale(1.06); }

.ghb-fx-hover-reveal .ghb-card-i p,
.ghb-fx-hover-reveal .ghb-card-i span {
    max-height: 0; opacity: 0; overflow: hidden;
    transition: max-height .4s ease, opacity .35s ease;
}
.ghb-fx-hover-reveal .ghb-card-i:hover p,
.ghb-fx-hover-reveal .ghb-card-i:hover span { max-height: 200px; opacity: 1; }

.ghb-progress-bar {
    position: fixed; top: 0; left: 0; height: 3px; width: 0; z-index: 99999;
    background: linear-gradient(90deg, var(--ghb-accent, #6c7bff), var(--ghb-accent2, #22b8cf));
    transition: width .1s linear;
}

/* ===========================================================
   SCROLL CINEMATOGRÁFICO
   =========================================================== */

.ghb-fx-parallax-layers > * { will-change: transform; }
.ghb-fx-zoom-scroll { will-change: transform; }
.ghb-fx-hero-sticky { position: sticky; top: 0; z-index: 0; }

/* ===========================================================
   MÓVIL — el 3D se achica y todo apila en una columna.
   =========================================================== */
@media (max-width: 900px) {
    .ghb-fx-carousel-3d .ghb-cards { animation: none; display: grid; }
    .ghb-fx-carousel-3d .ghb-card-i { position: static; width: auto; transform: none !important; }
    .ghb-fx-iso-fan .ghb-card-i { transform: none !important; box-shadow: 0 10px 24px -14px rgba(0,0,0,.4); }
    .ghb-fx-layered-glass .ghb-card-i { transform: none !important; }
    .ghb-fx-sticky-stack,
    .ghb-fx-hero-sticky { position: static; }
    .ghb-fx-mesh::before,
    .ghb-fx-aurora::before { filter: blur(34px); opacity: .4; }
}

/* ===========================================================
   HIPERESPACIO — estrellas y salto a la velocidad de la luz
   El dibujo lo hace un <canvas> que inyecta fx.js. Lo de acá es
   el andamio: dónde se apoya, qué queda encima, y el cielo de
   respaldo por si el JS no llega a cargar.
   =========================================================== */

.ghb-fx-hyperspace {
    position: relative;
    isolation: isolate;
}

/* Cielo de respaldo. Misma lección que el doble reveal: si el JS no
   carga, el bloque tiene que verse bien igual — acá queda un cielo
   estrellado fijo en vez de un rectángulo vacío. Se desvanece solo
   cuando el canvas ya está pintando. */
.ghb-fx-hyperspace::before {
    content: "";
    position: absolute;
    inset: 0;
    z-index: 0;
    border-radius: inherit;
    pointer-events: none;
    background-color: #05070f;
    background-image:
        radial-gradient(1.5px 1.5px at 12% 22%, rgba(255,255,255,.85), transparent 60%),
        radial-gradient(1px 1px at 28% 68%, rgba(255,255,255,.6), transparent 60%),
        radial-gradient(1.5px 1.5px at 44% 14%, rgba(255,255,255,.75), transparent 60%),
        radial-gradient(1px 1px at 57% 52%, rgba(255,255,255,.5), transparent 60%),
        radial-gradient(2px 2px at 71% 31%, rgba(255,255,255,.9), transparent 60%),
        radial-gradient(1px 1px at 83% 76%, rgba(255,255,255,.55), transparent 60%),
        radial-gradient(1.5px 1.5px at 92% 18%, rgba(255,255,255,.7), transparent 60%),
        radial-gradient(1px 1px at 8% 88%, rgba(255,255,255,.5), transparent 60%),
        radial-gradient(1px 1px at 36% 92%, rgba(255,255,255,.45), transparent 60%),
        radial-gradient(1.5px 1.5px at 64% 84%, rgba(255,255,255,.65), transparent 60%),
        radial-gradient(60% 50% at 50% 50%, rgba(125,211,252,.16), transparent 70%);
    transition: opacity .5s ease;
}
.ghb-fx-hyperspace.ghb-stars-on::before { opacity: 0; }

.ghb-fx-hyperspace > canvas.ghb-stars {
    position: absolute;
    inset: 0;
    display: block;
    width: 100%;
    height: 100%;
    z-index: 0;
    pointer-events: none;
    border-radius: inherit;
}

/* Todo lo que no sea el cielo va por encima. Sin esto el canvas tapa
   el texto del bloque. */
.ghb-fx-hyperspace > *:not(canvas.ghb-stars) {
    position: relative;
    z-index: 1;
}

/* ===========================================================
   ESPACIO Y VELOCIDAD — 9 escenas sobre <canvas> + titular RGB
   Mismo andamio que el hiperespacio: el canvas lo inyecta fx.js,
   acá va dónde se apoya, qué queda encima y un cielo de respaldo
   por si el JS no llega a cargar.
   =========================================================== */

:is(.ghb-fx-warp-tunnel, .ghb-fx-black-hole, .ghb-fx-synthwave, .ghb-fx-nebula, .ghb-fx-deep-space,
    .ghb-fx-fiber-optic, .ghb-fx-radar, .ghb-fx-network-mesh, .ghb-fx-orbits) {
    position: relative;
    isolation: isolate;
    overflow: hidden;
    min-height: 320px;
}

:is(.ghb-fx-warp-tunnel, .ghb-fx-black-hole, .ghb-fx-synthwave, .ghb-fx-nebula, .ghb-fx-deep-space,
    .ghb-fx-fiber-optic, .ghb-fx-radar, .ghb-fx-network-mesh, .ghb-fx-orbits) > canvas.ghb-scene {
    position: absolute;
    inset: 0;
    display: block;
    width: 100%;
    height: 100%;
    z-index: 0;
    pointer-events: none;
    border-radius: inherit;
}

:is(.ghb-fx-warp-tunnel, .ghb-fx-black-hole, .ghb-fx-synthwave, .ghb-fx-nebula, .ghb-fx-deep-space,
    .ghb-fx-fiber-optic, .ghb-fx-radar, .ghb-fx-network-mesh, .ghb-fx-orbits) > *:not(canvas.ghb-scene) {
    position: relative;
    z-index: 1;
}

/* Cielo de respaldo, distinto para cada escena. Se apaga cuando el canvas ya pinta. */
:is(.ghb-fx-warp-tunnel, .ghb-fx-black-hole, .ghb-fx-synthwave, .ghb-fx-nebula, .ghb-fx-deep-space,
    .ghb-fx-fiber-optic, .ghb-fx-radar, .ghb-fx-network-mesh, .ghb-fx-orbits)::before {
    content: "";
    position: absolute;
    inset: 0;
    z-index: 0;
    pointer-events: none;
    border-radius: inherit;
    transition: opacity .5s ease;
}
.ghb-scene-on::before,
.ghb-scene-clear::before { opacity: 0; }

.ghb-fx-warp-tunnel::before  { background: radial-gradient(circle at 50% 50%, rgba(255,255,255,.35), rgba(168,85,247,.25) 12%, transparent 30%), repeating-radial-gradient(circle at 50% 50%, rgba(34,211,238,.18) 0 2px, transparent 2px 38px), #03040a; }
.ghb-fx-black-hole::before   { background: radial-gradient(circle at 50% 50%, #000 0 9%, rgba(255,214,150,.6) 10%, rgba(255,86,36,.25) 16%, transparent 34%), #020205; }
.ghb-fx-synthwave::before    { background: linear-gradient(transparent 57%, #ff2bd6 58%, transparent 59%), repeating-linear-gradient(90deg, rgba(255,43,214,.25) 0 1px, transparent 1px 60px) bottom / 100% 42% no-repeat, radial-gradient(circle at 50% 50%, #ffbe6e 0 18%, transparent 19%), linear-gradient(#0b0320, #2a0a3a); }
.ghb-fx-nebula::before       { background: radial-gradient(40% 50% at 30% 40%, rgba(124,58,237,.45), transparent 70%), radial-gradient(35% 45% at 70% 60%, rgba(6,182,212,.35), transparent 70%), radial-gradient(25% 30% at 55% 30%, rgba(244,114,182,.3), transparent 70%), #04030c; }
.ghb-fx-deep-space::before   { background: radial-gradient(1.5px 1.5px at 15% 25%, #fff, transparent 60%), radial-gradient(1px 1px at 40% 70%, #fff, transparent 60%), radial-gradient(1.5px 1.5px at 75% 20%, #fff, transparent 60%), radial-gradient(circle at 92% 115%, #1e2950 0 45%, rgba(96,165,250,.4) 46%, transparent 52%), #02030a; }
.ghb-fx-fiber-optic::before  { background: radial-gradient(circle at 0% 66%, rgba(56,189,248,.45), transparent 30%), linear-gradient(160deg, transparent 45%, rgba(56,189,248,.12) 50%, transparent 55%), #020617; }
.ghb-fx-radar::before        { background: repeating-radial-gradient(circle at 73% 50%, transparent 0 60px, rgba(56,189,248,.18) 60px 61px), conic-gradient(from 90deg at 73% 50%, rgba(56,189,248,.28), transparent 25%), #020b14; }
.ghb-fx-network-mesh::before { background: radial-gradient(circle at 20% 30%, rgba(52,211,153,.35) 0 2px, transparent 3px), radial-gradient(circle at 70% 60%, rgba(52,211,153,.35) 0 2px, transparent 3px), radial-gradient(circle at 45% 80%, rgba(148,163,184,.4) 0 2px, transparent 3px), #050814; }
.ghb-fx-orbits::before       { background: radial-gradient(circle at 73% 50%, #6366f1 0 7%, rgba(99,102,241,.3) 9%, transparent 16%), radial-gradient(ellipse 30% 9% at 73% 50%, transparent 94%, rgba(125,211,252,.35) 95%, transparent 100%), #030712; }

/* Texto legible sobre el espacio. El hero ya trae su color propio; los demás
   bloques pasan a una paleta oscura con tarjetas de vidrio, para que ni el
   texto ni las tarjetas queden "oscuro sobre oscuro" en un skin claro.
   Con bg="transparente" (ghb-scene-clear) se respeta el skin tal cual. */
.ghb-block:is(.ghb-fx-warp-tunnel, .ghb-fx-black-hole, .ghb-fx-synthwave, .ghb-fx-nebula, .ghb-fx-deep-space,
    .ghb-fx-fiber-optic, .ghb-fx-radar, .ghb-fx-network-mesh, .ghb-fx-orbits):not(.ghb-hero):not(.ghb-scene-clear) {
    --ghb-text: #eef2ff;
    --ghb-muted: #b8c1d9;
    --ghb-card-bg: rgba(8, 12, 28, .58);
    --ghb-card-border: rgba(255, 255, 255, .14);
    color: #eef2ff;
}
.ghb-block:is(.ghb-fx-warp-tunnel, .ghb-fx-black-hole, .ghb-fx-synthwave, .ghb-fx-nebula, .ghb-fx-deep-space,
    .ghb-fx-fiber-optic, .ghb-fx-radar, .ghb-fx-network-mesh, .ghb-fx-orbits):not(.ghb-hero):not(.ghb-scene-clear) .ghb-card-i {
    -webkit-backdrop-filter: blur(10px);
    backdrop-filter: blur(10px);
}
/* El título del hero, con una sombra suave para que se despegue de lo que pasa atrás. */
.ghb-hero:is(.ghb-fx-warp-tunnel, .ghb-fx-black-hole, .ghb-fx-synthwave, .ghb-fx-nebula, .ghb-fx-deep-space,
    .ghb-fx-fiber-optic, .ghb-fx-radar, .ghb-fx-network-mesh, .ghb-fx-orbits) .ghb-hero-inner {
    text-shadow: 0 2px 18px rgba(0, 0, 0, .55);
}

/* ── Titular con aberración cromática ── */
.ghb-glitch-t {
    position: relative;
    text-shadow: -1px 0 rgba(34, 211, 238, .45), 1px 0 rgba(255, 43, 214, .45);
}
.ghb-glitch-t::before,
.ghb-glitch-t::after {
    content: attr(data-ghb-glitch);
    position: absolute;
    inset: 0;
    padding: inherit;
    box-sizing: border-box;
    pointer-events: none;
    opacity: 0;
    text-shadow: none;
    white-space: inherit;
    text-align: inherit;
}
.ghb-glitch-t::before { color: var(--ghb-glitch-a, #22d3ee); }
.ghb-glitch-t::after  { color: var(--ghb-glitch-b, #ff2bd6); }
.ghb-glitching { animation: ghb-glitch-base .65s steps(1) both; }
.ghb-glitching::before { animation: ghb-glitch-a .65s steps(1) both; }
.ghb-glitching::after  { animation: ghb-glitch-b .65s steps(1) both; }

@keyframes ghb-glitch-base {
    0%, 100% { transform: none; }
    20% { transform: translateX(2px) skewX(-4deg); }
    40% { transform: translateX(-2px); }
    60% { transform: skewX(3deg); }
}
@keyframes ghb-glitch-a {
    0%   { opacity: .9; clip-path: inset(12% 0 70% 0); transform: translate(-6px, -2px); }
    15%  { clip-path: inset(55% 0 20% 0); transform: translate(5px, 1px); }
    30%  { clip-path: inset(30% 0 45% 0); transform: translate(-3px, 0); }
    45%  { clip-path: inset(80% 0 5% 0);  transform: translate(7px, -1px); }
    60%  { clip-path: inset(5% 0 85% 0);  transform: translate(-5px, 2px); }
    75%  { clip-path: inset(40% 0 38% 0); transform: translate(3px, 0); }
    100% { opacity: 0; clip-path: inset(50% 0 50% 0); transform: none; }
}
@keyframes ghb-glitch-b {
    0%   { opacity: .9; clip-path: inset(65% 0 10% 0); transform: translate(6px, 1px); }
    15%  { clip-path: inset(15% 0 62% 0); transform: translate(-4px, -1px); }
    30%  { clip-path: inset(48% 0 30% 0); transform: translate(5px, 2px); }
    45%  { clip-path: inset(2% 0 88% 0);  transform: translate(-7px, 0); }
    60%  { clip-path: inset(72% 0 12% 0); transform: translate(4px, -2px); }
    75%  { clip-path: inset(25% 0 55% 0); transform: translate(-3px, 1px); }
    100% { opacity: 0; clip-path: inset(50% 0 50% 0); transform: none; }
}
@media (prefers-reduced-motion: reduce) {
    .ghb-glitching, .ghb-glitching::before, .ghb-glitching::after { animation: none; }
}

/* ===========================================================
   TECNOLOGÍA Y SEGURIDAD — 6 escenas más, mismo andamio.
   =========================================================== */

:is(.ghb-fx-datacenter, .ghb-fx-cctv-wall, .ghb-fx-ai-vision, .ghb-fx-circuit, .ghb-fx-terminal, .ghb-fx-antenna) {
    position: relative;
    isolation: isolate;
    overflow: hidden;
    min-height: 320px;
}
:is(.ghb-fx-datacenter, .ghb-fx-cctv-wall, .ghb-fx-ai-vision, .ghb-fx-circuit, .ghb-fx-terminal, .ghb-fx-antenna) > canvas.ghb-scene {
    position: absolute;
    inset: 0;
    display: block;
    width: 100%;
    height: 100%;
    z-index: 0;
    pointer-events: none;
    border-radius: inherit;
}
:is(.ghb-fx-datacenter, .ghb-fx-cctv-wall, .ghb-fx-ai-vision, .ghb-fx-circuit, .ghb-fx-terminal, .ghb-fx-antenna) > *:not(canvas.ghb-scene) {
    position: relative;
    z-index: 1;
}
:is(.ghb-fx-datacenter, .ghb-fx-cctv-wall, .ghb-fx-ai-vision, .ghb-fx-circuit, .ghb-fx-terminal, .ghb-fx-antenna)::before {
    content: "";
    position: absolute;
    inset: 0;
    z-index: 0;
    pointer-events: none;
    border-radius: inherit;
    transition: opacity .5s ease;
}

.ghb-fx-datacenter::before { background: radial-gradient(circle at 50% 46%, rgba(34,211,238,.3), transparent 35%), repeating-linear-gradient(90deg, transparent 0 46px, rgba(34,211,238,.12) 46px 48px), #03060c; }
.ghb-fx-cctv-wall::before  { background: linear-gradient(90deg, transparent 47%, #111820 47%), repeating-linear-gradient(0deg, transparent 0 3px, rgba(0,0,0,.25) 3px 4px), #05070a; }
.ghb-fx-ai-vision::before  { background: linear-gradient(rgba(56,189,248,.05) 1px, transparent 1px) 0 0 / 60px 60px, linear-gradient(90deg, rgba(56,189,248,.05) 1px, transparent 1px) 0 0 / 60px 60px, #04070d; }
.ghb-fx-circuit::before    { background: linear-gradient(rgba(45,212,191,.08) 1px, transparent 1px) 0 0 / 22px 22px, linear-gradient(90deg, rgba(45,212,191,.08) 1px, transparent 1px) 0 0 / 22px 22px, #031212; }
.ghb-fx-terminal::before   { background: linear-gradient(90deg, transparent 47%, rgba(2,6,23,.8) 47%), #020617; }
.ghb-fx-antenna::before    { background: repeating-radial-gradient(circle at 73% 20%, transparent 0 60px, rgba(239,68,68,.16) 60px 62px), #05060b; }

.ghb-block:is(.ghb-fx-datacenter, .ghb-fx-cctv-wall, .ghb-fx-ai-vision, .ghb-fx-circuit, .ghb-fx-terminal, .ghb-fx-antenna):not(.ghb-hero):not(.ghb-scene-clear) {
    --ghb-text: #eef2ff;
    --ghb-muted: #b8c1d9;
    --ghb-card-bg: rgba(8, 12, 28, .58);
    --ghb-card-border: rgba(255, 255, 255, .14);
    color: #eef2ff;
}
.ghb-hero:is(.ghb-fx-datacenter, .ghb-fx-cctv-wall, .ghb-fx-ai-vision, .ghb-fx-circuit, .ghb-fx-terminal, .ghb-fx-antenna) .ghb-hero-inner {
    text-shadow: 0 2px 18px rgba(0, 0, 0, .6);
}
