/* ==========================================================================
 * ChannelGuru — Landing Page Effects Library  (lp-effects.css)
 * --------------------------------------------------------------------------
 * A self-hosted, dependency-free motion + surface toolkit for AI-generated
 * landing / sales / lead-magnet pages. It is the web counterpart of the slide
 * renderer's cg-* classes: the AI author just adds these classes and the page
 * gets premium, production-grade motion and depth with zero bespoke keyframes.
 *
 * Served from  https://api.guruchannels.net/assets/lp-effects.css  and paired
 * with lp-effects.js (which drives the scroll-reveal / counters / tilt).
 *
 * DESIGN CONTRACTS (read before editing):
 *  - Everything is namespaced lp-* so it never clashes with Bootstrap, the
 *    model's own CSS, or the brand color variables (--primary / --on-primary…).
 *  - PROGRESSIVE ENHANCEMENT: content that "reveals" is ONLY hidden when JS is
 *    alive (html.lp-js, set synchronously by lp-effects.js). If the script or
 *    CDN fails, html has no .lp-js class, so every .lp-reveal stays fully
 *    visible. Nothing is ever permanently hidden behind JS.
 *  - prefers-reduced-motion: reduce disables ALL animation/transition below.
 * ========================================================================== */

/* -------------------------------------------------------------------------- *
 * 0. TOKENS  (safe fallbacks; a page may already define --primary/--secondary)
 * -------------------------------------------------------------------------- */
:root {
  --lp-ease: cubic-bezier(.22, 1, .36, 1);
  --lp-ease-bounce: cubic-bezier(.34, 1.56, .64, 1);
  --lp-reveal-dur: .7s;
  --lp-reveal-shift: 26px;
}

/* -------------------------------------------------------------------------- *
 * 1. SCROLL REVEAL  (drive: lp-effects.js adds .lp-in when in viewport)
 *    Hidden ONLY while JS is alive so a failed script never blanks the page.
 * -------------------------------------------------------------------------- */
.lp-js .lp-reveal {
  opacity: 0;
  transform: translateY(var(--lp-reveal-shift));
  transition:
    opacity var(--lp-reveal-dur) var(--lp-ease),
    transform var(--lp-reveal-dur) var(--lp-ease);
  transition-delay: var(--lp-d, 0s);
  will-change: opacity, transform;
}
.lp-js .lp-reveal-up    { transform: translateY(var(--lp-reveal-shift)); }
.lp-js .lp-reveal-down  { transform: translateY(calc(-1 * var(--lp-reveal-shift))); }
.lp-js .lp-reveal-left  { transform: translateX(var(--lp-reveal-shift)); }
.lp-js .lp-reveal-right { transform: translateX(calc(-1 * var(--lp-reveal-shift))); }
.lp-js .lp-reveal-zoom  { transform: scale(.92); }
.lp-js .lp-reveal-blur  { filter: blur(12px); transition: opacity var(--lp-reveal-dur) var(--lp-ease), filter var(--lp-reveal-dur) var(--lp-ease); }

.lp-js .lp-reveal.lp-in {
  opacity: 1;
  transform: none;
  filter: none;
}

/* -------------------------------------------------------------------------- *
 * 2. CONTINUOUS "ALWAYS-ALIVE" LOOPS  (seamless: start state === end state)
 *    Put several across a section so something is always gently moving.
 * -------------------------------------------------------------------------- */
.lp-float   { animation: lp-float 6s var(--lp-ease) infinite; }
.lp-float-x { animation: lp-float-x 7s var(--lp-ease) infinite; }
.lp-sway    { animation: lp-sway 5s ease-in-out infinite; transform-origin: 50% 50%; }
.lp-rock    { animation: lp-sway 4.5s ease-in-out infinite; transform-origin: 50% 0; }
.lp-breathe { animation: lp-breathe 5s ease-in-out infinite; }
.lp-pulse   { animation: lp-pulse 3.2s ease-in-out infinite; }
.lp-glow    { animation: lp-glow 3.4s ease-in-out infinite; }
.lp-spin    { animation: lp-spin 18s linear infinite; }
.lp-drift   { animation: lp-drift 16s ease-in-out infinite; }

