/* c2-lattice LOAD MOMENT (~3 s, once per load in the concept): a dark stage, one beam of white light strikes the
   glass, the glass splits it into the spectrum, and the light opens the page from the glass outward while the slabs
   assemble, the headline comes into focus, the pair appears and answers, and the lattice crystallizes in the glass.
   Only under html.intro (set in <head>: motion allowed, no splash, no ?nointro=1). Reduced motion never sees it. */
:root { --ix: 72vw; --iy: 48vh; --ia: 17deg; }
@property --hole { syntax: "<length>"; inherits: false; initial-value: -2000px; }

.intro-veil, .intro-light { display: none; }
.intro .intro-veil, .intro .intro-light { display: block; position: fixed; inset: 0; pointer-events: none; }
.intro .intro-veil {
  z-index: 90;
  background: radial-gradient(110% 90% at var(--ix) var(--iy), #1B2029 0%, #0C0E12 62%, #08090B 100%);
  -webkit-mask-image: radial-gradient(circle at var(--ix) var(--iy), transparent var(--hole), #000 calc(var(--hole) + 16vmax));
          mask-image: radial-gradient(circle at var(--ix) var(--iy), transparent var(--hole), #000 calc(var(--hole) + 16vmax));
  animation: veil-open 1.25s .82s cubic-bezier(.55, 0, .2, 1) both;
}
@keyframes veil-open { from { --hole: -20vmax; } 80% { opacity: 1; } to { --hole: 175vmax; opacity: 0; } }
.intro .intro-light { z-index: 95; overflow: hidden; }

/* the beam: grows from off-screen toward the impact point */
.beam-wrap { position: absolute; right: calc(100% - var(--ix)); top: var(--iy); width: 160vmax; height: 3px; margin-top: -1.5px; transform-origin: 100% 50%; transform: rotate(var(--ia)); }
.beam { display: block; width: 100%; height: 100%; border-radius: 3px; transform-origin: 0 50%;
  background: linear-gradient(90deg, rgba(255, 255, 255, 0), rgba(255, 255, 255, .55) 55%, #fff 92%, #fff);
  box-shadow: 0 0 10px 2px rgba(255, 255, 255, .85), 0 0 34px 8px rgba(198, 181, 246, 0.22);
  animation: beam 1.15s .12s cubic-bezier(.7, 0, .25, 1) both; }
@keyframes beam { 0% { transform: scaleX(0); opacity: 1; } 52% { transform: scaleX(1); opacity: 1; } 100% { transform: scaleX(1); opacity: 0; } }

/* impact: a white bloom, a spectral shock ring, and the dispersion fan out the far side of the glass */
.flash, .ring { position: absolute; left: var(--ix); top: var(--iy); width: 44vmax; height: 44vmax; margin: -22vmax 0 0 -22vmax; border-radius: 50%; }
.flash { background: radial-gradient(circle, #fff 0, rgba(255, 255, 255, .85) 12%, rgba(198, 181, 246, 0.2) 34%, rgba(160, 223, 242, 0.07) 48%, transparent 62%);
  animation: flash 1.1s .66s cubic-bezier(.2, .7, .2, 1) both; }
@keyframes flash { 0% { transform: scale(.15); opacity: 0; } 18% { opacity: 1; } 100% { transform: scale(1.7); opacity: 0; } }
.ring { background: conic-gradient(#7FD6F2, #B49CF8, #EBB3CF, #B49CF8, #7FD6F2);
  -webkit-mask: radial-gradient(circle, transparent 66%, #000 67.5%, #000 69%, transparent 70.5%);
          mask: radial-gradient(circle, transparent 66%, #000 67.5%, #000 69%, transparent 70.5%);
  animation: ring 1.3s .7s cubic-bezier(.15, .6, .2, 1) both; }
@keyframes ring { 0% { transform: scale(.08) rotate(0deg); opacity: 0; } 12% { opacity: 1; } 100% { transform: scale(3.2) rotate(120deg); opacity: 0; } }
.fan { position: absolute; left: var(--ix); top: calc(var(--iy) - 70vmax); width: 140vmax; height: 140vmax; transform-origin: 0 50%;
  background: conic-gradient(from 0deg at 0% 50%, transparent 0deg 99deg, rgba(116, 206, 234, 0) 99deg, rgba(116, 206, 234, 0.65) 102.5deg,
    rgba(176, 151, 243, 0.65) 106.5deg, rgba(231, 161, 197, 0.65) 110.5deg, rgba(245, 203, 218, 0.65) 114.5deg, rgba(175, 226, 242, 0.5) 118deg,
    rgba(175, 226, 242, 0) 121deg, transparent 121deg 360deg);
  -webkit-mask-image: radial-gradient(circle at 0% 50%, #000 0, #000 22%, transparent 64%);
          mask-image: radial-gradient(circle at 0% 50%, #000 0, #000 22%, transparent 64%);
  filter: blur(1.5px); animation: fan 1.9s .7s cubic-bezier(.2, .8, .2, 1) both; }
@keyframes fan { 0% { transform: scaleX(0) scaleY(.4); opacity: 0; } 14% { opacity: 1; } 55% { transform: scaleX(1) scaleY(1); opacity: .95; } 100% { transform: scaleX(1.06) scaleY(1); opacity: 0; } }

/* the glass assembles where the light landed */
.intro .slab-1 { --rest: translateZ(-120px) rotate(-6deg); --from: translate3d(-20vw, -16vh, -760px) rotate(-30deg) rotateX(38deg); }
.intro .slab-2 { --rest: translateZ(-60px) rotate(5deg); --from: translate3d(24vw, 18vh, -640px) rotate(26deg) rotateY(-34deg); }
.intro .slab-3 { --rest: translateZ(0); --from: translate3d(0, 8vh, -980px) rotateX(52deg) rotate(-10deg); }
.intro .slab { animation: slab-in 1.25s cubic-bezier(.22, 1.22, .36, 1) both; }
.intro .slab-3 { animation-delay: .74s; }
.intro .slab-1 { animation-delay: .86s; }
.intro .slab-2 { animation-delay: .98s; }
@keyframes slab-in { from { transform: var(--from); opacity: 0; } 40% { opacity: 1; } to { transform: var(--rest); opacity: 1; } }

/* headline comes into focus as the light reaches it (visible, never opacity 0, so it still counts for LCP) */
.intro .hero-copy > * { animation: copy-in .95s cubic-bezier(.2, .8, .2, 1) both !important; }
.intro .hero-copy > .eyebrow { animation-delay: 1.02s !important; }
.intro .hero-copy > h1 { animation-name: h1-in !important; animation-duration: 1.2s !important; animation-delay: 1.0s !important; }
.intro .hero-copy > .lede { animation-delay: 1.22s !important; }
.intro .hero-copy > .cta-row { animation-delay: 1.34s !important; }
.intro .hero-copy > .explore { animation-delay: 1.46s !important; }
@keyframes copy-in { from { opacity: .04; transform: translateY(18px); filter: blur(6px); } }
@keyframes h1-in { from { opacity: .04; transform: translateY(26px) scale(.985); filter: blur(14px); } 60% { filter: blur(0); } }
.intro .hero h1 em {
  background: linear-gradient(100deg, var(--ink) 0 40%, #74CEEA 46%, #B097F3 50%, #E7A1C5 54%, #F5CBDA 57%, var(--ink) 62% 100%);
  background-size: 260% 100%; background-position: 100% 0; -webkit-background-clip: text; background-clip: text; color: transparent;
  animation: em-sheen 1.5s 1.75s cubic-bezier(.45, 0, .2, 1) both; }
@keyframes em-sheen { from { background-position: 100% 0; } to { background-position: 0% 0; } }

/* the pair appears, the thread draws itself, then one particle is touched and the other answers */
.intro .stack .particle .orb { animation: orb-pop .85s cubic-bezier(.34, 1.56, .64, 1) both; }
.intro .stack .p-a .orb { animation-delay: 1.5s; }
.intro .stack .p-b .orb { animation-delay: 1.66s; }
@keyframes orb-pop { from { transform: scale(0); } }
.intro .stack .p-label, .intro .stack .p-sub, .intro .stack .hint { animation: copy-in .8s cubic-bezier(.2, .8, .2, 1) both; }
.intro .stack .p-a .p-label { animation-delay: 1.62s; } .intro .stack .p-a .p-sub { animation-delay: 1.7s; }
.intro .stack .p-b .p-label { animation-delay: 1.78s; } .intro .stack .p-b .p-sub { animation-delay: 1.86s; }
.intro .stack .hint { animation-delay: 2.2s; }
/* the thread uses non-scaling strokes, so dash lengths are screen pixels: dash longer than any on-screen thread */
.intro .stack .thread-base { animation: draw 1s 1.7s cubic-bezier(.6, 0, .2, 1) both; }
@keyframes draw { from { stroke-dasharray: 1600; stroke-dashoffset: 1600; } to { stroke-dasharray: 1600; stroke-dashoffset: 0; } }

/* header arrives last */
.intro .site-header { animation: head-in .8s 1.6s cubic-bezier(.2, .8, .2, 1) both; }
@keyframes head-in { from { transform: translateY(-100%); opacity: 0; } }

/* done: hand every element back to c2's own rules (so hover, tilt and the path split work again) */
.intro-done .intro-veil, .intro-done .intro-light { display: none !important; }
.intro-done .slab, .intro-done .hero-copy > *, .intro-done .stack .particle .orb, .intro-done .stack .p-label,
.intro-done .stack .p-sub, .intro-done .stack .hint, .intro-done .stack .thread-base, .intro-done .site-header,
.intro-done .hero h1 em { animation: none !important; }
.intro-done .hero h1 em { background: none; color: inherit; }
