
/* =========================================================
   BLOCK 03 V4 SAFE
   Exact artwork stays exact. No black masks, no fake outlines.
   ========================================================= */

.story3v4 .story-exact-wrap{
  overflow:hidden;
}

/* Base image starts slightly dim, then returns to full strength. */
.story3v4 .story3-base{
  filter:brightness(.78) saturate(.92);
  transition:filter 1.45s cubic-bezier(.22,.61,.36,1);
}
.story3v4.s3-enter .story3-base{
  filter:brightness(1) saturate(1);
}

/* Same image, clipped to text regions, so reveals cannot create black boxes. */
.story3-fragment{
  position:absolute;
  inset:0;
  width:100%;
  height:100%;
  object-fit:fill;
  pointer-events:none;
  z-index:3;
  opacity:0;
  clip-path:inset(0);
  filter:brightness(1.08) saturate(1.02);
}

.frag-title{clip-path:inset(10.5% 60.5% 55.2% 4.7%)}
.frag-copy{clip-path:inset(44.8% 66.2% 38.0% 4.8%)}
.frag-top{clip-path:inset(4.8% 7.0% 61.0% 63.4%)}
.frag-left{clip-path:inset(57.5% 45.2% 13.0% 26.0%)}
.frag-right{clip-path:inset(59.0% 4.8% 12.0% 65.0%)}

.story3v4.s3-enter .frag-title{animation:s3FragReveal .78s cubic-bezier(.22,.61,.36,1) .08s forwards}
.story3v4.s3-enter .frag-copy{animation:s3FragReveal .72s cubic-bezier(.22,.61,.36,1) .34s forwards}
.story3v4.s3-enter .frag-top{animation:s3FragReveal .66s cubic-bezier(.22,.61,.36,1) .62s forwards}
.story3v4.s3-enter .frag-left{animation:s3FragReveal .66s cubic-bezier(.22,.61,.36,1) .82s forwards}
.story3v4.s3-enter .frag-right{animation:s3FragReveal .66s cubic-bezier(.22,.61,.36,1) 1.02s forwards}

@keyframes s3FragReveal{
  0%{opacity:0;filter:brightness(.72) saturate(.88)}
  35%{opacity:1}
  100%{opacity:1;filter:brightness(1.05) saturate(1)}
}

