/* ============================================================
   LUFLY - First-entry brand intro
   The real logo image (images/logo.png, true teal ink) painted
   in large by a travelling pen of light: seed glow -> reveal
   sweep -> glass reflection -> seal of light -> the whole
   stage lifts like a curtain. Shown only when <html> carries
   .has-intro (set pre-paint by the gate script on the home
   page). Ambient tokens mirror loader.css.
   ============================================================ */

:root {
  --in-mint: var(--lu-mint, #7fe2d0);
  --in-teal: var(--lu-teal-500, #1c8b8b);
  --in-ease: cubic-bezier(.19, 1, .22, 1);
  --in-curtain: cubic-bezier(.76, 0, .24, 1);
  --in-paint: cubic-bezier(.65, .02, .23, 1);
}

/* hidden unless the gate script decided this visit gets the intro;
   no JavaScript = no intro, the page is simply there */
.intro {
  display: none;
}

html.has-intro .intro {
  display: flex;
}

/* hold the page still while the stage is up */
html.has-intro {
  overflow: hidden;
  animation: inRestoreScroll 0s linear 6.9s forwards;
}

@keyframes inRestoreScroll {
  to { overflow: visible; }
}

/* ---------------- the stage ---------------- */

.intro {
  position: fixed;
  inset: 0;
  z-index: 100000; /* above the classic loader (99999) while both exist */
  align-items: center;
  justify-content: center;
  overflow: hidden;
  background:
    radial-gradient(120% 90% at 50% 40%, #0b2f2b 0%, #06211e 44%, #030c0b 100%);
  will-change: transform;
  animation:
    inCurtain .95s var(--in-curtain) 2.55s forwards,
    inFailsafe .4s ease 6.5s forwards;
}

@keyframes inCurtain {
  0% { transform: translateY(0); }
  100% { transform: translateY(-101%); visibility: hidden; }
}

/* last-resort safety net: whatever happens, the stage lets go */
@keyframes inFailsafe {
  to { opacity: 0; visibility: hidden; pointer-events: none; }
}

/* glowing curtain edge, lit as the stage lifts (loader language) */
.intro::after {
  content: "";
  position: absolute;
  left: 0;
  right: 0;
  bottom: -3px;
  height: 3px;
  background: linear-gradient(90deg, transparent, var(--in-mint), transparent);
  box-shadow: 0 0 60px 12px color-mix(in srgb, var(--in-mint) 45%, transparent);
  opacity: 0;
  animation: inEdge .45s ease 2.5s forwards;
}

@keyframes inEdge {
  to { opacity: 1; }
}

/* click / Esc skip: JS drops the keyframe timeline and lifts now */
.intro.is-leaving {
  animation: none;
  transition: transform .65s var(--in-curtain);
  transform: translateY(-101%);
}

/* ---------------- atmosphere: aura + rising motes ---------------- */

.intro-aura {
  position: absolute;
  left: 50%;
  top: 44%;
  width: 92vmin;
  height: 92vmin;
  margin: -46vmin 0 0 -46vmin;
  border-radius: 50%;
  background: radial-gradient(circle,
    color-mix(in srgb, var(--in-mint) 30%, transparent) 0%,
    color-mix(in srgb, var(--in-teal) 15%, transparent) 42%,
    transparent 68%);
  filter: blur(6px);
  opacity: 0;
  animation: inAura 3.5s ease both;
  pointer-events: none;
}

@keyframes inAura {
  0% { opacity: 0; transform: scale(.72); }
  38% { opacity: .95; transform: scale(1); }
  72% { opacity: .8; transform: scale(1.06); }
  100% { opacity: .65; transform: scale(1.1); }
}

.intro-motes {
  position: absolute;
  inset: 0;
  pointer-events: none;
}

.intro-motes i {
  position: absolute;
  left: var(--x);
  bottom: -12px;
  width: var(--s);
  height: var(--s);
  border-radius: 50%;
  background: var(--in-mint);
  box-shadow: 0 0 10px 2px color-mix(in srgb, var(--in-mint) 55%, transparent);
  opacity: 0;
  animation: inRise 3.4s linear var(--d) both;
}

@keyframes inRise {
  0% { transform: translate(0, 0) scale(1); opacity: 0; }
  12% { opacity: .85; }
  70% { opacity: .5; }
  100% { transform: translate(var(--drift), -88vh) scale(.35); opacity: 0; }
}

/* ---------------- the logo: big, painted in, reflected ---------------- */

.intro-logoBox {
  position: relative;
  z-index: 3;
  width: min(640px, 84vw); /* the artwork is 510px wide; stay near-crisp */
  aspect-ratio: 510 / 325;
  transform-origin: center center;
  flex-shrink: 0;
  animation: inLogoLife 3.5s var(--in-ease) both;
}

/* dreamy arrival (blur clears, settles) -> seal of light -> gentle
   parallax exit while the curtain lifts around it */
@keyframes inLogoLife {
  0% {
    transform: scale(.94) translateY(14px);
    filter: blur(10px) drop-shadow(0 0 0 transparent);
  }
  28% {
    transform: scale(1) translateY(0);
    filter: blur(0) drop-shadow(0 0 0 transparent);
  }
  60% {
    filter: blur(0) drop-shadow(0 0 30px color-mix(in srgb, var(--in-mint) 55%, transparent));
  }
  72% {
    filter: blur(0) drop-shadow(0 0 10px color-mix(in srgb, var(--in-mint) 28%, transparent));
  }
  100% {
    transform: scale(.985) translateY(-5vh);
    filter: blur(0) drop-shadow(0 0 14px color-mix(in srgb, var(--in-mint) 32%, transparent));
  }
}

/* a band of light sweeps the finished logo before the curtain */
.intro-logoBox::after {
  content: "";
  position: absolute;
  inset: -12% -18%;
  background: linear-gradient(100deg,
    transparent 42%,
    rgba(255, 255, 255, .16) 50%,
    transparent 58%);
  mix-blend-mode: screen;
  transform: translateX(-85%) skewX(-8deg);
  opacity: 0;
  animation: inSweep .9s ease 2.02s both;
  pointer-events: none;
  z-index: 5;
}

@keyframes inSweep {
  0% { transform: translateX(-85%) skewX(-8deg); opacity: 0; }
  18% { opacity: 1; }
  82% { opacity: 1; }
  100% { transform: translateX(85%) skewX(-8deg); opacity: 0; }
}

/* the logo image itself, painted in left-to-right by a moving clip edge —
   slight overshoot past the box so antialiased edges are never shaved */
.intro-logo {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  display: block;
  clip-path: inset(0 101% 0 0);
  animation: inReveal 1.55s var(--in-paint) .3s both;
  will-change: clip-path;
  -webkit-user-drag: none;
  user-select: none;
}

@keyframes inReveal {
  0% { clip-path: inset(0 101% 0 0); }
  100% { clip-path: inset(0 -1% 0 0); }
}

/* the pen of light riding the reveal edge, in sync with inReveal */
.intro-pen {
  position: absolute;
  top: -5%;
  height: 110%;
  left: 0;
  width: 3px;
  border-radius: 2px;
  background: linear-gradient(to bottom,
    transparent 0%,
    var(--in-mint) 36%,
    #eafffa 50%,
    var(--in-mint) 64%,
    transparent 100%);
  box-shadow: 0 0 18px 4px color-mix(in srgb, var(--in-mint) 55%, transparent);
  opacity: 0;
  animation: inPen 1.55s var(--in-paint) .3s both;
  pointer-events: none;
  z-index: 4;
}

@keyframes inPen {
  0% { left: 0; opacity: 0; }
  7% { opacity: 1; }
  93% { opacity: 1; }
  100% { left: calc(100% - 3px); opacity: 0; }
}

/* seed dot: the spark the logo is born from */
.intro-seed {
  position: absolute;
  left: 50%;
  top: 50%;
  width: 12px;
  height: 12px;
  margin: -6px 0 0 -6px;
  border-radius: 50%;
  background: var(--in-mint);
  box-shadow: 0 0 26px 8px color-mix(in srgb, var(--in-mint) 55%, transparent);
  animation: inSeed 1.1s ease .05s both;
  z-index: 2;
}

@keyframes inSeed {
  0% { opacity: 0; transform: scale(.4); }
  20% { opacity: 1; transform: scale(1); }
  55% { opacity: .9; transform: scale(1.35); }
  100% { opacity: 0; transform: scale(2.6); }
}

/* glass-floor reflection: the same image, mirrored under a hairline of
   light. The mask is written in the pre-flip direction on purpose — the
   scaleY(-1) flip turns "strong at local bottom" into "strong at the
   floor line, fading downward" on screen. */
.intro-floor {
  position: absolute;
  top: calc(100% + 5px);
  left: 8%;
  right: 8%;
  height: 1px;
  background: linear-gradient(90deg,
    transparent,
    color-mix(in srgb, var(--in-mint) 62%, transparent),
    transparent);
  opacity: 0;
  animation: inReflectIn .9s ease 1.82s both;
  pointer-events: none;
  z-index: 1;
}

.intro-reflect {
  position: absolute;
  top: calc(100% + 6px);
  left: 0;
  width: 100%;
  height: 100%;
  transform: scaleY(-1);
  filter: blur(1.4px);
  opacity: 0;
  animation: inReflectIn 1s ease 1.88s both;
  pointer-events: none;
  z-index: 1;
  -webkit-mask-image: linear-gradient(to top, rgba(0, 0, 0, .95) 4%, rgba(0, 0, 0, .3) 34%, transparent 50%);
  mask-image: linear-gradient(to top, rgba(0, 0, 0, .95) 4%, rgba(0, 0, 0, .3) 34%, transparent 50%);
}

.intro-reflect img {
  display: block;
  width: 100%;
  height: 100%;
  -webkit-user-drag: none;
  user-select: none;
}

@keyframes inReflectIn {
  from { opacity: 0; }
  to { opacity: .3; }
}

/* ---------------- reduced motion: never ---------------- */

@media (prefers-reduced-motion: reduce) {
  .intro { display: none !important; }
  html.has-intro { overflow: visible; animation: none; }
}
