/* ============================================================
   Bigul Connect — shared animations
   Recreates the motion of the original app in pure CSS.
   IMPORTANT: the *resting* state of every rule below is the
   page's normal appearance, so the design/UI is unchanged —
   these only add entrance motion and ambient loops.
   ============================================================ */

/* ---------- Scroll reveal ------------------------------------
   [data-animate] starts offset/transparent; js/script.js adds
   .is-visible when the element scrolls into view.            */
[data-animate] {
  opacity: 0;
  transition: opacity .62s cubic-bezier(.22,.61,.36,1),
              transform .62s cubic-bezier(.22,.61,.36,1);
  will-change: opacity, transform;
}
[data-animate="up"]    { transform: translateY(26px); }
[data-animate="down"]  { transform: translateY(-26px); }
[data-animate="left"]  { transform: translateX(28px); }
[data-animate="right"] { transform: translateX(-28px); }
[data-animate="fade"]  { transform: none; }
[data-animate="zoom"]  { transform: scale(.98); }  /* matches the app's hero-video reveal */

[data-animate].is-visible {
  opacity: 1;
  transform: none;
}

/* Safety net: if JS is disabled or blocked, never hide content. */
.no-js [data-animate] { opacity: 1 !important; transform: none !important; }

/* ---------- Entrance animations (run on load) ---------------- */
@keyframes bg-fade-in   { from { opacity: 0 } to { opacity: 1 } }
@keyframes bg-rise      { from { opacity: 0; transform: translateY(22px) } to { opacity: 1; transform: none } }
@keyframes bg-rise-sm   { from { opacity: 0; transform: translateY(12px) } to { opacity: 1; transform: none } }
@keyframes bg-drop      { from { opacity: 0; transform: translateY(-18px) } to { opacity: 1; transform: none } }
@keyframes bg-pop       { from { opacity: 0; transform: scale(.9) } to { opacity: 1; transform: scale(1) } }

/* fill-mode is `backwards`, NOT `both`, on purpose:
   `backwards` holds the start frame during the delay (so there is no flash)
   but releases the properties once the animation finishes. With `both`, the
   filled end frame keeps overriding normal rules — which silently breaks
   `:hover { transform: scale(...) }` on buttons/cards for the rest of the
   session. The final rendered result is identical either way. */
.anim-fade  { animation: bg-fade-in .7s ease-out backwards; }
.anim-rise  { animation: bg-rise .7s cubic-bezier(.22,.61,.36,1) backwards; }
.anim-drop  { animation: bg-drop .6s cubic-bezier(.22,.61,.36,1) backwards; }
.anim-pop   { animation: bg-pop .55s cubic-bezier(.34,1.4,.64,1) backwards; }

/* Stagger helpers */
.anim-d1 { animation-delay: .08s } .anim-d2 { animation-delay: .16s }
.anim-d3 { animation-delay: .24s } .anim-d4 { animation-delay: .32s }
.anim-d5 { animation-delay: .40s } .anim-d6 { animation-delay: .48s }

/* ---------- Auth / dashboard card entrance ------------------- */
/* `backwards` (not `both`) for the same reason as the .anim-* classes above:
   it must not keep overriding hover/active transforms after it finishes. */
.card, .account-card { animation: bg-rise-sm .5s cubic-bezier(.22,.61,.36,1) backwards; }

/* ---------- Ambient loops ----------------------------------- */
/* Soft pulsing glow — used by hero orbs / ambient blobs. */
@keyframes bg-pulse {
  0%,100% { opacity: .55; transform: scale(1) }
  50%     { opacity: .9;  transform: scale(1.06) }
}
.anim-pulse { animation: bg-pulse 4.5s ease-in-out infinite; }

/* Hero logo glow (mirrors the original drop-shadow pulse). */
@keyframes bg-logo-glow {
  0%,100% { filter: drop-shadow(0 0 4px rgba(83,103,252,.35)) drop-shadow(0 0 10px rgba(0,255,193,.15)) }
  50%     { filter: drop-shadow(0 0 12px rgba(83,103,252,.55)) drop-shadow(0 0 22px rgba(0,255,193,.25)) }
}
.anim-logo-glow { animation: bg-logo-glow 3s ease-in-out infinite; }
/* Light mode keeps the same continuous pulse — just a soft white halo
   instead of the blue/teal glow, matching the original app (it animates
   the logo's drop-shadow in both themes, only the colour differs). */