/* Precise travel dots */
.story3-svg{
  position:absolute;
  inset:0;
  z-index:5;
  width:100%;
  height:100%;
  pointer-events:none;
}
.s3-travel-dot{
  fill:#d9fdff;
  opacity:0;
  filter:drop-shadow(0 0 4px #8cf7ff)
         drop-shadow(0 0 10px rgba(57,224,255,.92));
}

/* Central portal pulse */
.s3-core-pulse{
  position:absolute;
  z-index:4;
  left:62.65%;
  top:49.15%;
  width:28.8%;
  aspect-ratio:1;
  transform:translate(-50%,-50%) scale(.93);
  border-radius:50%;
  border:1.5px solid rgba(105,243,255,.52);
  opacity:0;
  pointer-events:none;
  box-shadow:0 0 18px rgba(55,226,255,.18);
}
.story3v4.s3-live .core1{animation:s3Core 4.8s ease-out infinite}
.story3v4.s3-live .core2{animation:s3Core 4.8s ease-out 2.4s infinite}
@keyframes s3Core{
  0%{opacity:0;transform:translate(-50%,-50%) scale(.93)}
  10%{opacity:.52}
  44%{opacity:.10}
  60%{opacity:0;transform:translate(-50%,-50%) scale(1.08)}
  100%{opacity:0;transform:translate(-50%,-50%) scale(1.08)}
}

/* Small node pulses centered exactly on baked circles */
.s3-node-pulse{
  position:absolute;
  z-index:6;
  width:7.4%;
  aspect-ratio:1;
  transform:translate(-50%,-50%) scale(.96);
  border-radius:50%;
  border:1.5px solid rgba(120,247,255,.70);
  opacity:0;
  pointer-events:none;
  box-shadow:0 0 12px rgba(69,231,255,.24);
}
.s3-node-pulse.top{left:60.65%;top:11.15%}
.s3-node-pulse.left{left:35.45%;top:58.95%}
.s3-node-pulse.right{left:84.82%;top:58.70%}

.story3v4.s3-live .s3-node-pulse.top.p1{animation:s3NodeTop 4.8s ease-out infinite}
.story3v4.s3-live .s3-node-pulse.top.p2{animation:s3NodeTop 4.8s ease-out .24s infinite}
.story3v4.s3-live .s3-node-pulse.left.p1{animation:s3NodeLeft 4.8s ease-out .32s infinite}
.story3v4.s3-live .s3-node-pulse.left.p2{animation:s3NodeLeft 4.8s ease-out .56s infinite}
.story3v4.s3-live .s3-node-pulse.right.p1{animation:s3NodeRight 4.8s ease-out .64s infinite}
.story3v4.s3-live .s3-node-pulse.right.p2{animation:s3NodeRight 4.8s ease-out .88s infinite}

@keyframes s3NodeTop{
  0%,29%,100%{opacity:0;transform:translate(-50%,-50%) scale(.96)}
  32%{opacity:.72}
  43%{opacity:0;transform:translate(-50%,-50%) scale(1.34)}
}
@keyframes s3NodeLeft{
  0%,34%,100%{opacity:0;transform:translate(-50%,-50%) scale(.96)}
  37%{opacity:.72}
  48%{opacity:0;transform:translate(-50%,-50%) scale(1.34)}
}
@keyframes s3NodeRight{
  0%,39%,100%{opacity:0;transform:translate(-50%,-50%) scale(.96)}
  42%{opacity:.72}
  53%{opacity:0;transform:translate(-50%,-50%) scale(1.34)}
}

/* Soft panel illumination, no visible geometric frame */
.s3-panel-bloom{
  position:absolute;
  z-index:4;
  pointer-events:none;
  opacity:0;
  mix-blend-mode:screen;
  filter:blur(13px);
  background:radial-gradient(ellipse at center,
    rgba(76,235,255,.23) 0%,
    rgba(53,203,255,.11) 38%,
    transparent 72%);
}
.bloom-top{left:63.5%;top:4.8%;width:31.5%;height:35.5%}
.bloom-left{left:26.0%;top:57.0%;width:29%;height:29%}
.bloom-right{left:65.0%;top:59.0%;width:30%;height:29%}

.story3v4.s3-live .bloom-top{animation:s3BloomTop 4.8s ease-in-out infinite}
.story3v4.s3-live .bloom-left{animation:s3BloomLeft 4.8s ease-in-out .32s infinite}
.story3v4.s3-live .bloom-right{animation:s3BloomRight 4.8s ease-in-out .64s infinite}

@keyframes s3BloomTop{
  0%,30%,100%{opacity:0}
  33%,39%{opacity:.78}
  47%{opacity:0}
}
@keyframes s3BloomLeft{
  0%,35%,100%{opacity:0}
  38%,44%{opacity:.78}
  52%{opacity:0}
}
@keyframes s3BloomRight{
  0%,40%,100%{opacity:0}
  43%,49%{opacity:.78}
  57%{opacity:0}
}

/* Button hitbox aligned to the actual baked button */
.story3v4 .s3-button-hit{
  left:5.70% !important;
  top:62.60% !important;
  width:16.20% !important;
  height:6.45% !important;
  border-radius:12px !important;
  outline:none !important;
  overflow:hidden !important;
  box-shadow:none !important;
  background:transparent !important;
  z-index:8;
}
.story3v4 .s3-button-hit::before{
  content:"";
  position:absolute;
  inset:0;
  border-radius:inherit;
  opacity:0;
  background:rgba(218,254,255,.10);
  box-shadow:inset 0 1px 0 rgba(255,255,255,.25),
             inset 0 -1px 0 rgba(255,255,255,.05);
  transition:opacity .16s ease;
}
.story3v4 .s3-button-hit::after{
  content:"";
  position:absolute;
  top:-70%;
  left:-50%;
  width:28%;
  height:240%;
  opacity:0;
  transform:rotate(17deg);
  background:linear-gradient(90deg,
    transparent,
    rgba(255,255,255,.12),
    rgba(255,255,255,.72),
    rgba(255,255,255,.12),
    transparent);
}
.story3v4 .s3-button-hit:hover,
.story3v4 .s3-button-hit:focus-visible{
  transform:scale(1.016);
  filter:brightness(1.05);
  box-shadow:0 0 16px rgba(54,226,255,.19) !important;
}
.story3v4 .s3-button-hit:hover::before,
.story3v4 .s3-button-hit:focus-visible::before{opacity:1}
.story3v4 .s3-button-hit:hover::after,
.story3v4 .s3-button-hit:focus-visible::after{
  animation:s3BtnWave .76s cubic-bezier(.22,.61,.36,1) 1 both;
}
@keyframes s3BtnWave{
  0%{left:-50%;opacity:0}
  16%{opacity:.82}
  100%{left:125%;opacity:0}
}

/* Exact overlay is desktop/tablet only */
@media(max-width:700px){
  .story3-fragment,
  .story3-svg,
  .s3-core-pulse,
  .s3-node-pulse,
  .s3-panel-bloom{display:none!important}
  .story3v4 .story3-base{filter:none!important}
}
@media(prefers-reduced-motion:reduce){
  .story3-fragment,
  .story3-svg,
  .s3-core-pulse,
  .s3-node-pulse,
  .s3-panel-bloom{display:none!important}
  .story3v4 .story3-base{filter:none!important}
  .story3v4 .s3-button-hit:hover,
  .story3v4 .s3-button-hit:focus-visible{transform:none}
}


/* =========================================================
   BLOCK 03 V5 — PULSE POSITION + TIMING SYNC
   Only fixes:
   1) node waves start exactly from baked circles
   2) signal reaches node BEFORE panel glow
   3) central portal pulse is visibly readable
   ========================================================= */

/* --- Small circle calibration against 1672×941 exact artwork --- */
.s3-node-pulse{
  width:6.95% !important;
  border-width:1.7px !important;
  box-shadow:
    0 0 10px rgba(69,231,255,.22),
    0 0 22px rgba(57,219,255,.12) !important;
}

/* Exact visual centers of the three baked circles */
.s3-node-pulse.top{
  left:61.36% !important;
  top:11.02% !important;
}
.s3-node-pulse.left{
  left:35.41% !important;
  top:59.08% !important;
}
.s3-node-pulse.right{
  left:84.81% !important;
  top:59.62% !important;
}

/* One 5.2s timeline.
   Dot arrives first -> circle emits wave -> panel glows after. */
.story3v4.s3-live .s3-node-pulse.top.p1{
  animation:s3NodeTopV5 5.2s ease-out infinite !important;
}
.story3v4.s3-live .s3-node-pulse.top.p2{
  animation:s3NodeTopV5 5.2s ease-out .18s infinite !important;
}
.story3v4.s3-live .s3-node-pulse.left.p1{
  animation:s3NodeLeftV5 5.2s ease-out infinite !important;
}
.story3v4.s3-live .s3-node-pulse.left.p2{
  animation:s3NodeLeftV5 5.2s ease-out .18s infinite !important;
}
.story3v4.s3-live .s3-node-pulse.right.p1{
  animation:s3NodeRightV5 5.2s ease-out infinite !important;
}
.story3v4.s3-live .s3-node-pulse.right.p2{
  animation:s3NodeRightV5 5.2s ease-out .18s infinite !important;
}

/* Top signal arrives around 34% */
@keyframes s3NodeTopV5{
  0%,33.5%,100%{opacity:0;transform:translate(-50%,-50%) scale(.98)}
  35%{opacity:.82;transform:translate(-50%,-50%) scale(1)}
  42%{opacity:.30;transform:translate(-50%,-50%) scale(1.22)}
  47%{opacity:0;transform:translate(-50%,-50%) scale(1.38)}
}
/* Left signal arrives later */
@keyframes s3NodeLeftV5{
  0%,39.5%,100%{opacity:0;transform:translate(-50%,-50%) scale(.98)}
  41%{opacity:.82;transform:translate(-50%,-50%) scale(1)}
  48%{opacity:.30;transform:translate(-50%,-50%) scale(1.22)}
  53%{opacity:0;transform:translate(-50%,-50%) scale(1.38)}
}
/* Right signal arrives last */
@keyframes s3NodeRightV5{
  0%,45.5%,100%{opacity:0;transform:translate(-50%,-50%) scale(.98)}
  47%{opacity:.82;transform:translate(-50%,-50%) scale(1)}
  54%{opacity:.30;transform:translate(-50%,-50%) scale(1.22)}
  59%{opacity:0;transform:translate(-50%,-50%) scale(1.38)}
}

/* Panel glow deliberately starts AFTER node wave is visible */
.story3v4.s3-live .bloom-top{
  animation:s3BloomTopV5 5.2s ease-in-out infinite !important;
}
.story3v4.s3-live .bloom-left{
  animation:s3BloomLeftV5 5.2s ease-in-out infinite !important;
}
.story3v4.s3-live .bloom-right{
  animation:s3BloomRightV5 5.2s ease-in-out infinite !important;
}

@keyframes s3BloomTopV5{
  0%,40%,100%{opacity:0}
  43%,49%{opacity:.72}
  56%{opacity:0}
}
@keyframes s3BloomLeftV5{
  0%,46%,100%{opacity:0}
  49%,55%{opacity:.72}
  62%{opacity:0}
}
@keyframes s3BloomRightV5{
  0%,52%,100%{opacity:0}
  55%,61%{opacity:.72}
  68%{opacity:0}
}

/* Central portal: stronger and easier to read against the bright artwork */
.s3-core-pulse{
  left:61.66% !important;
  top:48.65% !important;
  width:31.0% !important;
  border:2.3px solid rgba(141,250,255,.72) !important;
  box-shadow:
    0 0 10px rgba(111,244,255,.40),
    0 0 28px rgba(56,226,255,.28),
    0 0 52px rgba(37,176,255,.16),
    inset 0 0 22px rgba(106,241,255,.08) !important;
  mix-blend-mode:screen;
}

.story3v4.s3-live .core1{
  animation:s3CoreV5 5.2s cubic-bezier(.22,.61,.36,1) infinite !important;
}
.story3v4.s3-live .core2{
  animation:s3CoreV5 5.2s cubic-bezier(.22,.61,.36,1) 2.6s infinite !important;
}

@keyframes s3CoreV5{
  0%{
    opacity:0;
    transform:translate(-50%,-50%) scale(.985);
  }
  9%{
    opacity:.74;
  }
  22%{
    opacity:.48;
    transform:translate(-50%,-50%) scale(1.035);
  }
  42%{
    opacity:.16;
    transform:translate(-50%,-50%) scale(1.10);
  }
  58%,100%{
    opacity:0;
    transform:translate(-50%,-50%) scale(1.16);
  }
}

/* Make the travel dots slightly brighter so their arrival is obvious */
.s3-travel-dot{
  r:7;
  filter:
    drop-shadow(0 0 5px #d8feff)
    drop-shadow(0 0 12px rgba(81,235,255,.96))
    drop-shadow(0 0 20px rgba(44,190,255,.58)) !important;
}


/* =========================================================
   BLOCK 03 V6 — CENTER CALIBRATION + TEXT ENTRANCE
   Exact artwork remains unchanged.
   ========================================================= */

/* ---------- Exact pulse centers calibrated from the source artwork ---------- */

/* Central portal outer circle:
   detected center ~1039×460 on the 1672×941 source. */
.s3-core-pulse{
  left:62.14% !important;
  top:48.91% !important;
  width:26.48% !important;
  border-width:2px !important;
  border-color:rgba(151,251,255,.82) !important;
  box-shadow:
    0 0 10px rgba(150,250,255,.44),
    0 0 28px rgba(64,232,255,.34),
    0 0 48px rgba(42,186,255,.16),
    inset 0 0 20px rgba(110,243,255,.07) !important;
}

/* Stronger pulse that visibly starts ON the portal ring itself. */
.story3v4.s3-live .core1{
  animation:s3CoreV6 5.2s cubic-bezier(.22,.61,.36,1) infinite !important;
}
.story3v4.s3-live .core2{
  animation:s3CoreV6 5.2s cubic-bezier(.22,.61,.36,1) 2.6s infinite !important;
}
@keyframes s3CoreV6{
  0%{
    opacity:0;
    transform:translate(-50%,-50%) scale(.995);
  }
  8%{
    opacity:.82;
  }
  24%{
    opacity:.52;
    transform:translate(-50%,-50%) scale(1.035);
  }
  43%{
    opacity:.16;
    transform:translate(-50%,-50%) scale(1.095);
  }
  58%,100%{
    opacity:0;
    transform:translate(-50%,-50%) scale(1.145);
  }
}

/* Small baked-circle centers, calibrated separately. */
.s3-node-pulse{
  width:6.55% !important;
}
.s3-node-pulse.top{
  left:61.57% !important;
  top:11.37% !important;
}
.s3-node-pulse.left{
  left:35.92% !important;
  top:59.79% !important;
}
.s3-node-pulse.right{
  left:86.04% !important;
  top:60.81% !important;
}

/* Waves visibly originate from the icon ring, not beside it. */
@keyframes s3NodeTopV6{
  0%,33.5%,100%{opacity:0;transform:translate(-50%,-50%) scale(.98)}
  35%{opacity:.82;transform:translate(-50%,-50%) scale(1)}
  41%{opacity:.42;transform:translate(-50%,-50%) scale(1.18)}
  47%{opacity:0;transform:translate(-50%,-50%) scale(1.42)}
}
@keyframes s3NodeLeftV6{
  0%,39.5%,100%{opacity:0;transform:translate(-50%,-50%) scale(.98)}
  41%{opacity:.82;transform:translate(-50%,-50%) scale(1)}
  47%{opacity:.42;transform:translate(-50%,-50%) scale(1.18)}
  53%{opacity:0;transform:translate(-50%,-50%) scale(1.42)}
}
@keyframes s3NodeRightV6{
  0%,45.5%,100%{opacity:0;transform:translate(-50%,-50%) scale(.98)}
  47%{opacity:.82;transform:translate(-50%,-50%) scale(1)}
  53%{opacity:.42;transform:translate(-50%,-50%) scale(1.18)}
  59%{opacity:0;transform:translate(-50%,-50%) scale(1.42)}
}

.story3v4.s3-live .s3-node-pulse.top.p1{
  animation:s3NodeTopV6 5.2s ease-out infinite !important;
}
.story3v4.s3-live .s3-node-pulse.top.p2{
  animation:s3NodeTopV6 5.2s ease-out .18s infinite !important;
}
.story3v4.s3-live .s3-node-pulse.left.p1{
  animation:s3NodeLeftV6 5.2s ease-out infinite !important;
}
.story3v4.s3-live .s3-node-pulse.left.p2{
  animation:s3NodeLeftV6 5.2s ease-out .18s infinite !important;
}
.story3v4.s3-live .s3-node-pulse.right.p1{
  animation:s3NodeRightV6 5.2s ease-out infinite !important;
}
.story3v4.s3-live .s3-node-pulse.right.p2{
  animation:s3NodeRightV6 5.2s ease-out .18s infinite !important;
}

/* ---------- Heading entrance ----------
   No rectangular black mask. A feathered veil dims the whole left text zone,
   while the exact same image fragment gently zooms into place. */
.s3-title-veil{
  position:absolute;
  z-index:2;
  left:2.5%;
  top:7%;
  width:39%;
  height:56%;
  pointer-events:none;
  opacity:.92;
  background:
    linear-gradient(90deg,
      rgba(1,10,18,.98) 0%,
      rgba(2,13,23,.94) 66%,
      rgba(2,13,23,.68) 82%,
      transparent 100%);
  -webkit-mask-image:linear-gradient(180deg,transparent 0%,#000 8%,#000 91%,transparent 100%);
  mask-image:linear-gradient(180deg,transparent 0%,#000 8%,#000 91%,transparent 100%);
}

/* Title fragment: reveal by depth, not by a harsh wipe. */
.frag-title{
  transform-origin:22% 29%;
  transform:scale(.90);
  filter:blur(6px) brightness(.92) saturate(.92) !important;
  opacity:0 !important;
}
.story3v4.s3-enter .frag-title{
  animation:s3TitleDepth 1.05s cubic-bezier(.16,.78,.26,1) .16s forwards !important;
}

/* Copy follows more calmly. */
.frag-copy{
  transform:translateY(10px);
  filter:blur(3px) brightness(.94) !important;
  opacity:0 !important;
}
.story3v4.s3-enter .frag-copy{
  animation:s3CopyIn .72s cubic-bezier(.22,.61,.36,1) .62s forwards !important;
}

/* Fade the feathered veil only after title begins appearing. */
.story3v4.s3-enter .s3-title-veil{
  animation:s3VeilAway 1.10s cubic-bezier(.22,.61,.36,1) .14s forwards;
}

@keyframes s3TitleDepth{
  0%{
    opacity:0;
    transform:scale(.90);
    filter:blur(6px) brightness(.90) saturate(.90);
  }
  32%{opacity:.45}
  100%{
    opacity:1;
    transform:scale(1);
    filter:blur(0) brightness(1.04) saturate(1);
  }
}
@keyframes s3CopyIn{
  0%{
    opacity:0;
    transform:translateY(10px);
    filter:blur(3px) brightness(.94);
  }
  100%{
    opacity:1;
    transform:translateY(0);
    filter:blur(0) brightness(1.02);
  }
}
@keyframes s3VeilAway{
  0%{opacity:.92}
  100%{opacity:0}
}

/* The three callout text fragments keep their existing subtle reveal. */
.frag-top,
.frag-left,
.frag-right{
  transform:none !important;
}

/* Accessibility */
@media(prefers-reduced-motion:reduce){
  .s3-title-veil{display:none!important}
  .frag-title,
  .frag-copy{
    opacity:1!important;
    transform:none!important;
    filter:none!important;
    animation:none!important;
  }
}
