html.is-loading body { overflow: hidden; }

#nl-intro {
  position: fixed;
  inset: 0;
  z-index: 9999;
  overflow: hidden;
  pointer-events: none;
  background: transparent;
}
#nl-intro .nl-intro__bar {
  position: absolute;
  left: 0;
  width: 101%;
  height: calc(100% / 7 + 1px);
  overflow: hidden;
  transform: translate3d(0, 0, 0);
  will-change: transform;
  background: #F4F2EC;
}
#nl-intro .nl-intro__bar[data-bar="1"] { top: 0;                    --bar-i: 0; background: #F7F6F2; }
#nl-intro .nl-intro__bar[data-bar="2"] { top: calc(100% / 7 * 1);   --bar-i: 1; background: #F3F1EB; }
#nl-intro .nl-intro__bar[data-bar="3"] { top: calc(100% / 7 * 2);   --bar-i: 2; background: #F6F4EE; }
#nl-intro .nl-intro__bar[data-bar="4"] { top: calc(100% / 7 * 3);   --bar-i: 3; background: #FAF8F2; }
#nl-intro .nl-intro__bar[data-bar="5"] { top: calc(100% / 7 * 4);   --bar-i: 4; background: #F6F4EE; }
#nl-intro .nl-intro__bar[data-bar="6"] { top: calc(100% / 7 * 5);   --bar-i: 5; background: #F3F1EB; }
#nl-intro .nl-intro__bar[data-bar="7"] { top: calc(100% / 7 * 6);   --bar-i: 6; background: #F7F6F2; }

/* Each bar holds a copy of the logo positioned so that across all 7 bars the
   full logo visually aligns at the viewport center. Each bar's overflow:hidden
   clips to show only the horizontal slice that falls in that row, so when the
   bar slides out its slice of the logo goes with it. */
#nl-intro .nl-intro__logo-slice {
  position: absolute;
  left: 50%;
  top: calc(50vh - (100vh / 7) * var(--bar-i, 0));
  transform: translate(-50%, calc(-50% + 40px));
  width: clamp(180px, 22vw, 280px);
  height: auto;
  opacity: 0;
  will-change: transform, opacity;
  pointer-events: none;
}
#nl-intro.is-done { pointer-events: none; }

html.is-ready #nl-intro { display: none; }

/* Char reveal: heading stays in place; individual chars fade in one by one */
[data-reveal="chars"] { opacity: 1; }
[data-reveal="chars"] .char {
  display: inline-block;
  opacity: 0;
  will-change: opacity;
}

/* Section / stagger / image: hidden in place. GSAP tweens a small y-offset on reveal. */
[data-reveal="section"],
[data-reveal="stagger"] > *,
[data-reveal="image"] {
  opacity: 0;
  will-change: opacity, transform;
}
[data-reveal="section"].is-visible {
  opacity: 1;
  transition: opacity 700ms var(--nl-ease-out-expo);
}

/* Safety net: if JS never boots (no is-loading, no is-ready), show everything */
html:not(.is-ready):not(.is-loading) [data-reveal],
html:not(.is-ready):not(.is-loading) [data-reveal="stagger"] > *,
html:not(.is-ready):not(.is-loading) [data-reveal="chars"] .char { opacity: 1; }

html.is-lenis, html.is-lenis body { height: auto; }
.lenis.lenis-smooth { scroll-behavior: auto !important; }
.lenis.lenis-smooth [data-lenis-prevent] { overscroll-behavior: contain; }
.lenis.lenis-stopped { overflow: hidden; }

@media (prefers-reduced-motion: reduce) {
  #nl-intro { display: none !important; }
  html.is-loading body { overflow: auto; }
  [data-reveal="chars"],
  [data-reveal="chars"] .char,
  [data-reveal="section"],
  [data-reveal="image"],
  [data-reveal="stagger"] > * {
    opacity: 1 !important;
    transform: none !important;
  }
}
