/* ============================================================
   LUFLY - Preloader "Building the brand"
   Seed dot -> glyph pieces fly in on their own paths -> settle
   + glass reflection -> seal glow -> glowing curtain exit.
   Tokens resolve through design-system/style.css with fallbacks.
   ============================================================ */

:root {
  --ld-teal-hi: var(--lu-mint, #7fe2d0);
  --ld-mint: var(--lu-mint, #7fe2d0);
  --ld-teal: var(--lu-teal-500, #1c8b8b);
  --ld-ease: cubic-bezier(.19, 1, .22, 1);
}

body.ld-loading {
  overflow: hidden !important;
}

body.ready {
  /* the design system clips horizontal overflow globally; a bare
     `overflow: auto` here undid that for the whole site once the loader
     exited (any too-wide element then scrolled the page sideways) */
  overflow-y: auto;
  overflow-x: clip;
  overflow-x: hidden; /* fallback for browsers without `clip` */
}

/* Last-resort safety net, pure CSS so it works even if the script dies.
   The loader is only allowed to hold the page for a few seconds; after
   that it fades out and scrolling is returned no matter what state JS
   is in. Nothing here depends on a class being added by JavaScript. */
@keyframes ldFailsafe {
  to { opacity: 0; visibility: hidden; pointer-events: none; }
}

.ld-loader {
  animation: ldFailsafe 0.4s ease 8s forwards;
}

@keyframes ldRestoreScroll {
  to { overflow: auto !important; }
}

body.ld-loading {
  animation: ldRestoreScroll 0s linear 8.4s forwards;
}

/* once the normal exit path runs, the failsafe must not interfere */
.ld-loader.exit { animation: none; }

@media (prefers-reduced-motion: reduce) {
  .ld-loader { animation-delay: 3s; }
  body.ld-loading { animation-delay: 3.4s; }
}

/* ---------------- loader stage ---------------- */

.ld-loader {
  position: fixed;
  inset: 0;
  z-index: 99999;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  /* Balanced translucent scrim: preserves page visibility underneath
     while guaranteeing high contrast for the brand assembly */
  background: rgba(4, 9, 10, 0.42);
  backdrop-filter: blur(12px) saturate(140%);
  -webkit-backdrop-filter: blur(12px) saturate(140%);
  transition: transform .85s cubic-bezier(.76, 0, .24, 1), opacity .45s ease, visibility 0s linear .86s;
  will-change: transform, opacity;
}

.ld-loader.is-nav {
  background: rgba(4, 9, 10, 0.30);
}

.ld-loader.exit {
  transform: translateY(-101%);
  visibility: hidden;
}

.ld-loader.exit::after {
  /* glowing curtain edge */
  content: "";
  position: absolute;
  left: 0;
  right: 0;
  bottom: -3px;
  height: 3px;
  background: linear-gradient(90deg, transparent, var(--ld-teal-hi), transparent);
  box-shadow: 0 0 60px 12px color-mix(in srgb, var(--ld-mint) 45%, transparent);
}

/* re-entry must be instant: without this, the .exit visibility delay
   (0.86s) would keep a re-shown nav loader invisible while it blocks
   clicks. Hides keep their delay; shows get none. */
.ld-loader:not(.exit) {
  visibility: visible;
  transition-delay: 0s, 0s, 0s;
}

/* ---------------- center content stage ---------------- */

.ld-center {
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  width: 100%;
  margin: auto;
}

/* ---------------- logo box: assemble + reflect ---------------- */

.ld-logoBox {
  position: relative;
  z-index: 3;
  width: min(340px, 62vw);
  aspect-ratio: 510 / 325;
  transform-origin: center center;
  flex-shrink: 0;
}

.ld-draw {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  overflow: visible;
  animation: ldSettle .45s ease 1.56s both;
}

/* ---- "Building the brand": every glyph piece flies in on its own path.
   Staggered so the mark assembles piece by piece, then the whole group
   settles with a tiny vibration. ---- */

.ld-draw path {
  fill: none;
  stroke: var(--ld-teal-hi);
  stroke-width: 7;
  stroke-linecap: round;
  stroke-linejoin: round;
  opacity: 0;
  transform-box: fill-box;
  transform-origin: center;
  filter: drop-shadow(0 0 8px color-mix(in srgb, var(--ld-mint) 45%, transparent));
  animation-duration: .58s;
  animation-timing-function: var(--ld-ease);
  animation-fill-mode: both;
}

/* two-tone identity: mint strokes with two soft-ink accents */
.ld-draw path:nth-child(4),
.ld-draw path:nth-child(8) {
  stroke: color-mix(in srgb, var(--lu-neutral-0, #ffffff) 82%, var(--ld-mint));
}

.ld-draw path:nth-child(1) { animation-name: ldPieceUp;     animation-delay: .20s; }
.ld-draw path:nth-child(2) { animation-name: ldPieceLeft;   animation-delay: .31s; }
.ld-draw path:nth-child(3) { animation-name: ldPieceArc;    animation-delay: .42s; animation-duration: .64s; }
.ld-draw path:nth-child(4) { animation-name: ldPieceDrop;   animation-delay: .53s; animation-duration: .66s; }
.ld-draw path:nth-child(5) { animation-name: ldPieceRise;   animation-delay: .64s; }
.ld-draw path:nth-child(6) { animation-name: ldPieceRight;  animation-delay: .75s; }
.ld-draw path:nth-child(7) { animation-name: ldPieceBounce; animation-delay: .86s; animation-duration: .7s; }
.ld-draw path:nth-child(8) { animation-name: ldPieceSpin;   animation-delay: .97s; animation-duration: .62s; }

@keyframes ldPieceUp     { 0% { opacity: 0; transform: translateY(46px); } 30% { opacity: 1; } 100% { opacity: 1; transform: translateY(0); } }
@keyframes ldPieceLeft   { 0% { opacity: 0; transform: translateX(-38px); } 30% { opacity: 1; } 100% { opacity: 1; transform: translateX(0); } }
@keyframes ldPieceRight  { 0% { opacity: 0; transform: translateX(40px); } 30% { opacity: 1; } 100% { opacity: 1; transform: translateX(0); } }
@keyframes ldPieceArc    { 0% { opacity: 0; transform: translate(-34px, 30px); } 30% { opacity: 1; } 55% { transform: translate(10px, -9px); } 100% { opacity: 1; transform: translate(0, 0); } }
@keyframes ldPieceRise   { 0% { opacity: 0; transform: translate(30px, 34px) rotate(8deg); } 30% { opacity: 1; } 100% { opacity: 1; transform: translate(0, 0) rotate(0deg); } }
@keyframes ldPieceDrop   { 0% { opacity: 0; transform: translateY(-46px); } 30% { opacity: 1; } 70% { transform: translateY(7px); } 85% { transform: translateY(-3px); } 100% { opacity: 1; transform: translateY(0); } }
@keyframes ldPieceBounce { 0% { opacity: 0; transform: translateY(42px) scale(.94); } 28% { opacity: 1; } 62% { transform: translateY(-8px) scale(1.01); } 82% { transform: translateY(3px); } 100% { opacity: 1; transform: translateY(0) scale(1); } }
@keyframes ldPieceSpin   { 0% { opacity: 0; transform: translateY(-34px) rotate(12deg); } 30% { opacity: 1; } 75% { transform: translateY(3px) rotate(-2.5deg); } 100% { opacity: 1; transform: translateY(0) rotate(0deg); } }

/* settling motion: tiny vibration before full rest */
@keyframes ldSettle {
  0% { transform: scale(1); }
  40% { transform: scale(1.015) translateY(-1.5px); }
  70% { transform: scale(0.998); }
  100% { transform: scale(1); }
}

/* ---- seed dot: minimal presence before the first piece ---- */

.ld-seed {
  position: absolute;
  left: 50%;
  top: 50%;
  width: 10px;
  height: 10px;
  margin: -5px 0 0 -5px;
  border-radius: 50%;
  background: var(--ld-mint);
  box-shadow: 0 0 18px 5px color-mix(in srgb, var(--ld-mint) 55%, transparent);
  animation: ldSeed 1.05s ease .05s both;
  z-index: 2;
}

@keyframes ldSeed {
  0% { opacity: 0; transform: scale(.4); }
  18% { opacity: 1; transform: scale(1); }
  52% { opacity: .9; transform: scale(1.3); }
  100% { opacity: 0; transform: scale(2.4); }
}

/* ---- glass-floor reflection (flipped, squashed, teal tint) ---- */

.ld-floor {
  position: absolute;
  top: calc(100% + 4px);
  left: 10%;
  right: 10%;
  height: 1px;
  background: linear-gradient(90deg,
    transparent,
    color-mix(in srgb, var(--ld-mint) 62%, transparent),
    transparent);
  opacity: 0;
  animation: ldReflectIn .9s ease 1.38s both;
  pointer-events: none;
  z-index: 1;
}

.ld-reflect {
  position: absolute;
  top: 70%;
  left: 0;
  width: 100%;
  height: 100%;
  transform: scaleY(-.3);
  transform-origin: 50% 100%;
  filter: blur(1.3px);
  opacity: 0;
  animation: ldReflectIn 1s ease 1.45s 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) 38%, transparent 56%);
  mask-image: linear-gradient(to top, rgba(0, 0, 0, .95) 4%, rgba(0, 0, 0, .3) 38%, transparent 56%);
}

.ld-reflect path {
  fill: none;
  stroke: color-mix(in srgb, var(--ld-teal) 70%, var(--ld-mint));
  stroke-width: 7;
  stroke-linecap: round;
  stroke-linejoin: round;
}

@keyframes ldReflectIn {
  from { opacity: 0; }
  to { opacity: .32; }
}

/* navigation overlays: the finished mark, no replay of the choreography */
.ld-loader.is-nav .ld-seed { display: none; }
.ld-loader.is-nav .ld-draw { animation: none; }
.ld-loader.is-nav .ld-draw path { animation: none; opacity: 1; }
.ld-loader.is-nav .ld-floor { animation: none; opacity: .5; }
.ld-loader.is-nav .ld-reflect { animation: none; opacity: .32; }

/* ---------------- seal: one warm glow pulse, then the curtain ---------------- */

.ld-loader.seal .ld-logoBox {
  animation: ldSeal .45s var(--ld-ease) both;
}

@keyframes ldSeal {
  0% { transform: scale(1); filter: drop-shadow(0 0 0 transparent); }
  50% { transform: scale(1.02); filter: drop-shadow(0 0 20px color-mix(in srgb, var(--ld-mint) 50%, transparent)); }
  100% { transform: scale(1); filter: none; }
}

/* ---------------- reduced motion ---------------- */

.ld-reduced .ld-draw { animation: none; }
.ld-reduced .ld-draw path { animation: none; opacity: 1; transform: none; }
.ld-reduced .ld-seed { display: none; }
.ld-reduced .ld-floor { animation: none; opacity: .5; }
.ld-reduced .ld-reflect { animation: none; opacity: .32; }
.ld-loader.ld-reduced { transition-duration: .35s; }