@keyframes bg-logo-glow-light {
  0%,100% { filter: drop-shadow(0 0 6px rgba(255,255,255,.6)) drop-shadow(0 0 14px rgba(255,255,255,.3)) }
  50%     { filter: drop-shadow(0 0 14px rgba(255,255,255,.9)) drop-shadow(0 0 28px rgba(255,255,255,.5)) }
}
html.light .anim-logo-glow { animation: bg-logo-glow-light 3s ease-in-out infinite; }

/* Expanding connection rings (hero). */
@keyframes bg-ring {
  from { opacity: .8; transform: translate(-50%,-50%) scale(.35) }
  to   { opacity: 0;  transform: translate(-50%,-50%) scale(1.5) }
}
.anim-ring { animation: bg-ring 2.6s ease-out infinite; }

/* Gradient bar sweep (performance divider). */
@keyframes bg-sweep { from { background-position: 0% 50% } to { background-position: 200% 50% } }
.anim-sweep { background-size: 200% 100%; animation: bg-sweep 3.5s linear infinite; }

/* Marquee / ticker (platform partners). */
/* One logo set measures 6 x 140px + 6 x 20px gap = 960px. The row holds three
   sets and shifts by exactly one, so ~1900px of strip always covers the
   viewport — a two-set/-50% loop leaves a gap on displays wider than 960px. */
@keyframes bg-marquee { from { transform: translateX(0) } to { transform: translateX(-960px) } }
.anim-marquee { animation: bg-marquee 26s linear infinite; will-change: transform; }
.anim-marquee:hover { animation-play-state: paused; }

/* Dashed flow lines (ecosystem diagram). */
@keyframes bg-dash { to { stroke-dashoffset: -30 } }
.anim-dash { stroke-dasharray: 6 8; animation: bg-dash 1s linear infinite; }

/* Pulsing junction dots. */
@keyframes bg-dot { 0%,100% { opacity:.6 } 50% { opacity:1 } }
.anim-dot { animation: bg-dot 1.6s ease-in-out infinite; }

/* Spinner (loading states). */
@keyframes bg-spin { to { transform: rotate(360deg) } }
.anim-spin { animation: bg-spin .8s linear infinite; }

/* ---------- Hover polish (no layout change) ----------------- */
.card, .account-card, .stat-card, .app-card, .algo-card {
  transition: transform .22s ease, box-shadow .22s ease, border-color .22s ease;
}

/* ============================================================
   Shared `bgc-*` motion vocabulary
   Fixed names — other stylesheets (css/home.css etc.) APPLY these
   by name and must never redefine them. Each keyframe ships with a
   matching utility class carrying the agreed default timing, so a
   consumer can either use the class or write its own
   `animation: <name> ... ;` shorthand.
   All are switched off under prefers-reduced-motion (bottom of file).
   ============================================================ */

/* Auto zoom in/out — scale(1) -> scale(1.06) -> scale(1). */
@keyframes bgc-pulse-zoom {
  0%, 100% { transform: scale(1) }
  50%      { transform: scale(1.06) }
}
.bgc-pulse-zoom { animation: bgc-pulse-zoom 2.5s ease-in-out infinite; }

/* Hero floating background — slow vertical drift, plays alternate. */
@keyframes bgc-float {
  from { transform: translateY(0) }
  to   { transform: translateY(-18px) }
}
.bgc-float { animation: bgc-float 6s ease-in-out infinite alternate; }

/* Downward arrow travel — translateY(0 -> 8px) with a fade. */
@keyframes bgc-arrow-down {
  0%   { transform: translateY(0);   opacity: .45 }
  50%  { transform: translateY(8px); opacity: 1 }
  100% { transform: translateY(0);   opacity: .45 }
}
.bgc-arrow-down { animation: bgc-arrow-down 1.5s ease-in-out infinite; }

/* Partner logo slide — the track must hold exactly two duplicated
   sets so the -50% shift loops seamlessly. */
