/* ==========================================================================
   QIX SERVICE IT — motion.css
   Keyframe library, scroll-reveal engine, ambient decor primitives.

   IMPORTANT: no `prefers-reduced-motion` blocks anywhere in this project.
   Motion is a required, always-on part of the brand experience.
   ========================================================================== */

/* ==========================================================================
   1. KEYFRAME LIBRARY
   ========================================================================== */

@keyframes gradShift {
  from { background-position: 0% 50%; }
  to   { background-position: 100% 50%; }
}

@keyframes ruleGrow {
  from { transform: scaleX(0); opacity: 0; }
  to   { transform: scaleX(1); opacity: .75; }
}

@keyframes floatY {
  0%, 100% { transform: translate3d(0, 0, 0); }
  50%      { transform: translate3d(0, -14px, 0); }
}

@keyframes floatXY {
  0%   { transform: translate3d(0,0,0) rotate(0deg); }
  33%  { transform: translate3d(10px,-16px,0) rotate(4deg); }
  66%  { transform: translate3d(-8px,-8px,0) rotate(-3deg); }
  100% { transform: translate3d(0,0,0) rotate(0deg); }
}

@keyframes spinSlow  { to { transform: rotate(360deg); } }
@keyframes spinSlowR { to { transform: rotate(-360deg); } }

@keyframes pulseRing {
  0%   { transform: scale(.7); opacity: .85; }
  70%  { opacity: 0; }
  100% { transform: scale(2.4); opacity: 0; }
}

@keyframes blink {
  0%, 45%  { opacity: 1; }
  50%, 95% { opacity: .15; }
  100%     { opacity: 1; }
}

@keyframes dashFlow    { to { stroke-dashoffset: -1000; } }
@keyframes dashFlowRev { to { stroke-dashoffset: 1000; } }

@keyframes drawIn {
  from { stroke-dashoffset: var(--len, 1000); }
  to   { stroke-dashoffset: 0; }
}

@keyframes scanSweep {
  0%   { transform: translateY(-120%); opacity: 0; }
  12%  { opacity: 1; }
  88%  { opacity: 1; }
  100% { transform: translateY(120%); opacity: 0; }
}

@keyframes gridDrift {
  from { background-position: 0 0, 0 0; }
  to   { background-position: 56px 56px, 56px 56px; }
}

@keyframes auroraDrift {
  0%   { transform: translate3d(0,0,0) scale(1); }
  33%  { transform: translate3d(6%, -8%, 0) scale(1.14); }
  66%  { transform: translate3d(-7%, 5%, 0) scale(.92); }
  100% { transform: translate3d(0,0,0) scale(1); }
}

@keyframes marquee { to { transform: translate3d(-50%, 0, 0); } }

@keyframes shimmer {
  0%   { transform: translateX(-120%) skewX(-18deg); }
  100% { transform: translateX(320%) skewX(-18deg); }
}

@keyframes bounceCue {
  0%, 100% { transform: translateY(0); opacity: .55; }
  50%      { transform: translateY(9px); opacity: 1; }
}

@keyframes glowPulse {
  0%, 100% { opacity: .45; filter: blur(24px); }
  50%      { opacity: .9;  filter: blur(34px); }
}

@keyframes tickerTick {
  0%, 100% { transform: scaleY(.35); opacity: .4; }
  50%      { transform: scaleY(1);   opacity: 1; }
}

@keyframes orbit {
  from { transform: rotate(0deg) translateX(var(--orbit-r, 40px)) rotate(0deg); }
  to   { transform: rotate(360deg) translateX(var(--orbit-r, 40px)) rotate(-360deg); }
}

@keyframes typeCaret {
  0%, 49%   { opacity: 1; }
  50%, 100% { opacity: 0; }
}

@keyframes riseIn {
  from { opacity: 0; transform: translate3d(0, 26px, 0); }
  to   { opacity: 1; transform: translate3d(0, 0, 0); }
}

