/* ZorX Stream Overlay — shared shape styles. */

.overlay-root {
  position: relative;
  width: 1920px;
  height: 1080px;
  font-family: 'Inter', system-ui, sans-serif;
  color: #fff;
}

.overlay-shape {
  position: absolute;
  width: 480px;
  aspect-ratio: 6 / 1;
  filter: drop-shadow(0 6px 18px rgba(0, 0, 0, 0.5));
  --hue: 0deg;
  --sat: 1;
  --bri: 1;
}

.overlay-shape__bg {
  position: absolute;
  inset: 0;
  background-position: center;
  background-size: contain;
  background-repeat: no-repeat;
  filter: hue-rotate(var(--hue)) saturate(var(--sat)) brightness(var(--bri));
  pointer-events: none;
  /* Defensive: keep each shape in its own compositing context so any SVG that
     uses internal `mix-blend-mode` composites within its own box and never
     blends against the (transparent in OBS, dark in editor) page backdrop.
     Cheap insurance so editor and OBS render identically. The primary OBS
     fix for vanishing shapes was sanitizing non-ASCII gradient IDs in
     Shape 1/Shape 2/Face Overlay (OBS's older Chromium failed to match
     `url(#...)` refs against multi-byte ids). */
  isolation: isolate;
}

.overlay-shape.is-solid-color .overlay-shape__bg {
  background-image: none !important;
  background-color: var(--solid-color, #aaff14);
  -webkit-mask-image: var(--svg-mask);
  -webkit-mask-position: center;
  -webkit-mask-size: contain;
  -webkit-mask-repeat: no-repeat;
          mask-image: var(--svg-mask);
          mask-position: center;
          mask-size: contain;
          mask-repeat: no-repeat;
  filter: none;
}

.overlay-shape__payment-wordmark {
  position: absolute;
  inset: 0;
  background-color: var(--payment-wordmark-color, #000000);
  -webkit-mask-image: var(--payment-wordmark-mask);
  -webkit-mask-position: center;
  -webkit-mask-size: contain;
  -webkit-mask-repeat: no-repeat;
          mask-image: var(--payment-wordmark-mask);
          mask-position: center;
          mask-size: contain;
          mask-repeat: no-repeat;
  pointer-events: none;
}

/* ---- Icon layer: recolorable via CSS mask (color = --icon-color) ----
   NOTE: Split mask into long-hand properties because OBS's older Chromium build
   doesn't reliably parse the `mask:` shorthand when its value comes from a CSS var. */
.overlay-shape--icon .overlay-shape__bg {
  background-image: none !important;
  background-color: var(--icon-color, #aaff14);
  -webkit-mask-image: var(--svg-mask);
  -webkit-mask-position: center;
  -webkit-mask-size: contain;
  -webkit-mask-repeat: no-repeat;
          mask-image: var(--svg-mask);
          mask-position: center;
          mask-size: contain;
          mask-repeat: no-repeat;
  filter: drop-shadow(0 2px 6px rgba(0,0,0,.45));
}
.overlay-shape--icon { filter: none; }

/* ---- Ticker / Marquee bar ---- */
.overlay-shape--ticker {
  filter: none;
  overflow: hidden;
  display: flex;
  align-items: center;
  border-radius: 4px;
}
.overlay-shape--ticker .ticker-track {
  display: inline-flex;
  align-items: center;
  white-space: nowrap;
  will-change: transform;
  animation: zorx-ticker-left var(--ticker-speed, 30s) linear infinite;
}
.overlay-shape--ticker[data-ticker-dir="right"] .ticker-track {
  animation-name: zorx-ticker-right;
}
.overlay-shape--ticker .ticker-item {
  display: inline-flex;
  align-items: center;
  font-weight: 700;
  text-transform: uppercase;
  line-height: 1;
}
@keyframes zorx-ticker-left {
  0%   { transform: translate3d(0, 0, 0); }
  100% { transform: translate3d(-50%, 0, 0); }
}
@keyframes zorx-ticker-right {
  0%   { transform: translate3d(-50%, 0, 0); }
  100% { transform: translate3d(0, 0, 0); }
}

/* ============ Goal Bar ============ */
.overlay-goal {
  filter: none;
  display: flex;
  flex-direction: column;
  justify-content: center;
  gap: 8px;
  padding: 4px 0;
  box-sizing: border-box;
  overflow: visible;
}
.overlay-goal__head {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 12px;
  text-transform: uppercase;
  font-weight: 700;
}
.overlay-goal__label { font-weight: 700; }
.overlay-goal__value { font-weight: 700; letter-spacing: 0.8px; font-family: 'JetBrains Mono', monospace; }
.overlay-goal__track {
  position: relative;
  width: 100%;
  height: 14px;
  background: var(--goal-track, rgba(255,255,255,0.08));
  border-radius: 8px;
  overflow: hidden;
}
.overlay-goal__fill {
  position: absolute;
  top: 0; left: 0; bottom: 0;
  width: var(--goal-pct, 0%);
  background: var(--goal-fill, #aaff14);
  border-radius: inherit;
  transition: width 1.4s cubic-bezier(0.16, 1, 0.3, 1);
}

/* Style: Classic */
.overlay-goal--classic .overlay-goal__track {
  background: var(--goal-track);
  border: 1px solid rgba(255,255,255,0.08);
}
.overlay-goal--classic .overlay-goal__fill {
  background: linear-gradient(90deg, color-mix(in srgb, var(--goal-fill) 70%, transparent), var(--goal-fill));
}

/* Style: Neon (bright glowing edges + animated shine) */
.overlay-goal--neon .overlay-goal__track {
  height: 16px;
  background: rgba(0,0,0,0.6);
  border: 1px solid color-mix(in srgb, var(--goal-fill) 40%, transparent);
  box-shadow: 0 0 12px color-mix(in srgb, var(--goal-fill) 30%, transparent), inset 0 0 6px rgba(0,0,0,0.6);
}
.overlay-goal--neon .overlay-goal__fill {
  background: linear-gradient(90deg, color-mix(in srgb, var(--goal-fill) 55%, transparent), var(--goal-fill));
  box-shadow: 0 0 10px var(--goal-fill), 0 0 24px var(--goal-fill);
}
.overlay-goal--neon .overlay-goal__fill::after {
  content: '';
  position: absolute;
  inset: 0;
  background: linear-gradient(90deg, transparent, rgba(255,255,255,0.45), transparent);
  background-size: 200% 100%;
  animation: zorx-goal-shine 2.4s linear infinite;
}

/* Style: Pill (slim, super rounded) */
.overlay-goal--pill .overlay-goal__track {
  height: 10px;
  border-radius: 999px;
  background: var(--goal-track);
}
.overlay-goal--pill .overlay-goal__fill {
  border-radius: 999px;
  background: var(--goal-fill);
}

/* Style: Segmented (20 discrete blocks lighting up) */
.overlay-goal--segmented .overlay-goal__track {
  height: 18px;
  background: transparent;
  padding: 0;
}
.overlay-goal__segs {
  display: flex;
  width: 100%;
  height: 100%;
  gap: 3px;
}
.overlay-goal__seg {
  flex: 1;
  background: var(--goal-track);
  border-radius: 2px;
  transition: background 0.25s ease, box-shadow 0.25s ease;
}
.overlay-goal__seg.is-lit {
  background: var(--goal-fill);
  box-shadow: 0 0 6px var(--goal-fill);
}

/* Style: Glass (frosted/translucent with shine) */
.overlay-goal--glass .overlay-goal__track {
  height: 18px;
  background: rgba(255,255,255,0.05);
  border: 1px solid rgba(255,255,255,0.18);
  backdrop-filter: blur(6px);
  -webkit-backdrop-filter: blur(6px);
}
.overlay-goal--glass .overlay-goal__fill {
  background: linear-gradient(180deg,
    color-mix(in srgb, var(--goal-fill) 65%, transparent),
    color-mix(in srgb, var(--goal-fill) 95%, black) 100%);
  border-right: 1px solid rgba(255,255,255,0.35);
}
.overlay-goal__shine {
  position: absolute;
  top: 0; left: 0; right: 0;
  height: 50%;
  background: linear-gradient(180deg, rgba(255,255,255,0.18), transparent);
  border-radius: inherit inherit 0 0;
  pointer-events: none;
}

@keyframes zorx-goal-shine {
  0%   { background-position: 200% 0; }
  100% { background-position: -200% 0; }
}

/* Text: wrapper positions (translateY(-50%) for vertical center), inner gets animated.
   Separating these means text animations don't override vertical centering. */
.overlay-text {
  position: absolute;
  z-index: 2;
  transform: translateY(-50%);
  word-break: break-word;
  pointer-events: auto;
}
.overlay-text__inner {
  display: inline-block;
  max-width: 100%;
}

/* Editor-only helpers (no effect in the viewer).
   Use outline (doesn't affect layout/box size) so editor & OBS-view position match exactly. */
.overlay-root--editor .overlay-shape { cursor: grab; }
.overlay-root--editor .overlay-shape.dragging { cursor: grabbing; }
.overlay-root--editor .overlay-shape.selected {
  outline: 2px dashed #aaff14;
  outline-offset: 4px;
}
.overlay-root--editor .overlay-text {
  cursor: move;
  outline: 1px dashed transparent;
  outline-offset: 2px;
}
.overlay-root--editor .overlay-shape.selected .overlay-text {
  outline-color: rgba(170, 255, 20, 0.35);
}
.overlay-root--editor .overlay-text:hover {
  outline-color: rgba(170, 255, 20, 0.7);
}
.overlay-root--editor .overlay-text.dragging {
  outline-style: solid;
  outline-color: #aaff14;
  background: rgba(170, 255, 20, 0.06);
}

/* ===================== ANIMATIONS — all infinite loops ===================== */

@property --cyber-angle {
  syntax: '<angle>';
  initial-value: 0deg;
  inherits: false;
}

/* ---- SHAPE ANIMATIONS — unified 7s in/out timing (16% in, 84% out) so shapes + text + icons all sync ---- */
.overlay-shape[data-anim="fade"]        { animation: zorx-fade-loop        7s cubic-bezier(0.4, 0, 0.2, 1)   infinite; }
.overlay-shape[data-anim="slide-left"]  { animation: zorx-slide-left-loop  7s cubic-bezier(0.16, 1, 0.3, 1)  infinite; }
.overlay-shape[data-anim="slide-right"] { animation: zorx-slide-right-loop 7s cubic-bezier(0.16, 1, 0.3, 1)  infinite; }
.overlay-shape[data-anim="slide-up"]    { animation: zorx-slide-up-loop    7s cubic-bezier(0.16, 1, 0.3, 1)  infinite; }
.overlay-shape[data-anim="slide-down"]  { animation: zorx-slide-down-loop  7s cubic-bezier(0.16, 1, 0.3, 1)  infinite; }
.overlay-shape[data-anim="pop"]         { animation: zorx-pop-loop         7s cubic-bezier(0.34, 1.4, 0.64, 1) infinite; }
.overlay-shape[data-anim="zoom-in"]     { animation: zorx-zoom-in-loop     7s cubic-bezier(0.16, 1, 0.3, 1)   infinite; }
.overlay-shape[data-anim="zoom-out"]    { animation: zorx-zoom-out-loop    7s cubic-bezier(0.16, 1, 0.3, 1)   infinite; }
.overlay-shape[data-anim="rotate"]      { animation: zorx-rotate-loop      7s cubic-bezier(0.16, 1, 0.3, 1)   infinite; }
.overlay-shape[data-anim="flip"]        { animation: zorx-flip-loop        7s cubic-bezier(0.16, 1, 0.3, 1)   infinite; }
.overlay-shape[data-anim="bounce"]      { animation: zorx-bounce-loop      7s cubic-bezier(0.34, 1.5, 0.64, 1) infinite; }
.overlay-shape[data-anim="swing"]       { animation: zorx-swing-loop       7s cubic-bezier(0.4, 0, 0.2, 1)    infinite; transform-origin: top center; }
.overlay-shape[data-anim="spin"]        { animation: zorx-spin-loop        7s linear                          infinite; }
.overlay-shape[data-anim="roll-in"]     { animation: zorx-roll-in-loop     7s cubic-bezier(0.16, 1, 0.3, 1)   infinite; }
.overlay-shape[data-anim="drop"]        { animation: zorx-drop-loop        7s cubic-bezier(0.34, 1.5, 0.64, 1) infinite; }
.overlay-shape[data-anim="wobble"]      { animation: zorx-wobble-loop      7s cubic-bezier(0.4, 0, 0.2, 1)    infinite; }
.overlay-shape[data-anim="shake"]       { animation: zorx-shake-loop       7s cubic-bezier(0.4, 0, 0.2, 1)    infinite; }

@keyframes zorx-fade-loop {
  0%, 100%   { opacity: 0; }
  16%, 84%   { opacity: 1; }
}
@keyframes zorx-slide-left-loop {
  0%       { opacity: 0; transform: translateX(-80px); }
  16%, 84% { opacity: 1; transform: translateX(0); }
  100%     { opacity: 0; transform: translateX(80px); }
}
@keyframes zorx-slide-right-loop {
  0%       { opacity: 0; transform: translateX(80px); }
  16%, 84% { opacity: 1; transform: translateX(0); }
  100%     { opacity: 0; transform: translateX(-80px); }
}
@keyframes zorx-slide-up-loop {
  0%       { opacity: 0; transform: translateY(80px); }
  16%, 84% { opacity: 1; transform: translateY(0); }
  100%     { opacity: 0; transform: translateY(-80px); }
}
@keyframes zorx-slide-down-loop {
  0%       { opacity: 0; transform: translateY(-80px); }
  16%, 84% { opacity: 1; transform: translateY(0); }
  100%     { opacity: 0; transform: translateY(80px); }
}
@keyframes zorx-pop-loop {
  0%, 100% { opacity: 0; transform: scale(.65); }
  10%      { transform: scale(1.12); }
  16%, 84% { opacity: 1; transform: scale(1); }
  92%      { transform: scale(.92); }
}
@keyframes zorx-zoom-in-loop {
  0%       { opacity: 0; transform: scale(0); }
  16%, 84% { opacity: 1; transform: scale(1); }
  100%     { opacity: 0; transform: scale(0); }
}
@keyframes zorx-zoom-out-loop {
  0%       { opacity: 0; transform: scale(1.8); }
  16%, 84% { opacity: 1; transform: scale(1); }
  100%     { opacity: 0; transform: scale(1.8); }
}
@keyframes zorx-rotate-loop {
  0%       { opacity: 0; transform: rotate(-180deg) scale(.4); }
  16%, 84% { opacity: 1; transform: rotate(0deg) scale(1); }
  100%     { opacity: 0; transform: rotate(180deg) scale(.4); }
}
@keyframes zorx-flip-loop {
  0%       { opacity: 0; transform: perspective(600px) rotateY(90deg); }
  16%, 84% { opacity: 1; transform: perspective(600px) rotateY(0deg); }
  100%     { opacity: 0; transform: perspective(600px) rotateY(-90deg); }
}
@keyframes zorx-bounce-loop {
  0%       { opacity: 0; transform: translateY(-120px) scale(.7); }
  10%      { transform: translateY(0) scale(1.08); }
  16%, 84% { opacity: 1; transform: translateY(0) scale(1); }
  90%      { transform: translateY(-12px) scale(1.04); }
  100%     { opacity: 0; transform: translateY(120px) scale(.7); }
}
@keyframes zorx-swing-loop {
  0%       { opacity: 0; transform: rotate(20deg); }
  12%      { opacity: 1; transform: rotate(-15deg); }
  24%      { transform: rotate(10deg); }
  36%      { transform: rotate(-6deg); }
  48%      { transform: rotate(3deg); }
  60%, 80% { opacity: 1; transform: rotate(0deg); }
  100%     { opacity: 0; transform: rotate(20deg); }
}
@keyframes zorx-spin-loop {
  0%       { opacity: 0; transform: rotate(0deg) scale(.4); }
  10%      { opacity: 1; }
  16%, 84% { opacity: 1; transform: rotate(720deg) scale(1); }
  90%      { opacity: 1; }
  100%     { opacity: 0; transform: rotate(1440deg) scale(.4); }
}
@keyframes zorx-roll-in-loop {
  0%       { opacity: 0; transform: translateX(-150px) rotate(-360deg); }
  16%, 84% { opacity: 1; transform: translateX(0) rotate(0deg); }
  100%     { opacity: 0; transform: translateX(150px) rotate(360deg); }
}
@keyframes zorx-drop-loop {
  0%       { opacity: 0; transform: translateY(-200px) scale(1, .85); }
  10%      { opacity: 1; transform: translateY(0) scale(1.15, .8); }
  14%      { transform: translateY(0) scale(.92, 1.1); }
  16%, 84% { opacity: 1; transform: translateY(0) scale(1, 1); }
  90%      { transform: translateY(-20px) scale(1.05, .92); }
  100%     { opacity: 0; transform: translateY(200px) scale(1, .85); }
}
@keyframes zorx-wobble-loop {
  0%       { opacity: 0; transform: translateX(0) rotate(0deg); }
  12%      { opacity: 1; transform: translateX(-25%) rotate(-5deg); }
  24%      { transform: translateX(20%) rotate(3deg); }
  36%      { transform: translateX(-15%) rotate(-3deg); }
  48%      { transform: translateX(10%) rotate(2deg); }
  60%      { transform: translateX(-5%) rotate(-1deg); }
  72%, 84% { opacity: 1; transform: translateX(0) rotate(0deg); }
  100%     { opacity: 0; transform: translateX(0) rotate(0deg); }
}
@keyframes zorx-shake-loop {
  0%, 100%       { opacity: 0; transform: translateX(0); }
  10%, 16%, 84%, 90% { opacity: 1; transform: translateX(0); }
  18%, 22%, 26%  { transform: translateX(-10px); }
  20%, 24%, 28%  { transform: translateX(10px); }
}

/* ---- CYBER EFFECTS — independent of shape animation, run on ::after pseudo only.
   All variants use the XOR edge-ring mask so the glow follows the actual SVG silhouette. ---- */
.overlay-shape[data-cyber]::after {
  content: '';
  position: absolute; inset: 0;
  -webkit-mask:
    var(--svg-mask) center / 100% 100% no-repeat,
    var(--svg-mask) center / calc(100% - var(--cyber-thickness, 8px)) calc(100% - var(--cyber-thickness, 8px)) no-repeat;
  -webkit-mask-composite: xor;
          mask:
    var(--svg-mask) center / 100% 100% no-repeat,
    var(--svg-mask) center / calc(100% - var(--cyber-thickness, 8px)) calc(100% - var(--cyber-thickness, 8px)) no-repeat;
          mask-composite: exclude;
  filter:
    drop-shadow(0 0 4px var(--cyber-color, #aaff14))
    drop-shadow(0 0 10px var(--cyber-color, #aaff14));
  pointer-events: none;
  z-index: 1;
  mix-blend-mode: screen;
}
@keyframes zorx-cyber-rotate { to { --cyber-angle: 360deg; } }

.overlay-shape[data-cyber="edges"]::after {
  background: conic-gradient(
    from var(--cyber-angle, 0deg),
    transparent 0deg,
    var(--cyber-color, #aaff14) 18deg,
    transparent 50deg,
    transparent 180deg,
    var(--cyber-color, #aaff14) 198deg,
    transparent 230deg,
    transparent 360deg
  );
  animation: zorx-cyber-rotate var(--cyber-speed, 3s) linear infinite;
}

.overlay-shape[data-cyber="spark"]::after {
  background: conic-gradient(
    from var(--cyber-angle, 0deg),
    transparent 0deg,
    var(--cyber-color, #aaff14) 4deg,
    transparent 12deg,
    transparent 50deg,
    var(--cyber-color, #aaff14) 54deg,
    transparent 62deg,
    transparent 110deg,
    var(--cyber-color, #aaff14) 114deg,
    transparent 122deg,
    transparent 200deg,
    var(--cyber-color, #aaff14) 204deg,
    transparent 212deg,
    transparent 280deg,
    var(--cyber-color, #aaff14) 284deg,
    transparent 292deg,
    transparent 360deg
  );
  animation: zorx-cyber-rotate var(--cyber-speed, 3s) linear infinite;
}

.overlay-shape[data-cyber="comet"]::after {
  background: conic-gradient(
    from var(--cyber-angle, 0deg),
    transparent 0deg,
    var(--cyber-color, #aaff14) 90deg,
    transparent 130deg,
    transparent 360deg
  );
  animation: zorx-cyber-rotate var(--cyber-speed, 3s) linear infinite;
  filter:
    drop-shadow(0 0 4px var(--cyber-color, #aaff14))
    drop-shadow(0 0 12px var(--cyber-color, #aaff14))
    drop-shadow(0 0 24px var(--cyber-color, #aaff14));
}

.overlay-shape[data-cyber="dual"]::after {
  background: conic-gradient(
    from var(--cyber-angle, 0deg),
    transparent 0deg,
    var(--cyber-color, #aaff14) 16deg,
    transparent 44deg,
    transparent 180deg,
    var(--cyber-color, #aaff14) 196deg,
    transparent 224deg,
    transparent 360deg
  );
  animation: zorx-cyber-rotate var(--cyber-speed, 3s) linear infinite;
}

.overlay-shape[data-cyber="triple"]::after {
  background: conic-gradient(
    from var(--cyber-angle, 0deg),
    transparent 0deg,
    var(--cyber-color, #aaff14) 14deg,
    transparent 38deg,
    transparent 120deg,
    var(--cyber-color, #aaff14) 134deg,
    transparent 158deg,
    transparent 240deg,
    var(--cyber-color, #aaff14) 254deg,
    transparent 278deg,
    transparent 360deg
  );
  animation: zorx-cyber-rotate var(--cyber-speed, 3s) linear infinite;
}

/* Edge Wave — wide smooth flowing bright arc */
.overlay-shape[data-cyber="wave"]::after {
  background: conic-gradient(
    from var(--cyber-angle, 0deg),
    transparent 0deg,
    var(--cyber-color, #aaff14) 60deg,
    var(--cyber-color, #aaff14) 120deg,
    transparent 180deg,
    transparent 360deg
  );
  animation: zorx-cyber-rotate var(--cyber-speed, 3s) ease-in-out infinite;
  opacity: 0.85;
}

/* Edge Beat — rotating spot with rhythmic brightness pulse */
.overlay-shape[data-cyber="beat"]::after {
  background: conic-gradient(
    from var(--cyber-angle, 0deg),
    transparent 0deg,
    var(--cyber-color, #aaff14) 24deg,
    transparent 60deg,
    transparent 360deg
  );
  animation:
    zorx-cyber-rotate var(--cyber-speed, 3s) linear infinite,
    zorx-cyber-beat calc(var(--cyber-speed, 3s) / 2) ease-in-out infinite;
}
@keyframes zorx-cyber-beat {
  0%, 100% { opacity: 0.4; }
  50%      { opacity: 1; }
}

/* Edge Pulse — whole edge ring brightens and dims rhythmically */
.overlay-shape[data-cyber="pulse"]::after {
  background: var(--cyber-color, #aaff14);
  animation: zorx-cyber-edge-pulse var(--cyber-speed, 3s) ease-in-out infinite;
}
@keyframes zorx-cyber-edge-pulse {
  0%, 100% { opacity: 0.15; }
  50%      { opacity: 1; }
}

/* Quad Trace — 4 evenly-spaced bright spots circling the edge */
.overlay-shape[data-cyber="quad"]::after {
  background: conic-gradient(
    from var(--cyber-angle, 0deg),
    transparent 0deg,
    var(--cyber-color, #aaff14) 10deg,
    transparent 30deg,
    transparent 90deg,
    var(--cyber-color, #aaff14) 100deg,
    transparent 120deg,
    transparent 180deg,
    var(--cyber-color, #aaff14) 190deg,
    transparent 210deg,
    transparent 270deg,
    var(--cyber-color, #aaff14) 280deg,
    transparent 300deg,
    transparent 360deg
  );
  animation: zorx-cyber-rotate var(--cyber-speed, 3s) linear infinite;
}

/* Laser Sweep — single very thin bright beam, very fast and intense */
.overlay-shape[data-cyber="laser"]::after {
  background: conic-gradient(
    from var(--cyber-angle, 0deg),
    transparent 0deg,
    var(--cyber-color, #aaff14) 2deg,
    transparent 8deg,
    transparent 360deg
  );
  animation: zorx-cyber-rotate calc(var(--cyber-speed, 3s) * 0.55) linear infinite;
  filter:
    drop-shadow(0 0 3px var(--cyber-color, #aaff14))
    drop-shadow(0 0 8px var(--cyber-color, #aaff14))
    drop-shadow(0 0 16px var(--cyber-color, #aaff14))
    drop-shadow(0 0 28px var(--cyber-color, #aaff14));
}

/* Rainbow Trace — single spot circling with cycling hue */
.overlay-shape[data-cyber="rainbow"]::after {
  background: conic-gradient(
    from var(--cyber-angle, 0deg),
    transparent 0deg,
    var(--cyber-color, #aaff14) 18deg,
    transparent 60deg,
    transparent 360deg
  );
  animation:
    zorx-cyber-rotate var(--cyber-speed, 3s) linear infinite,
    zorx-cyber-rainbow calc(var(--cyber-speed, 3s) * 1.8) linear infinite;
}
@keyframes zorx-cyber-rainbow {
  0%   { filter: hue-rotate(0deg)   drop-shadow(0 0 6px var(--cyber-color, #aaff14)) drop-shadow(0 0 14px var(--cyber-color, #aaff14)); }
  100% { filter: hue-rotate(360deg) drop-shadow(0 0 6px var(--cyber-color, #aaff14)) drop-shadow(0 0 14px var(--cyber-color, #aaff14)); }
}

/* Edge Strobe — entire edge flashes on/off rapidly, no rotation */
.overlay-shape[data-cyber="strobe"]::after {
  background: var(--cyber-color, #aaff14);
  animation: zorx-cyber-strobe calc(var(--cyber-speed, 3s) * 0.35) steps(2, end) infinite;
}
@keyframes zorx-cyber-strobe {
  0%, 49%   { opacity: 1; }
  50%, 100% { opacity: 0; }
}

/* Solid Glow — steady soft pulsing edge, no rotation (clean look) */
.overlay-shape[data-cyber="glow"]::after {
  background: var(--cyber-color, #aaff14);
  animation: zorx-cyber-solid-glow var(--cyber-speed, 3s) ease-in-out infinite;
  filter:
    drop-shadow(0 0 6px var(--cyber-color, #aaff14))
    drop-shadow(0 0 14px var(--cyber-color, #aaff14))
    drop-shadow(0 0 22px var(--cyber-color, #aaff14));
}
@keyframes zorx-cyber-solid-glow {
  0%, 100% { opacity: 0.6; }
  50%      { opacity: 1;   }
}

/* Heartbeat — double-pulse like an EKG beat (no rotation) */
.overlay-shape[data-cyber="heartbeat"]::after {
  background: var(--cyber-color, #aaff14);
  animation: zorx-cyber-heartbeat var(--cyber-speed, 3s) ease-out infinite;
}
@keyframes zorx-cyber-heartbeat {
  0%       { opacity: 0.2; }
  8%       { opacity: 1;   }
  16%      { opacity: 0.3; }
  22%      { opacity: 1;   }
  30%      { opacity: 0.25; }
  100%     { opacity: 0.2; }
}

/* Plasma Flow — multi-color flowing energy around the edge */
.overlay-shape[data-cyber="plasma"]::after {
  background: conic-gradient(
    from var(--cyber-angle, 0deg),
    var(--cyber-color, #aaff14) 0deg,
    #ff2b6e 90deg,
    #00f7cb 180deg,
    #ffd15c 270deg,
    var(--cyber-color, #aaff14) 360deg
  );
  animation: zorx-cyber-rotate var(--cyber-speed, 3s) linear infinite;
  opacity: 0.9;
  filter:
    drop-shadow(0 0 4px var(--cyber-color, #aaff14))
    drop-shadow(0 0 12px var(--cyber-color, #aaff14));
  mix-blend-mode: screen;
}

/* Glitch Flicker — random rapid on/off bursts (glitchy strobe) */
.overlay-shape[data-cyber="flicker"]::after {
  background: var(--cyber-color, #aaff14);
  animation: zorx-cyber-flicker calc(var(--cyber-speed, 3s) * 0.8) steps(1, end) infinite;
}
@keyframes zorx-cyber-flicker {
  0%, 4%, 9%, 14%, 22%, 28%, 36%, 50%, 64%, 78%, 100% { opacity: 1; }
  6%, 12%, 19%, 25%, 32%, 42%, 56%, 72%               { opacity: 0; }
  16%, 24%, 38%                                       { opacity: 0.35; }
}


/* ---- TEXT ANIMATIONS — AE-style smooth easing on slides ---- */
/* Text in/out animations share the 7s timing of shape animations so they enter/exit together. */
.overlay-text__inner[data-anim="fade"]        { animation: zorx-text-fade-loop        7s cubic-bezier(0.4, 0, 0.2, 1)  infinite; }
.overlay-text__inner[data-anim="slide-left"]  { animation: zorx-text-slide-left-loop  7s cubic-bezier(0.16, 1, 0.3, 1) infinite; }
.overlay-text__inner[data-anim="slide-right"] { animation: zorx-text-slide-right-loop 7s cubic-bezier(0.16, 1, 0.3, 1) infinite; }
.overlay-text__inner[data-anim="slide-up"]    { animation: zorx-text-slide-up-loop    7s cubic-bezier(0.16, 1, 0.3, 1) infinite; }
.overlay-text__inner[data-anim="slide-down"]  { animation: zorx-text-slide-down-loop  7s cubic-bezier(0.16, 1, 0.3, 1) infinite; }
.overlay-text__inner[data-anim="typewriter"] {
  overflow: hidden;
  white-space: nowrap;
  animation: zorx-typewriter-loop 7s steps(28, end) infinite;
}
.overlay-text__inner[data-anim="wave"]    { animation: zorx-text-wave 3s ease-in-out infinite; }
.overlay-text__inner[data-anim="pulse"]   { animation: zorx-text-pulse 2.4s ease-in-out infinite; transform-origin: center; }
.overlay-text__inner[data-anim="float"]   { animation: zorx-text-float 3.6s ease-in-out infinite; }
.overlay-text__inner[data-anim="breathe"] { animation: zorx-text-breathe 4s ease-in-out infinite; transform-origin: center; }
.overlay-text__inner[data-anim="zoom-in"] { animation: zorx-text-zoom-in-loop 7s cubic-bezier(0.16, 1, 0.3, 1) infinite; transform-origin: center; }
.overlay-text__inner[data-anim="bounce"]  { animation: zorx-text-bounce-loop  7s cubic-bezier(0.34, 1.5, 0.64, 1) infinite; }
.overlay-text__inner[data-anim="flicker"] { animation: zorx-text-flicker      2.2s steps(1, end) infinite; }
.overlay-text__inner[data-anim="glitch"]  { animation: zorx-text-glitch       2.4s steps(2, end) infinite; }
.overlay-text__inner[data-anim="shake"]   { animation: zorx-text-shake        7s cubic-bezier(0.4, 0, 0.2, 1) infinite; }

@keyframes zorx-text-fade-loop {
  0%, 100%   { opacity: 0; }
  16%, 84%   { opacity: 1; }
}
@keyframes zorx-text-slide-left-loop {
  0%       { opacity: 0; transform: translateX(-40px); }
  16%, 84% { opacity: 1; transform: translateX(0); }
  100%     { opacity: 0; transform: translateX(40px); }
}
@keyframes zorx-text-slide-right-loop {
  0%       { opacity: 0; transform: translateX(40px); }
  16%, 84% { opacity: 1; transform: translateX(0); }
  100%     { opacity: 0; transform: translateX(-40px); }
}
@keyframes zorx-text-slide-up-loop {
  0%       { opacity: 0; transform: translateY(30px); }
  16%, 84% { opacity: 1; transform: translateY(0); }
  100%     { opacity: 0; transform: translateY(-30px); }
}
@keyframes zorx-text-slide-down-loop {
  0%       { opacity: 0; transform: translateY(-30px); }
  16%, 84% { opacity: 1; transform: translateY(0); }
  100%     { opacity: 0; transform: translateY(30px); }
}
@keyframes zorx-typewriter-loop {
  0%       { max-width: 0; }
  16%, 84% { max-width: 100%; }
  100%     { max-width: 0; }
}
@keyframes zorx-text-wave {
  0%, 100% { transform: translateY(0); }
  50%      { transform: translateY(-5px); }
}
@keyframes zorx-text-pulse {
  0%, 100% { transform: scale(1);    opacity: 1; }
  50%      { transform: scale(1.06); opacity: 0.92; }
}
@keyframes zorx-text-float {
  0%, 100% { transform: translateY(0); opacity: 0.95; }
  50%      { transform: translateY(-4px); opacity: 1; }
}
@keyframes zorx-text-breathe {
  0%, 100% { transform: scale(1);     opacity: 0.85; }
  50%      { transform: scale(1.025); opacity: 1; }
}
@keyframes zorx-text-zoom-in-loop {
  0%       { opacity: 0; transform: scale(0); }
  16%, 84% { opacity: 1; transform: scale(1); }
  100%     { opacity: 0; transform: scale(0); }
}
@keyframes zorx-text-bounce-loop {
  0%       { opacity: 0; transform: translateY(-60px) scale(.8); }
  10%      { transform: translateY(0) scale(1.08); }
  16%, 84% { opacity: 1; transform: translateY(0) scale(1); }
  90%      { transform: translateY(-8px) scale(1.04); }
  100%     { opacity: 0; transform: translateY(60px) scale(.8); }
}
@keyframes zorx-text-flicker {
  0%, 18%, 22%, 25%, 53%, 57%, 100% {
    opacity: 1;
    text-shadow:
      0 0 4px currentColor,
      0 0 11px currentColor,
      0 0 19px currentColor;
  }
  20%, 24%, 55% { opacity: 0.2; text-shadow: none; }
}
@keyframes zorx-text-glitch {
  0%, 100% { transform: translate(0, 0); filter: none; }
  20%      { transform: translate(-2px, 1px); filter: hue-rotate(15deg) drop-shadow(2px 0 #ff2b6e) drop-shadow(-2px 0 #00ffae); }
  40%      { transform: translate(2px, -1px); filter: hue-rotate(-15deg) drop-shadow(-2px 0 #ff2b6e) drop-shadow(2px 0 #00ffae); }
  60%      { transform: translate(-1px, 2px); filter: none; }
  80%      { transform: translate(1px, -2px); filter: drop-shadow(2px 0 #00ffae) drop-shadow(-2px 0 #ff2b6e); }
}
@keyframes zorx-text-shake {
  0%, 100%           { opacity: 0; transform: translateX(0); }
  10%, 16%, 84%, 90% { opacity: 1; transform: translateX(0); }
  18%, 22%, 26%      { transform: translateX(-4px); }
  20%, 24%, 28%      { transform: translateX(4px); }
}

/* Smart alignment guides — drag-time snap visualization. */
/* Mirrors the dashed neon-green guide style used by Result Maker / MVP Poster Maker. */
.so-align-guide {
  position: absolute;
  pointer-events: none;
  z-index: 90;
}
.so-align-guide--x {
  width: 0;
  border-left: 2px dashed rgba(170, 255, 20, 0.92);
  box-shadow: 0 0 10px rgba(170, 255, 20, 0.55);
}
.so-align-guide--y {
  height: 0;
  border-top: 2px dashed rgba(170, 255, 20, 0.92);
  box-shadow: 0 0 10px rgba(170, 255, 20, 0.55);
}
