/* ============================================================
   FORGED · motion.css
   Site-wide animation layer. Loads AFTER site.css.
   All hidden start-states are gated on html.motion — added by a
   tiny inline head script ONLY when the visitor allows motion.
   No JS / reduced-motion / print => content is visible at rest.
   ============================================================ */

/* ---- page-level glow accent (overridable per product page) ---- */
:root { --glow: var(--accent); }

/* ============================================================
   1 · HERO ENTRANCE  ([data-enter], staggered by --i)
   ============================================================ */
html.motion [data-enter] {
  opacity: 0;
  transform: translateY(24px);
  will-change: opacity, transform;
}
html.motion.loaded [data-enter] {
  opacity: 1;
  transform: none;
  transition: opacity 0.85s var(--ease-out), transform 0.85s var(--ease-out);
  transition-delay: calc(var(--i, 0) * 85ms);
}

/* ============================================================
   2 · SCROLL REVEAL  (.m-reveal -> .m-in), staggered by --i
   ============================================================ */
html.motion .m-reveal {
  opacity: 0;
  transform: translateY(28px);
  will-change: opacity, transform;
}
html.motion .m-reveal.m-left  { transform: translateX(-28px); }
html.motion .m-reveal.m-right { transform: translateX(28px); }
html.motion .m-reveal.m-scale { transform: scale(0.94); }
html.motion .m-reveal.m-in {
  opacity: 1;
  transform: none;
  transition: opacity 0.72s var(--ease-out), transform 0.72s var(--ease-out);
  transition-delay: calc(var(--i, 0) * 65ms);
}

/* hairline that draws itself left-to-right when revealed */
html.motion .draw-line {
  display: block; height: 1px; width: 100%;
  background: var(--border);
  transform: scaleX(0); transform-origin: left center;
}
html.motion .draw-line.m-in {
  transform: scaleX(1);
  transition: transform 0.9s var(--ease-out);
}

/* kicker gets a self-drawing accent rule beside it on reveal */
html.motion .section-head .kicker { position: relative; }
html.motion .section-head.m-in .kicker::after {
  content: ""; position: absolute; left: calc(100% + 14px); top: 50%;
  width: 64px; height: 1px; background: linear-gradient(90deg, var(--glow), transparent);
  transform: scaleX(0); transform-origin: left; transform: translateY(-50%) scaleX(0);
  animation: kicker-draw 0.8s var(--ease-out) 0.15s forwards;
}
@keyframes kicker-draw { to { transform: translateY(-50%) scaleX(1); } }

/* ============================================================
   3 · BUTTONS — sheen sweep + press
   ============================================================ */
.btn { position: relative; overflow: hidden; }
.btn > * { position: relative; z-index: 1; }
.btn::after {
  content: ""; position: absolute; top: 0; left: -130%;
  width: 55%; height: 100%; z-index: 0;
  background: linear-gradient(100deg, transparent, rgba(255,255,255,0.22), transparent);
  transform: skewX(-18deg);
  transition: left 0.6s var(--ease-out);
  pointer-events: none;
}
.btn:hover::after { left: 150%; }
.btn:active { transform: translateY(0) scale(0.985); }
.btn-mini { position: relative; overflow: hidden; }
.btn-mini::after {
  content: ""; position: absolute; inset: 0 auto 0 -130%;
  width: 55%; background: linear-gradient(100deg, transparent, rgba(255,255,255,0.25), transparent);
  transform: skewX(-18deg); transition: left 0.55s var(--ease-out); pointer-events: none;
}
.btn-mini:hover::after { left: 150%; }

/* ============================================================
   4 · CARD HOVER — lift + accent glow + border lift
   ============================================================ */