@keyframes barGrow {
  from { transform: scaleY(.08); }
  to   { transform: scaleY(1); }
}

@keyframes noiseShift {
  0%   { transform: translate3d(0,0,0); }
  10%  { transform: translate3d(-2%,-3%,0); }
  20%  { transform: translate3d(-4%,2%,0); }
  30%  { transform: translate3d(2%,-4%,0); }
  40%  { transform: translate3d(-1%,3%,0); }
  50%  { transform: translate3d(-3%,1%,0); }
  60%  { transform: translate3d(3%,0,0); }
  70%  { transform: translate3d(0,2%,0); }
  80%  { transform: translate3d(-2%,-1%,0); }
  90%  { transform: translate3d(2%,3%,0); }
  100% { transform: translate3d(0,0,0); }
}

/* ==========================================================================
   2. SCROLL-REVEAL ENGINE
   Elements start hidden; IntersectionObserver adds .is-in.
   Stagger with style="--d:2" (multiplied by 70ms).
   .no-js fallback below guarantees content is visible without JS.
   ========================================================================== */

[data-reveal] {
  opacity: 0;
  transition:
    opacity 900ms var(--ease-out),
    transform 900ms var(--ease-out),
    filter 900ms var(--ease-out),
    clip-path 1000ms var(--ease-out);
  transition-delay: calc(var(--d, 0) * 70ms);
  will-change: opacity, transform;
}

[data-reveal="up"]    { transform: translate3d(0, 42px, 0); }
[data-reveal="down"]  { transform: translate3d(0, -30px, 0); }
[data-reveal="left"]  { transform: translate3d(-48px, 0, 0); }
[data-reveal="right"] { transform: translate3d(48px, 0, 0); }
[data-reveal="scale"] { transform: scale(.9); }
[data-reveal="blur"]  { filter: blur(14px); transform: translate3d(0, 22px, 0); }
[data-reveal="clip"]  { clip-path: inset(0 0 100% 0); transform: translate3d(0, 16px, 0); }
[data-reveal="tilt"]  { transform: perspective(900px) rotateX(14deg) translate3d(0, 40px, 0); transform-origin: top; }

/* "mask" + "words": the element itself stays visible; its inner
   .line-mask / .word-fx children carry the animation instead. */
[data-reveal="mask"],
[data-reveal="words"] { opacity: 1; transform: none; }

[data-reveal].is-in {
  opacity: 1;
  transform: none;
  filter: none;
  clip-path: inset(0 0 0 0);
}

/* Line-by-line headline reveal (built by JS) */
.line-mask { display: block; overflow: hidden; padding-block: 0.04em; }
.line-mask > span {
  display: block;
  transform: translate3d(0, 110%, 0);
  transition: transform 1000ms var(--ease-out);
  transition-delay: calc(var(--d, 0) * 85ms);
}
.is-in .line-mask > span,
.line-mask.is-in > span { transform: none; }

/* Word-level stagger (built by JS) */
.word-fx {
  display: inline-block;
  opacity: 0;
  transform: translate3d(0, 0.5em, 0) rotate(3deg);
  transition: opacity 720ms var(--ease-out), transform 720ms var(--ease-out);
  transition-delay: calc(var(--d, 0) * 42ms);
}
.is-in .word-fx { opacity: 1; transform: none; }

/* No-JS safety net */
.no-js [data-reveal],
.no-js .word-fx { opacity: 1; transform: none; filter: none; clip-path: none; }
.no-js .line-mask > span { transform: none; }

/* ==========================================================================
   3. AMBIENT BACKDROP LAYERS
   ========================================================================== */

.backdrop {
  position: fixed;
  inset: 0;
  z-index: var(--z-decor);
  pointer-events: none;
  overflow: hidden;
}

