/* =========================================================================
   HSB Motion — shared animation layer
   =========================================================================
   Every animation here is transform/opacity only, so all of it runs on the
   compositor and stays at 60fps. Nothing animates width, height, top, left,
   or box-shadow on a loop.

   The whole file is disabled wholesale under prefers-reduced-motion (bottom).
   ========================================================================= */

/* ---- Scroll reveal ----------------------------------------------------- */
/* Elements start hidden and are revealed by hsb-motion.js via IntersectionObserver.
   The .hsb-motion-ready guard means that if JS never runs, content stays fully
   visible instead of being permanently invisible. */

.hsb-motion-ready [data-reveal] {
  opacity: 0;
  transform: translateY(18px);
  transition: opacity 620ms var(--hsb-ease-out), transform 620ms var(--hsb-ease-out);
  will-change: opacity, transform;
}
.hsb-motion-ready [data-reveal="left"]  { transform: translateX(-22px); }
.hsb-motion-ready [data-reveal="right"] { transform: translateX(22px); }
.hsb-motion-ready [data-reveal="scale"] { transform: scale(0.96); }

.hsb-motion-ready [data-reveal].is-visible {
  opacity: 1;
  transform: none;
  will-change: auto;
}

/* Stagger children — index set inline as --i by the markup or JS. */
.hsb-motion-ready [data-stagger] > * {
  opacity: 0;
  transform: translateY(16px);
  transition: opacity 560ms var(--hsb-ease-out), transform 560ms var(--hsb-ease-out);
  transition-delay: calc(var(--i, 0) * 80ms);
}
.hsb-motion-ready [data-stagger].is-visible > * { opacity: 1; transform: none; }

/* ---- Hero entrance sequence -------------------------------------------- */
/* Runs once on load, in the order the brief specifies:
   badge -> headline -> paragraph -> buttons -> preview */

@keyframes hsb-rise {
  from { opacity: 0; transform: translateY(20px); }
  to   { opacity: 1; transform: none; }
}
@keyframes hsb-rise-scale {
  from { opacity: 0; transform: translateY(26px) scale(0.97); }
  to   { opacity: 1; transform: none; }
}

.hsb-motion-ready [data-hero] {
  opacity: 0;
  animation: hsb-rise 720ms var(--hsb-ease-out) forwards;
  animation-delay: calc(var(--step, 0) * 120ms + 100ms);
}
.hsb-motion-ready [data-hero="preview"] {
  animation-name: hsb-rise-scale;
  animation-duration: 900ms;
}

/* ---- Ambient float ----------------------------------------------------- */
/* Used on the dashboard preview and decorative shapes. Long, low-amplitude,
   and transform-only so it costs essentially nothing per frame. */

@keyframes hsb-float {
  0%, 100% { transform: translateY(0); }
  50%      { transform: translateY(-12px); }
}
@keyframes hsb-float-slow {
  0%, 100% { transform: translate3d(0, 0, 0); }
  50%      { transform: translate3d(0, -22px, 0); }
}

.hsb-float      { animation: hsb-float 6s ease-in-out infinite; }
.hsb-float-slow { animation: hsb-float-slow 11s ease-in-out infinite; }
.hsb-float-delay { animation-delay: -3s; }

/* ---- Animated background blobs ----------------------------------------- */

.hsb-bg-decor {
  position: absolute; inset: 0;
  overflow: hidden; pointer-events: none;
  z-index: 0;
}
.hsb-blob {
  position: absolute;
  border-radius: 50%;
  filter: blur(70px);
  opacity: 0.5;
  will-change: transform;
}
/* Only ONE blurred layer per stacking context on mobile — overlapping blurs
   are the most common cause of jank on low-end phones (see media query below). */
.hsb-blob-1 {
  width: 42vw; height: 42vw; max-width: 520px; max-height: 520px;
  top: -12%; left: -8%;
  background: radial-gradient(circle, var(--hsb-brand) 0%, transparent 70%);
  animation: hsb-drift-a 22s ease-in-out infinite;
}
.hsb-blob-2 {
  width: 36vw; height: 36vw; max-width: 460px; max-height: 460px;
  top: 4%; right: -10%;
  background: radial-gradient(circle, var(--hsb-accent) 0%, transparent 70%);
  animation: hsb-drift-b 27s ease-in-out infinite;
}
.hsb-blob-3 {
  width: 30vw; height: 30vw; max-width: 380px; max-height: 380px;
  bottom: -14%; left: 32%;
  background: radial-gradient(circle, var(--hsb-brand-strong) 0%, transparent 70%);
  animation: hsb-drift-a 31s ease-in-out infinite reverse;
}