@keyframes lp-float   { 0%,100% { transform: translateY(0); } 50% { transform: translateY(-12px); } }
@keyframes lp-float-x { 0%,100% { transform: translateX(0); } 50% { transform: translateX(12px); } }
@keyframes lp-sway    { 0%,100% { transform: rotate(-2.5deg); } 50% { transform: rotate(2.5deg); } }
@keyframes lp-breathe { 0%,100% { transform: scale(1); } 50% { transform: scale(1.04); } }
@keyframes lp-pulse   { 0%,100% { opacity: 1; } 50% { opacity: .55; } }
@keyframes lp-glow    { 0%,100% { filter: drop-shadow(0 0 0 rgba(99,102,241,0)); } 50% { filter: drop-shadow(0 0 22px rgba(99,102,241,.45)); } }
@keyframes lp-spin    { to { transform: rotate(360deg); } }
@keyframes lp-drift   { 0%,100% { transform: translate(0,0) scale(1); } 33% { transform: translate(4%,-3%) scale(1.06); } 66% { transform: translate(-3%,4%) scale(.97); } }

/* -------------------------------------------------------------------------- *
 * 3. SHIMMER / SWEEP  (light travelling across text, borders, cards)
 * -------------------------------------------------------------------------- */
/* Animated gradient THROUGH gradient text. The element sets its own gradient. */
.lp-shimmer {
  background-size: 200% auto;
  -webkit-background-clip: text;
  background-clip: text;
  -webkit-text-fill-color: transparent;
  color: transparent;
  animation: lp-shimmer 6s linear infinite;
}
@keyframes lp-shimmer { to { background-position: 200% center; } }

/* A translucent light band sweeps across the element (put on cards/buttons). */
.lp-sweep { position: relative; overflow: hidden; }
.lp-sweep::after {
  content: "";
  position: absolute;
  inset: 0;
  background: linear-gradient(115deg, transparent 30%, rgba(255,255,255,.35) 50%, transparent 70%);
  transform: translateX(-120%);
  animation: lp-sweep 4.5s var(--lp-ease) infinite;
  pointer-events: none;
}
@keyframes lp-sweep { 0% { transform: translateX(-120%); } 60%,100% { transform: translateX(120%); } }

/* -------------------------------------------------------------------------- *
 * 4. SURFACES — glass, gradient text/border, animated mesh, blobs, patterns
 * -------------------------------------------------------------------------- */
.lp-glass {
  background: rgba(255, 255, 255, .08);
  backdrop-filter: blur(16px) saturate(140%);
  -webkit-backdrop-filter: blur(16px) saturate(140%);
  border: 1px solid rgba(255, 255, 255, .18);
  box-shadow: 0 24px 60px -20px rgba(10, 14, 30, .35);
}
.lp-glass-dark {
  background: rgba(12, 15, 25, .38);
  backdrop-filter: blur(16px) saturate(140%);
  -webkit-backdrop-filter: blur(16px) saturate(140%);
  border: 1px solid rgba(255, 255, 255, .10);
  box-shadow: 0 24px 60px -20px rgba(0, 0, 0, .5);
}