/* Blueprint grid that slowly drifts */
.backdrop__grid {
  position: absolute;
  inset: -60px;
  background-image:
    linear-gradient(to right, rgba(180,205,235,.045) 1px, transparent 1px),
    linear-gradient(to bottom, rgba(180,205,235,.045) 1px, transparent 1px);
  background-size: 56px 56px, 56px 56px;
  animation: gridDrift 26s linear infinite;
  mask-image: radial-gradient(ellipse 120% 90% at 50% 0%, #000 12%, transparent 78%);
  -webkit-mask-image: radial-gradient(ellipse 120% 90% at 50% 0%, #000 12%, transparent 78%);
}

/* Slow-moving colour fields */
.backdrop__aurora {
  position: absolute;
  border-radius: 50%;
  filter: blur(90px);
  opacity: .5;
  mix-blend-mode: screen;
}
.backdrop__aurora--a {
  width: 46vw; height: 46vw;
  top: -14vw; left: -8vw;
  background: radial-gradient(circle, rgba(200,255,77,.16), transparent 68%);
  animation: auroraDrift 30s var(--ease-in-out) infinite;
}
.backdrop__aurora--b {
  width: 52vw; height: 52vw;
  top: 22vh; right: -16vw;
  background: radial-gradient(circle, rgba(61,109,255,.18), transparent 68%);
  animation: auroraDrift 38s var(--ease-in-out) infinite reverse;
}
.backdrop__aurora--c {
  width: 38vw; height: 38vw;
  bottom: -12vw; left: 26vw;
  background: radial-gradient(circle, rgba(79,227,193,.10), transparent 70%);
  animation: auroraDrift 44s var(--ease-in-out) infinite;
}

/* Film grain */
.backdrop__grain {
  position: absolute;
  inset: -12%;
  opacity: .3;
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='180' height='180'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='.85' numOctaves='3' stitchTiles='stitch'/%3E%3CfeColorMatrix type='saturate' values='0'/%3E%3C/filter%3E%3Crect width='180' height='180' filter='url(%23n)' opacity='.42'/%3E%3C/svg%3E");
  animation: noiseShift 900ms steps(1) infinite;
}

/* Horizon scanline that sweeps down the viewport */
.backdrop__scan {
  position: absolute;
  left: 0; right: 0;
  height: 40vh;
  background: linear-gradient(to bottom, transparent, rgba(200,255,77,.035) 45%, rgba(200,255,77,.06) 50%, transparent);
  animation: scanSweep 14s var(--ease-in-out) infinite;
}

/* ==========================================================================
   4. FLOATING DECOR ELEMENTS
   Small animated shapes. Each page picks a different set via .decor--*
   ========================================================================== */

.decor {
  position: absolute;
  inset: 0;
  pointer-events: none;
  z-index: 1;
  overflow: hidden;
}

.dc {
  position: absolute;
  color: var(--acid);
  opacity: .5;
}

/* -- ring: thin rotating circle with a gap -- */
.dc--ring {
  width: 74px; height: 74px;
  border: 1px solid currentColor;
  border-radius: 50%;
  border-top-color: transparent;
  border-right-color: transparent;
  opacity: .3;
  animation: spinSlow 16s linear infinite;
}

/* -- dot with expanding ping -- */
.dc--dot { width: 7px; height: 7px; border-radius: 50%; background: currentColor; opacity: .85; }
.dc--dot::after {
  content: "";
  position: absolute;
  inset: -3px;
  border: 1px solid currentColor;
  border-radius: 50%;
  animation: pulseRing 3.4s var(--ease-out) infinite;
}

/* -- corner bracket -- */
.dc--bracket {
  width: 34px; height: 34px;
  border-left: 1px solid currentColor;
  border-top: 1px solid currentColor;
  opacity: .38;
  animation: floatXY 13s var(--ease-in-out) infinite;
}
.dc--bracket.is-flipped { transform: rotate(180deg); }

/* -- plus / crosshair -- */
.dc--plus { width: 16px; height: 16px; opacity: .4; animation: spinSlow 22s linear infinite; }
.dc--plus::before, .dc--plus::after {
  content: "";
  position: absolute;
  background: currentColor;
}
.dc--plus::before { left: 50%; top: 0; width: 1px; height: 100%; transform: translateX(-50%); }
.dc--plus::after  { top: 50%; left: 0; height: 1px; width: 100%; transform: translateY(-50%); }

/* -- diamond outline -- */
.dc--diamond {
  width: 22px; height: 22px;
  border: 1px solid currentColor;
  opacity: .35;
  animation: floatXY 17s var(--ease-in-out) infinite, spinSlow 30s linear infinite;
}

/* -- equalizer bars -- */
.dc--bars { display: flex; align-items: flex-end; gap: 3px; height: 26px; opacity: .5; }
.dc--bars span {
  display: block;
  width: 3px; height: 100%;
  background: currentColor;
  transform-origin: bottom;
  animation: tickerTick 1.5s var(--ease-in-out) infinite;
}
.dc--bars span:nth-child(2) { animation-delay: .22s; }
.dc--bars span:nth-child(3) { animation-delay: .44s; }
.dc--bars span:nth-child(4) { animation-delay: .66s; }
.dc--bars span:nth-child(5) { animation-delay: .88s; }

/* -- dot matrix square -- */
.dc--matrix {
  width: 62px; height: 62px;
  background-image: radial-gradient(currentColor 1px, transparent 1px);
  background-size: 9px 9px;
  opacity: .26;
  animation: floatY 12s var(--ease-in-out) infinite;
}

/* -- chevron stack (speed) -- */
.dc--chevrons { display: flex; flex-direction: column; gap: 5px; opacity: .45; }
.dc--chevrons i {
  display: block;
  width: 16px; height: 16px;
  border-right: 1px solid currentColor;
  border-bottom: 1px solid currentColor;
  transform: rotate(-45deg);
  animation: blink 2.1s var(--ease-in-out) infinite;
}
.dc--chevrons i:nth-child(2) { animation-delay: .22s; }
.dc--chevrons i:nth-child(3) { animation-delay: .44s; }

/* -- barcode (retail) -- */
.dc--barcode { display: flex; align-items: stretch; gap: 2px; height: 34px; opacity: .4; }
.dc--barcode i { display: block; width: 2px; background: currentColor; animation: blink 3s steps(2) infinite; }
.dc--barcode i:nth-child(odd) { width: 3px; opacity: .6; }
.dc--barcode i:nth-child(3n) { animation-delay: .5s; }
.dc--barcode i:nth-child(4n) { animation-delay: 1.1s; }

/* -- stacked slabs (platform) -- */
.dc--slabs { display: flex; flex-direction: column; gap: 4px; opacity: .4; }
.dc--slabs i {
  display: block;
  width: 46px; height: 6px;
  border: 1px solid currentColor;
  border-radius: 2px;
  transform-origin: left;
  animation: floatY 9s var(--ease-in-out) infinite;
}
.dc--slabs i:nth-child(2) { width: 36px; animation-delay: .3s; }
.dc--slabs i:nth-child(3) { width: 52px; animation-delay: .6s; }

/* -- signal waves (contact) -- */
.dc--waves { width: 46px; height: 46px; opacity: .4; }
.dc--waves i {
  position: absolute;
  inset: 0;
  border: 1px solid currentColor;
  border-radius: 50%;
  animation: pulseRing 3.6s var(--ease-out) infinite;
}
.dc--waves i:nth-child(2) { animation-delay: 1.2s; }
.dc--waves i:nth-child(3) { animation-delay: 2.4s; }

/* -- mono glyph label -- */
.dc--tag {
  font-family: var(--font-mono);
  font-size: 10px;
  letter-spacing: .28em;
  text-transform: uppercase;
  opacity: .3;
  white-space: nowrap;
  animation: floatY 15s var(--ease-in-out) infinite;
}

/* -- vertical hairline with travelling pip -- */
.dc--rail {
  width: 1px; height: 120px;
  background: linear-gradient(to bottom, transparent, currentColor, transparent);
  opacity: .3;
}
.dc--rail::after {
  content: "";
  position: absolute;
  left: -2px; top: 0;
  width: 5px; height: 5px;
  border-radius: 50%;
  background: currentColor;
  box-shadow: 0 0 10px currentColor;
  animation: railTravel 4.6s var(--ease-in-out) infinite;
}
@keyframes railTravel {
  0%, 100% { top: 0; opacity: 0; }
  15%      { opacity: 1; }
  85%      { opacity: 1; }
  100%     { top: 100%; }
}

/* Colour variants */
.dc.is-cobalt { color: var(--cobalt); }
.dc.is-teal   { color: var(--teal); }
.dc.is-amber  { color: var(--amber); }
.dc.is-dim    { color: var(--fg-dim); }

/* Speed variants */
.dc.is-slow  { animation-duration: 26s; }
.dc.is-fast  { animation-duration: 8s; }

/* Parallax hook — JS writes --py */
.dc[data-parallax] { transform: translate3d(0, var(--py, 0px), 0); }

@media (max-width: 700px) {
  .dc--matrix, .dc--rail, .dc--tag { display: none; }
}

/* ==========================================================================
   5. HERO SVG SYSTEM
   Shared animation classes used inside every page's bespoke hero artwork.
   ========================================================================== */

.art { width: 100%; height: auto; overflow: visible; }

.art .spin      { animation: spinSlow 34s linear infinite; transform-origin: center; transform-box: fill-box; }
.art .spin-rev  { animation: spinSlowR 46s linear infinite; transform-origin: center; transform-box: fill-box; }
.art .spin-fast { animation: spinSlow 15s linear infinite; transform-origin: center; transform-box: fill-box; }

.art .flow      { stroke-dasharray: 6 10; animation: dashFlow 3.6s linear infinite; }
.art .flow-slow { stroke-dasharray: 3 12; animation: dashFlow 7s linear infinite; }
.art .flow-rev  { stroke-dasharray: 6 10; animation: dashFlowRev 4.4s linear infinite; }

.art .draw {
  stroke-dasharray: var(--len, 1200);
  stroke-dashoffset: var(--len, 1200);
  animation: drawIn 2.6s var(--ease-out) forwards;
}

.art .bob   { animation: floatY 7s var(--ease-in-out) infinite; transform-box: fill-box; transform-origin: center; }
.art .bob-2 { animation: floatY 9s var(--ease-in-out) infinite .6s; transform-box: fill-box; transform-origin: center; }
.art .bob-3 { animation: floatY 11s var(--ease-in-out) infinite 1.2s; transform-box: fill-box; transform-origin: center; }

.art .twinkle   { animation: blink 3.2s var(--ease-in-out) infinite; }
.art .twinkle-2 { animation: blink 2.4s var(--ease-in-out) infinite .8s; }
.art .twinkle-3 { animation: blink 4s var(--ease-in-out) infinite 1.6s; }

.art .ping { transform-box: fill-box; transform-origin: center; animation: pulseRing 3.2s var(--ease-out) infinite; }
.art .ping-2 { transform-box: fill-box; transform-origin: center; animation: pulseRing 3.2s var(--ease-out) infinite 1.1s; }
.art .ping-3 { transform-box: fill-box; transform-origin: center; animation: pulseRing 3.2s var(--ease-out) infinite 2.2s; }

.art .grow { transform-box: fill-box; transform-origin: bottom; animation: barGrow 1.6s var(--ease-spring) infinite alternate; }

.art .glow-soft { animation: glowPulse 5s var(--ease-in-out) infinite; }

/* Hero artwork frame */
.art-frame {
  position: relative;
  isolation: isolate;
}
.art-frame::before {
  content: "";
  position: absolute;
  inset: 8%;
  border-radius: 50%;
  background: radial-gradient(circle, var(--acid-glow), transparent 66%);
  filter: blur(52px);
  opacity: .5;
  z-index: -1;
  animation: glowPulse 8s var(--ease-in-out) infinite;
}
