/* =========================================================
   huelabs — motion layer
   Everything here is decorative. Hidden "before" states are only
   applied by animations.js (or inside keyframes), so the site stays
   fully visible if scripts fail. All motion is switched off for
   people who prefer reduced motion.
   ========================================================= */
:root{
  --ease-out:cubic-bezier(.16,1,.3,1);
  --ease-in-out:cubic-bezier(.65,0,.35,1);
}

/* ---------- 1. Page enter / leave ---------- */
body{animation:pageIn .6s var(--ease-out) both}
body.is-leaving{opacity:0;transition:opacity .28s ease}
@keyframes pageIn{from{opacity:0}to{opacity:1}}

/* ---------- 2. Hero entrance (pure CSS, runs on load) ---------- */
.nav{animation:navIn .9s var(--ease-out) .1s both}
@keyframes navIn{from{opacity:0;transform:translateY(-16px)}to{opacity:1;transform:none}}

.hero-body > *,.page-hero-body > * > *,.page-hero-body > p,.page-hero-meta{animation:riseIn 1s var(--ease-out) both}
.hero-body > :nth-child(1),.page-hero-body > :nth-child(1) > :nth-child(1){animation-delay:.25s}
.hero-body > :nth-child(2),.page-hero-body > :nth-child(1) > :nth-child(2){animation-delay:.35s}
.hero-body > :nth-child(3),.page-hero-body > :nth-child(2),.page-hero-body > :nth-child(2) > *{animation-delay:.5s}
.page-hero-meta{animation-delay:.65s}
@keyframes riseIn{from{opacity:0;transform:translateY(28px)}to{opacity:1;transform:none}}

/* hero wordmark: letters rise one by one */
.hero-word .ch{display:inline-block;animation:charUp 1.2s var(--ease-out) both;animation-delay:calc(.45s + var(--i) * .06s)}
@keyframes charUp{from{transform:translateY(105%) rotate(6deg);opacity:0}to{transform:none;opacity:1}}
.hero-scroll{animation:riseIn 1s var(--ease-out) 1s both, bob 2s ease-in-out 2s infinite}

/* drifting light inside the blue heroes */
.hero::before,.page-hero::before{content:"";position:absolute;z-index:1;pointer-events:none;width:60vmax;aspect-ratio:1;border-radius:50%;
  background:radial-gradient(circle,rgba(143,149,255,.55),rgba(143,149,255,0) 65%);left:55%;top:-20%;filter:blur(20px);animation:drift 18s ease-in-out infinite alternate}
.page-hero::before{width:45vmax;top:-40%}
@keyframes drift{0%{transform:translate(0,0) scale(1)}50%{transform:translate(-25vw,15vh) scale(1.2)}100%{transform:translate(-8vw,30vh) scale(.9)}}
.cta-band{background-size:140% 140%;animation:bandShift 12s ease-in-out infinite alternate}
@keyframes bandShift{from{background-position:0% 0%}to{background-position:100% 100%}}

/* ---------- 3. Scroll reveals (classes added by JS) ---------- */
.rv{opacity:0;transform:translateY(48px);transition:opacity 1s var(--ease-out),transform 1.1s var(--ease-out);transition-delay:var(--d,0s)}
.rv-clip{clip-path:inset(100% 0 0 0 round var(--radius));transition:clip-path 1.3s var(--ease-out);transition-delay:var(--d,0s)}
.rv-clip > *{transform:scale(1.15);transition:transform 1.6s var(--ease-out);transition-delay:var(--d,0s)}
.rv-title{clip-path:inset(0 0 100% 0);transform:translateY(.25em);transition:clip-path 1.1s var(--ease-out),transform 1.1s var(--ease-out);transition-delay:var(--d,0s)}
.rv-line{transform:scaleX(0);transform-origin:left;transition:transform 1.2s var(--ease-out);transition-delay:var(--d,0s)}
.rv.in,.rv-title.in{opacity:1;transform:none;clip-path:inset(-10% -5% -20% -5%)}
.rv-clip.in{clip-path:inset(0 0 0 0 round var(--radius))}
.rv-clip.in > *{transform:none}
.rv-line.in{transform:none}

/* ---------- 4. Marquee band (home) ---------- */
.marquee{background:var(--lime);color:var(--ink);overflow:hidden;padding-block:clamp(14px,1.6vw,22px);border-block:1px solid rgba(0,0,0,.06)}
.marquee-track{display:flex;width:max-content;animation:marquee 32s linear infinite}
.marquee:hover .marquee-track{animation-play-state:paused}
.marquee-track span{font-size:clamp(20px,2.4vw,36px);font-weight:600;letter-spacing:-.03em;white-space:nowrap;padding-inline:clamp(16px,2vw,32px);display:flex;align-items:center;gap:clamp(16px,2vw,32px)}
.marquee-track span::after{content:"✦";font-size:.6em;color:var(--blue)}
@keyframes marquee{to{transform:translateX(-50%)}}