/* Gradient text — the element supplies the gradient via --lp-from/--lp-to. */
.lp-gradient-text {
  background-image: linear-gradient(120deg, var(--lp-from, var(--primary, #6366f1)), var(--lp-to, var(--secondary, #a855f7)));
  -webkit-background-clip: text;
  background-clip: text;
  -webkit-text-fill-color: transparent;
  color: transparent;
}

/* Gradient border ring (works on any radius via padding trick). */
.lp-gradient-border {
  position: relative;
  isolation: isolate;
}
.lp-gradient-border::before {
  content: "";
  position: absolute;
  inset: 0;
  border-radius: inherit;
  padding: 1.5px;
  background: linear-gradient(120deg, var(--lp-from, var(--primary, #6366f1)), var(--lp-to, var(--secondary, #a855f7)));
  -webkit-mask: linear-gradient(#000 0 0) content-box, linear-gradient(#000 0 0);
  -webkit-mask-composite: xor;
  mask-composite: exclude;
  pointer-events: none;
}

/* Slowly-shifting multi-stop gradient mesh — a premium hero/section backdrop.
   The element sets its own colors via --lp-c1..--lp-c4 (default to brand). */
.lp-mesh {
  background:
    radial-gradient(60% 60% at 15% 20%, var(--lp-c1, rgba(99,102,241,.55)), transparent 60%),
    radial-gradient(55% 55% at 85% 15%, var(--lp-c2, rgba(168,85,247,.45)), transparent 60%),
    radial-gradient(65% 65% at 75% 85%, var(--lp-c3, rgba(236,72,153,.40)), transparent 60%),
    radial-gradient(55% 55% at 20% 90%, var(--lp-c4, rgba(56,189,248,.40)), transparent 60%);
  background-color: var(--lp-mesh-base, #0b0f1e);
  background-size: 180% 180%;
  animation: lp-mesh 18s ease-in-out infinite;
}
@keyframes lp-mesh { 0%,100% { background-position: 0% 50%; } 50% { background-position: 100% 50%; } }

/* Soft blurred colour blob for layered depth behind hero/section content. */
.lp-blob {
  position: absolute;
  border-radius: 50%;
  filter: blur(90px);
  opacity: .55;
  pointer-events: none;
  z-index: 0;
}

/* Subtle dot / grid textures. The faintness is baked into the PATTERN COLOR
   (via color-mix) — NOT the element's opacity — so applying the class directly
   to a section/wrapper never fades the content inside it. In browsers without
   color-mix the pattern simply doesn't paint (graceful: content stays fully
   visible). currentColor lets the texture adapt to light/dark surfaces. */
.lp-dot-bg {
  background-image: radial-gradient(color-mix(in srgb, currentColor 12%, transparent) 1px, transparent 1px);
  background-size: 22px 22px;
}
.lp-grid-bg {
  background-image:
    linear-gradient(color-mix(in srgb, currentColor 9%, transparent) 1px, transparent 1px),
    linear-gradient(90deg, color-mix(in srgb, currentColor 9%, transparent) 1px, transparent 1px);
  background-size: 44px 44px;
}

/* -------------------------------------------------------------------------- *
 * 5. HOVER MICRO-INTERACTIONS  (cards, tiles, media, buttons)
 * -------------------------------------------------------------------------- */
.lp-lift {
  transition: transform .35s var(--lp-ease), box-shadow .35s var(--lp-ease);
}
.lp-lift:hover {
  transform: translateY(-6px);
  box-shadow: 0 28px 60px -22px rgba(10, 14, 30, .45);
}
.lp-hover-glow { transition: box-shadow .35s var(--lp-ease); }
.lp-hover-glow:hover {
  box-shadow: 0 0 0 1px rgba(255,255,255,.06), 0 18px 50px -18px var(--lp-glow-color, rgba(99,102,241,.6));
}
/* Pointer-parallax tilt — lp-effects.js sets --lp-rx/--lp-ry from the cursor. */
.lp-tilt {
  transform: perspective(900px) rotateX(var(--lp-rx, 0deg)) rotateY(var(--lp-ry, 0deg));
  transition: transform .25s var(--lp-ease);
  transform-style: preserve-3d;
}

/* -------------------------------------------------------------------------- *
 * 6. MARQUEE  (looping logo / feature strip — pure CSS, seamless)
 *    Markup: <div class="lp-marquee"><div class="lp-marquee-track">…dup…</div></div>
 * -------------------------------------------------------------------------- */
.lp-marquee { overflow: hidden; }
.lp-marquee-track {
  display: inline-flex;
  gap: 3rem;
  white-space: nowrap;
  animation: lp-marquee var(--lp-marquee-dur, 26s) linear infinite;
}
.lp-marquee:hover .lp-marquee-track { animation-play-state: paused; }
@keyframes lp-marquee { to { transform: translateX(-50%); } }

/* -------------------------------------------------------------------------- *
 * 7. STICKY HEADER STATE  (lp-effects.js toggles .lp-scrolled on scroll)
 * -------------------------------------------------------------------------- */
[data-lp-header] { transition: background-color .3s ease, box-shadow .3s ease, backdrop-filter .3s ease; }

/* -------------------------------------------------------------------------- *
 * 8. REDUCED MOTION — honour the OS setting: kill all motion, keep visibility.
 * -------------------------------------------------------------------------- */
@media (prefers-reduced-motion: reduce) {
  .lp-js .lp-reveal { opacity: 1 !important; transform: none !important; filter: none !important; transition: none !important; }
  .lp-float, .lp-float-x, .lp-sway, .lp-rock, .lp-breathe, .lp-pulse,
  .lp-glow, .lp-spin, .lp-drift, .lp-shimmer, .lp-mesh,
  .lp-sweep::after, .lp-marquee-track { animation: none !important; }
  .lp-lift, .lp-tilt, .lp-hover-glow { transition: none !important; }
  .lp-tilt { transform: none !important; }
}