@keyframes hsb-drift-a {
  0%, 100% { transform: translate3d(0, 0, 0) scale(1); }
  50%      { transform: translate3d(6%, 8%, 0) scale(1.1); }
}
@keyframes hsb-drift-b {
  0%, 100% { transform: translate3d(0, 0, 0) scale(1.05); }
  50%      { transform: translate3d(-7%, 6%, 0) scale(0.95); }
}

/* Fine grid overlay for depth — pure CSS, no image request. */
.hsb-grid-overlay {
  position: absolute; inset: 0; z-index: 0; pointer-events: none;
  background-image:
    linear-gradient(var(--hsb-border) 1px, transparent 1px),
    linear-gradient(90deg, var(--hsb-border) 1px, transparent 1px);
  background-size: 54px 54px;
  mask-image: radial-gradient(ellipse 70% 55% at 50% 0%, #000 40%, transparent 100%);
  -webkit-mask-image: radial-gradient(ellipse 70% 55% at 50% 0%, #000 40%, transparent 100%);
  opacity: 0.6;
}

/* ---- Parallax ---------------------------------------------------------- */
/* JS writes --py; the element only ever translates. */
.hsb-parallax { transform: translate3d(0, var(--py, 0px), 0); will-change: transform; }

/* ---- Marquee ----------------------------------------------------------- */

.hsb-marquee { overflow: hidden; position: relative;
  mask-image: linear-gradient(90deg, transparent, #000 12%, #000 88%, transparent);
  -webkit-mask-image: linear-gradient(90deg, transparent, #000 12%, #000 88%, transparent);
}
.hsb-marquee-track {
  display: flex; align-items: center; gap: 3rem; width: max-content;
  animation: hsb-marquee 32s linear infinite;
}
.hsb-marquee:hover .hsb-marquee-track { animation-play-state: paused; }
@keyframes hsb-marquee { to { transform: translateX(-50%); } }

/* ---- Accordion --------------------------------------------------------- */

.hsb-acc-panel {
  display: grid; grid-template-rows: 0fr;
  transition: grid-template-rows var(--hsb-dur-slow) var(--hsb-ease);
}
.hsb-acc-panel > div { overflow: hidden; }
.hsb-acc[open] .hsb-acc-panel,
.hsb-acc-item[data-open="true"] .hsb-acc-panel { grid-template-rows: 1fr; }
.hsb-acc-item[data-open="true"] .hsb-acc-chevron { transform: rotate(180deg); }
.hsb-acc-chevron { transition: transform var(--hsb-dur) var(--hsb-ease); }

/* ---- Auth card entrance ------------------------------------------------ */

@keyframes hsb-card-in {
  from { opacity: 0; transform: translateY(22px) scale(0.985); }
  to   { opacity: 1; transform: none; }
}
.hsb-motion-ready .hsb-auth-card {
  animation: hsb-card-in 620ms var(--hsb-ease-out) both;
}

/* Success tick */
@keyframes hsb-tick { from { stroke-dashoffset: 48; } to { stroke-dashoffset: 0; } }
.hsb-tick path { stroke-dasharray: 48; animation: hsb-tick 520ms var(--hsb-ease-out) forwards; }

/* Shake for rejected submissions — short, single, non-looping. */
@keyframes hsb-shake {
  10%, 90% { transform: translateX(-1px); }
  20%, 80% { transform: translateX(2px); }
  30%, 50%, 70% { transform: translateX(-4px); }
  40%, 60% { transform: translateX(4px); }
}
.hsb-shake { animation: hsb-shake 500ms cubic-bezier(0.36, 0.07, 0.19, 0.97) both; }

/* ---- Page transition --------------------------------------------------- */

@keyframes hsb-page-in { from { opacity: 0; } to { opacity: 1; } }
.hsb-motion-ready .hsb-page { animation: hsb-page-in 360ms var(--hsb-ease-out) both; }

/* ---- Mobile: cut the expensive work ------------------------------------ */

@media (max-width: 767.98px) {
  /* Stacked blur layers are the main frame-rate killer on low-end phones. */
  .hsb-blob-2, .hsb-blob-3 { display: none; }
  .hsb-blob-1 { filter: blur(50px); opacity: 0.38; }
  .hsb-float, .hsb-float-slow { animation: none; }
  .hsb-parallax { transform: none !important; }
  .hsb-grid-overlay { opacity: 0.35; }
}

/* ---- Reduced motion: honour it completely ------------------------------ */

@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after {
    animation-duration: 0.01ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: 0.01ms !important;
    scroll-behavior: auto !important;
  }
  /* Content must still be readable — reveal everything immediately. */
  .hsb-motion-ready [data-reveal],
  .hsb-motion-ready [data-stagger] > *,
  .hsb-motion-ready [data-hero] {
    opacity: 1 !important;
    transform: none !important;
    animation: none !important;
  }
  .hsb-blob, .hsb-grid-overlay { animation: none !important; }
  .hsb-parallax { transform: none !important; }
  .hsb-marquee-track { animation: none !important; }
}