/* ---------- 5. Hover micro-interactions ---------- */
/* nav underline grows in */
.nav ul a::before{content:"";position:absolute;left:0;right:0;bottom:-2px;height:2px;border-radius:2px;background:#fff;transform:scaleX(0);transform-origin:right;transition:transform .4s var(--ease-out)}
.nav ul a:hover::before{transform:scaleX(1);transform-origin:left}
.nav ul a:hover{opacity:1}

/* button arrows nudge, buttons get a shine */
.btn-lime,.btn-dark,.btn-white{position:relative;overflow:hidden;isolation:isolate}
.btn-lime span[aria-hidden],.btn-white span{transition:transform .35s var(--ease-out)}
.btn-lime:hover span[aria-hidden]{transform:translateX(4px)}
.btn-white:hover span{transform:rotate(-45deg)}
.btn-lime::after,.btn-dark::after{content:"";position:absolute;inset:0;z-index:-1;background:linear-gradient(110deg,transparent 30%,rgba(255,255,255,.55) 50%,transparent 70%);transform:translateX(-120%);transition:transform .7s var(--ease-out)}
.btn-dark::after{background:linear-gradient(110deg,transparent 30%,rgba(255,255,255,.18) 50%,transparent 70%)}
.btn-lime:hover::after,.btn-dark:hover::after{transform:translateX(120%)}

/* cards: image zoom + lift */
.proj .art > *,.post .art > *,.item .art > :not(.badge):not(.quick){transition:transform .9s var(--ease-out)}
.proj:hover .art > *,.post:hover .art > *,.item:hover .art > :not(.badge):not(.quick){transform:scale(1.06)}
.proj .art,.post .art,.item .art{transition:transform .6s var(--ease-out),border-radius .6s var(--ease-out)}
.proj:hover .art,.post:hover .art{border-radius:calc(var(--radius) * 2)}
.feature,.plan,.info-card,.brands div{transition:transform .5s var(--ease-out),box-shadow .5s var(--ease-out),background .2s}
.feature:hover,.plan:hover,.info-card:hover{transform:translateY(-6px);box-shadow:0 22px 44px rgba(17,17,20,.08)}
.brands div:hover{transform:translateY(-4px)}

/* 3D tilt (JS sets --rx / --ry) */
.tilt{transform:perspective(900px) rotateX(var(--rx,0deg)) rotateY(var(--ry,0deg));transition:transform .5s var(--ease-out);will-change:transform}
.tilt.tilting{transition:transform .1s linear}

/* magnetic elements (JS sets --mx / --my) */
.magnetic{translate:var(--mx,0) var(--my,0);transition:translate .5s var(--ease-out)}

/* accordion body slides in */
/* open/close height is animated in main.js */
@keyframes accIn{from{opacity:0;transform:translateY(-10px)}to{opacity:1;transform:none}}
details.acc summary .pm{transition:transform .4s var(--ease-out)}
details.acc[open] summary .pm{transform:rotate(180deg)}
details.acc.closing summary .pm{transform:none}
details.acc.closing summary .pm::before{content:"+"}

/* cart badge bump */
.cart-count.bump{animation:bump .5s var(--ease-out)}
@keyframes bump{0%{transform:scale(1)}40%{transform:scale(1.5)}100%{transform:scale(1)}}

/* footer wordmark letters wave on hover */
.foot-bottom .word{display:flex}
.foot-bottom .word .ch{display:inline-block;transition:transform .5s var(--ease-out);transition-delay:calc(var(--i) * 30ms)}
.foot-bottom .word:hover .ch{transform:translateY(-12%)}
.to-top{transition:background .2s,transform .4s var(--ease-out)}
.to-top:hover{transform:translateY(-4px)}

/* ---------- 6. Living placeholder art ---------- */
.art-orbs i{animation:float 9s ease-in-out infinite}
.art-orbs i:nth-child(2){animation-duration:11s;animation-delay:-3s}
.art-orbs i:nth-child(3){animation-duration:7s;animation-delay:-5s}
@keyframes float{0%,100%{transform:translate(0,0)}33%{transform:translate(6%,-8%)}66%{transform:translate(-5%,6%)}}
.art-grid i{animation:spin 24s linear infinite}
@keyframes spin{to{transform:rotate(1turn)}}
.art-glass::after{animation:stripes 6s linear infinite}
@keyframes stripes{to{background-position:90px 0}}
.art-agi{background-size:160% 160%;animation:agi 14s ease-in-out infinite alternate}
@keyframes agi{from{background-position:0% 100%}to{background-position:100% 0%}}
.tile-dark .keys i{transition:transform .35s var(--ease-out),box-shadow .35s}
.tile-dark:hover .keys i:nth-child(5){transform:translateY(6px);box-shadow:inset 0 2px 2px rgba(255,255,255,.08),0 3px 6px rgba(0,0,0,.6)}
.tile-blue .star{animation:spin 16s linear infinite}
.badge-circle{animation:pulse 2.6s ease-in-out infinite}
@keyframes pulse{0%,100%{box-shadow:0 0 0 0 rgba(217,247,74,.6)}50%{box-shadow:0 0 0 10px rgba(217,247,74,0)}}
.next-proj .arrow-btn{animation:pulse 2.6s ease-in-out infinite}

/* ---------- 7. Custom cursor (fine pointers only) ---------- */
.cursor{position:fixed;left:0;top:0;z-index:100;pointer-events:none;width:14px;height:14px;margin:-7px 0 0 -7px;border-radius:50%;background:var(--lime);mix-blend-mode:difference;transition:width .35s var(--ease-out),height .35s var(--ease-out),margin .35s var(--ease-out),background .3s,opacity .3s;display:grid;place-items:center;opacity:0}
.cursor.on{opacity:1}
.cursor.hover{width:44px;height:44px;margin:-22px 0 0 -22px}
.cursor.view{width:92px;height:92px;margin:-46px 0 0 -46px;mix-blend-mode:normal;background:var(--lime)}
.cursor .cursor-label{font-size:13px;font-weight:600;color:var(--ink);opacity:0;transition:opacity .2s}
.cursor.view .cursor-label{opacity:1}
.cursor.down{transform:scale(.8)}

/* ---------- 8. Reduced motion: switch it all off ---------- */
@media (prefers-reduced-motion:reduce){
  .rv,.rv-clip,.rv-title,.rv-line,.rv-clip > *{opacity:1!important;transform:none!important;clip-path:none!important}
  .hero::before,.page-hero::before,.cursor{display:none}
  .marquee-track{animation:none}
  .tilt,.magnetic{transform:none!important;translate:none!important}
}

/* =========================================================
   9. LOADER — first visit per session only.
   Shown only while <html> has .is-loading, which a tiny inline
   script in <head> adds (so no JS = no loader, never a blank page).
   ========================================================= */
.loader{display:none}
html.is-loading{overflow:hidden}
html.is-loading body{overflow:hidden;animation:none}
/* hold every page animation until the loader leaves */
html.is-loading body *:not(.loader):not(.loader *){animation-play-state:paused!important}

html.is-loading .loader,.loader.leaving{
  display:flex;position:fixed;inset:0;z-index:200;color:#fff;
  background:var(--hero-bg);flex-direction:column;justify-content:space-between;
  padding:clamp(20px,3vw,40px) var(--pad);
  clip-path:inset(0 0 0 0);
}
.loader::after{content:"";position:absolute;inset:0;pointer-events:none;opacity:.18;mix-blend-mode:overlay;background-image:var(--noise)}
.loader > *{position:relative;z-index:1;width:100%;max-width:calc(var(--container) - 2*var(--pad));margin-inline:auto}

.loader-top{display:flex;justify-content:space-between;gap:16px;font-size:var(--fs-sm);font-weight:600;opacity:0;animation:riseIn .8s var(--ease-out) .1s both}
.loader-top span:last-child{font-weight:400;opacity:.8}

.loader-mid{display:flex;align-items:flex-end;justify-content:space-between;gap:24px}
.loader-word{font-size:clamp(64px,16vw,260px);font-weight:600;letter-spacing:-.055em;line-height:.85;display:flex;padding-bottom:.04em}
.loader-word span{display:inline-block;animation:charUp 1s var(--ease-out) both;animation-delay:calc(.15s + var(--i) * .07s)}
.loader-count{font-size:clamp(40px,7vw,112px);font-weight:500;letter-spacing:-.04em;line-height:.9;font-variant-numeric:tabular-nums;white-space:nowrap}
.loader-count small{font-size:.4em;vertical-align:top;margin-left:4px;opacity:.7}

.loader-bottom{display:grid;gap:14px}
.loader-bottom .row{display:flex;justify-content:space-between;gap:16px;font-size:var(--fs-xs);letter-spacing:.06em;text-transform:uppercase;opacity:.85}
.loader-bar{height:2px;background:rgba(255,255,255,.25);border-radius:2px;overflow:hidden}
.loader-bar span{display:block;height:100%;background:var(--lime);transform-origin:left;transform:scaleX(0);transition:transform .25s linear}

/* exit: content lifts, then the screen wipes upward */
.loader.leaving > *{transition:transform .7s var(--ease-in-out),opacity .5s ease;transform:translateY(-40px);opacity:0}
.loader.leaving{transition:clip-path 1s var(--ease-in-out) .25s;clip-path:inset(0 0 100% 0)}

/* safety net: if the script never takes over, fade the loader away on its own */
html.is-loading .loader{animation:loaderFailsafe .6s ease 5.5s forwards}
@keyframes loaderFailsafe{to{opacity:0;visibility:hidden}}

@media (max-width:560px){
  .loader-mid{flex-direction:column;align-items:flex-start}
  .loader-top span:last-child{display:none}
}