@keyframes bgc-marquee {
  from { transform: translateX(0) }
  to   { transform: translateX(-50%) }
}
.bgc-marquee { animation: bgc-marquee 30s linear infinite; will-change: transform; }
.bgc-marquee:hover { animation-play-state: paused; }

/* Hover zoom utility. */
.bgc-hover-zoom { transition: transform .3s ease; }
.bgc-hover-zoom:hover { transform: scale(1.05); }

/* ---------- Respect reduced-motion ------------------------- */
@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after {
    animation-duration: .001ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: .001ms !important;
  }
  [data-animate] { opacity: 1 !important; transform: none !important; }

  /* Shared vocabulary: fully off, not just shortened. */
  .bgc-pulse-zoom, .bgc-float, .bgc-arrow-down, .bgc-marquee {
    animation: none !important;
    transform: none !important;
    opacity: 1 !important;
  }
  .bgc-hover-zoom,
  .bgc-hover-zoom:hover { transition: none !important; transform: none !important; }
}

/* ===================================================================
   Scrollbars — themed site-wide
   -------------------------------------------------------------------
   Lives here because animations.css is the only stylesheet every page
   loads. Left unstyled, a scroller paints the OS bar — on Windows a
   light-grey trough with arrow buttons at each end, which read as a
   foreign control against the dark chrome.

   Scoping: the bare `::-webkit-scrollbar` styles the document's own
   bar, `*::-webkit-scrollbar` every inner scroller (docs sidebar,
   code blocks, table wrappers, modals, API panels).

   NOTHING in this codebase may set the standard scrollbar-width or
   scrollbar-color outside the @supports block below. Chrome 121+ drops
   every ::-webkit-scrollbar rule on any element carrying either one,
   and both INHERIT — so a single declaration on <html> (or on a
   wrapper) silently reverts that whole subtree to the OS bar. Firefox
   supports no scrollbar pseudo-elements, so it gets the standard pair
   instead, fenced behind a query only it enters: Chromium and Safari
   understand selector(::-webkit-scrollbar) and skip the block.
   =================================================================== */

/* Firefox only — see the note above on why this is fenced. */
@supports not selector(::-webkit-scrollbar){
  html{ scrollbar-width:thin; scrollbar-color:#5367fc rgba(255,255,255,0.04); }
  html.light{ scrollbar-color:#5367fc rgba(15,23,42,0.05); }
}

::-webkit-scrollbar,
*::-webkit-scrollbar{ width:10px; height:10px; }

::-webkit-scrollbar-track,
*::-webkit-scrollbar-track{ background-color:rgba(255,255,255,0.04); border-radius:10px; }

/* Solid accent blue — the same #5367fc the nav, links and buttons use.
   Opaque on purpose: a translucent thumb picks up whatever sits behind it
   and reads as muted grey-blue rather than as the brand colour.

   background-color, not the `background` shorthand: the shorthand resets
   background-clip to border-box, which would collapse the inset below.
   The transparent 2px border clipped to padding-box is what makes the
   thumb read slimmer than its 10px track. */
::-webkit-scrollbar-thumb,
*::-webkit-scrollbar-thumb{ background-color:#5367fc; border-radius:10px;
  border:2px solid transparent; background-clip:padding-box; }
::-webkit-scrollbar-thumb:hover,
*::-webkit-scrollbar-thumb:hover{ background-color:#6b7cfd; }
::-webkit-scrollbar-thumb:active,
*::-webkit-scrollbar-thumb:active{ background-color:#8290ff; }

/* Drops the OS arrow buttons at each end, and the dead square where a
   horizontal and a vertical bar meet. */
::-webkit-scrollbar-button,
*::-webkit-scrollbar-button{ display:none; width:0; height:0; }
::-webkit-scrollbar-corner,
*::-webkit-scrollbar-corner{ background:transparent; }

/* Light theme — the thumb keeps the same solid blue (it reads correctly on
   both grounds); only the track swaps to an ink tint. */
html.light::-webkit-scrollbar-track,
html.light *::-webkit-scrollbar-track{ background-color:rgba(15,23,42,0.05); }