html.motion .module-card,
html.motion .sec-card,
html.motion .diff-card,
html.motion .step {
  transition: border-color 0.28s var(--ease-out), transform 0.28s var(--ease-out),
              box-shadow 0.28s var(--ease-out), background 0.28s var(--ease-out);
}
html.motion .module-card:hover,
html.motion .sec-card:hover,
html.motion .step:hover {
  transform: translateY(-4px);
  border-color: color-mix(in oklab, var(--glow) 45%, var(--border));
  box-shadow: 0 26px 60px -34px color-mix(in oklab, var(--glow) 60%, transparent);
}
html.motion .diff-card:hover {
  transform: translateY(-4px);
  border-color: color-mix(in oklab, var(--glow) 38%, var(--border));
  box-shadow: 0 26px 60px -34px color-mix(in oklab, var(--glow) 55%, transparent);
}
/* icon tiles get a little life on card hover */
html.motion .module-card .mc-ico,
html.motion .sec-card .sc-ico {
  transition: transform 0.28s var(--ease-out), box-shadow 0.28s var(--ease-out);
}
html.motion .module-card:hover .mc-ico,
html.motion .sec-card:hover .sc-ico {
  transform: scale(1.08) rotate(-3deg);
  box-shadow: 0 0 26px -6px color-mix(in oklab, var(--glow) 70%, transparent);
}

/* ============================================================
   5 · TOPBAR — condenses + shadow once scrolled
   ============================================================ */
.topbar { transition: background 0.3s var(--ease-out), border-color 0.3s var(--ease-out), box-shadow 0.3s var(--ease-out); }
.topbar.scrolled {
  background: rgba(10, 10, 10, 0.9);
  box-shadow: 0 10px 34px -16px rgba(0, 0, 0, 0.7);
}
.brand svg { transition: transform 0.5s var(--ease-out); }
.brand:hover svg { transform: rotate(-8deg) scale(1.08); }

/* ============================================================
   6 · LIVE APP-MOCK touches (scan sweep, blink, ticking)
   ============================================================ */
html.motion .app-mock { position: relative; }
html.motion .app-mock .scan {
  position: absolute; left: 0; right: 0; top: 0; height: 38%;
  background: linear-gradient(180deg, color-mix(in oklab, var(--glow) 16%, transparent), transparent);
  pointer-events: none; z-index: 3; mix-blend-mode: screen;
  animation: mock-scan 6.5s var(--ease-in-out) infinite;
}
@keyframes mock-scan {
  0% { transform: translateY(-110%); opacity: 0; }
  18% { opacity: 0.9; }
  60% { opacity: 0.9; }
  78%, 100% { transform: translateY(290%); opacity: 0; }
}
/* blinking caret in the mock search field */
html.motion .app-mock .caret {
  display: inline-block; width: 1px; height: 11px; margin-left: 1px;
  background: var(--glow); vertical-align: middle;
  animation: caret-blink 1.05s steps(1) infinite;
}
@keyframes caret-blink { 0%, 50% { opacity: 1; } 51%, 100% { opacity: 0; } }

/* live pulse ring used on "live"/status dots in mocks */
html.motion .live-ring { position: relative; }
html.motion .live-ring::after {
  content: ""; position: absolute; inset: -4px; border-radius: inherit;
  border: 1px solid currentColor; opacity: 0;
  animation: live-ring 2.4s var(--ease-out) infinite;
}
@keyframes live-ring {
  0% { transform: scale(0.7); opacity: 0.7; }
  100% { transform: scale(1.9); opacity: 0; }
}

/* a row that periodically "lights up" as if just updated */
html.motion .row-live { position: relative; overflow: hidden; }
html.motion .row-live::before {
  content: ""; position: absolute; inset: 0;
  background: linear-gradient(90deg, transparent, color-mix(in oklab, var(--glow) 14%, transparent), transparent);
  transform: translateX(-100%);
  animation: row-sweep 7s var(--ease-in-out) infinite;
}
@keyframes row-sweep { 0%, 70% { transform: translateX(-100%); } 86%, 100% { transform: translateX(100%); } }

/* ============================================================
   7 · floating ambient marks (hero backdrops)
   ============================================================ */
@media (prefers-reduced-motion: no-preference) {
  .float-slow { animation: floaty 9s var(--ease-in-out) infinite; }
  .float-med  { animation: floaty 6.5s var(--ease-in-out) infinite; }
}
@keyframes floaty {
  0%, 100% { transform: translateY(0); }
  50% { transform: translateY(-12px); }
}

/* respect reduced motion fully — kill the ambient/looping bits */
@media (prefers-reduced-motion: reduce) {
  .app-mock .scan, .app-mock .caret, .live-ring::after, .row-live::before { animation: none !important; display: none; }
}
