/* ============================================================
 * Vilkax · vlx-demo — animated product preview
 * ============================================================
 *
 * A self-contained, CSS-only looping "scene" that shows the
 * product catching a threat: an item arrives → Vilkax scans →
 * a risk verdict + alert lands. Used in the 16:9 video slots on
 * the consumer (/) and business (/business/) landing pages while
 * the real screen-recording is produced.
 *
 * Why CSS-only: the public pages ship a strict CSP (no
 * 'unsafe-inline'), so the animation must live in a linked
 * stylesheet (this file) with no inline <script>/<style>. Every
 * element is driven by one shared 13s timeline so the scene stays
 * in sync; prefers-reduced-motion freezes it on the final frame.
 *
 * Honest framing: this is an ANIMATED PREVIEW of real features
 * (scam/BEC interception, risk scoring, guardian/analyst alerts),
 * not a recording. The caption says so.
 *
 * Theming: `.vlx-demo--consumer` (iris) and `.vlx-demo--biz`
 * (ice/blue) only swap accents + copy; structure is shared.
 * ============================================================ */

/* Self-sufficient 16:9 frame so the demo works on ANY page (the consumer
 * landing doesn't load app.css's .biz-video-slot). On the business page the
 * demo nests inside .biz-video-slot, which already provides the frame. */
.vlx-demo-frame {
  position: relative;
  aspect-ratio: 16 / 9;
  width: 100%;
  border-radius: 16px;
  overflow: hidden;
  background:
    radial-gradient(120% 120% at 50% 0%, rgba(91, 107, 255, 0.10), transparent 60%),
    rgba(255, 255, 255, 0.025);
  border: 1px solid rgba(255, 255, 255, 0.08);
  /* Skip rendering + animation entirely when scrolled off-screen (pure CSS,
     no JS, no network). aspect-ratio keeps the height definite so there's no
     layout shift. This is the PRIMARY off-screen optimization; vlx-demo.js is
     a secondary reinforcement where IntersectionObserver is available. */
  content-visibility: auto;
}
/* The business page frames the same demo in .biz-video-slot (app.css), which
   has its own 16:9 aspect-ratio, so give it the same off-screen skip. */
.biz-video-slot { content-visibility: auto; }
.vlx-demo-frame--center {
  max-width: 760px;
  margin: 22px auto 0;
}

.vlx-demo {
  position: absolute;
  inset: 0;
  display: grid;
  place-items: center;
  padding: clamp(14px, 3.5vw, 32px);
  font-family: inherit;
  /* accent defaults (consumer/iris); --biz overrides below */
  --d-accent: #5B6BFF;
  --d-accent-soft: rgba(91, 107, 255, 0.16);
  --d-accent-line: rgba(91, 107, 255, 0.42);
  --d-danger: #ef4444;
  --d-danger-soft: rgba(239, 68, 68, 0.14);
  --d-ok: #34d399;
  --d-ink: #f8fafc;
  --d-muted: rgba(199, 207, 217, 0.62);
  --d-panel: rgba(13, 21, 38, 0.72);
  --d-panel-line: rgba(255, 255, 255, 0.09);
}
.vlx-demo--biz {
  --d-accent: #5BA8FF;
  --d-accent-soft: rgba(91, 168, 255, 0.16);
  --d-accent-line: rgba(91, 168, 255, 0.42);
}

/* The mock app window — a stylised Vilkax surface (not a literal
 * phone, so it composes cleanly into a 16:9 frame). */
.vlx-demo-app {
  position: relative;
  width: min(100%, 560px);
  aspect-ratio: 16 / 10;
  border-radius: 16px;
  background:
    radial-gradient(120% 90% at 50% -10%, var(--d-accent-soft), transparent 62%),
    var(--d-panel);
  border: 1px solid var(--d-panel-line);
  box-shadow:
    0 24px 60px -28px rgba(0, 0, 0, 0.7),
    inset 0 1px 0 rgba(255, 255, 255, 0.05);
  overflow: hidden;
  backdrop-filter: blur(8px);
  -webkit-backdrop-filter: blur(8px);
}

/* Top bar: brand mark + live status */
.vlx-demo-bar {
  display: flex;
  align-items: center;
  gap: 8px;
  padding: 10px 14px;
  border-bottom: 1px solid var(--d-panel-line);
  background: rgba(255, 255, 255, 0.02);
}
.vlx-demo-bar img { height: 18px; width: auto; display: block; }
.vlx-demo-brandname {
  font-size: 11.5px; font-weight: 800; letter-spacing: 0.04em;
  color: var(--d-ink);
}
.vlx-demo-bar .vlx-demo-live {
  margin-left: auto;
  display: inline-flex;
  align-items: center;
  gap: 6px;
  font-size: 10px;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  font-weight: 700;
  color: var(--d-muted);
}
.vlx-demo-dot {
  width: 7px; height: 7px; border-radius: 50%;
  background: var(--d-ok);
  box-shadow: 0 0 0 0 rgba(52, 211, 153, 0.6);
  animation: vlxDemoPulse 2.4s ease-out infinite;
}

/* Stage holds the staggered scene cards */
.vlx-demo-stage {
  position: relative;
  padding: 14px;
  height: calc(100% - 40px);
  display: flex;
  flex-direction: column;
  gap: 10px;
}

/* A generic card used for the inbound item + the verdict */
.vlx-demo-card {
  display: flex;
  align-items: flex-start;
  gap: 10px;
  padding: 11px 12px;
  border-radius: 12px;
  background: rgba(255, 255, 255, 0.035);
  border: 1px solid var(--d-panel-line);
  opacity: 0;
}
/* min-width:0 lets the text column shrink correctly inside the flex card. */
.vlx-demo-card > div { min-width: 0; }
.vlx-demo-card .vlx-demo-ic {
  flex: 0 0 auto;
  width: 30px; height: 30px; border-radius: 9px;
  display: grid; place-items: center;
}
.vlx-demo-card .vlx-demo-ic svg { width: 16px; height: 16px; }
.vlx-demo-ttl { margin: 0; font-size: 12.5px; font-weight: 700; color: var(--d-ink); line-height: 1.3; }
.vlx-demo-sub { margin: 2px 0 0; font-size: 11px; color: var(--d-muted); line-height: 1.4; word-break: break-word; }
.vlx-demo-pip {
  margin-left: auto;
  align-self: center;
  font-size: 9.5px; font-weight: 800; letter-spacing: 0.1em;
  padding: 4px 8px; border-radius: 999px;
  white-space: nowrap;
}

/* The inbound (suspicious) item */
.vlx-demo-inbound { animation: vlxDemoInbound 13s ease-in-out infinite; }
.vlx-demo-inbound .vlx-demo-ic { background: rgba(255, 255, 255, 0.06); color: var(--d-muted); }
.vlx-demo-inbound .vlx-demo-pip { background: rgba(255, 255, 255, 0.06); color: var(--d-muted); }

/* The scanning row */
.vlx-demo-scan {
  display: flex; align-items: center; gap: 9px;
  padding: 9px 12px; border-radius: 10px;
  background: var(--d-accent-soft);
  border: 1px solid var(--d-accent-line);
  font-size: 11px; font-weight: 600; color: var(--d-ink);
  opacity: 0;
  animation: vlxDemoScan 13s ease-in-out infinite;
}
.vlx-demo-scan .vlx-demo-spin {
  width: 13px; height: 13px; border-radius: 50%;
  border: 2px solid var(--d-accent-line);
  border-top-color: var(--d-accent);
  animation: vlxDemoSpin 0.8s linear infinite;
}
.vlx-demo-scanbar {
  margin-left: auto; width: 84px; height: 4px; border-radius: 999px;
  background: rgba(255, 255, 255, 0.08); overflow: hidden;
}
.vlx-demo-scanbar::after {
  content: ""; display: block; height: 100%; width: 40%;
  border-radius: 999px; background: var(--d-accent);
  animation: vlxDemoScanbar 13s ease-in-out infinite;
}

/* The verdict (threat caught) */
.vlx-demo-verdict {
  border-color: rgba(239, 68, 68, 0.4);
  background: var(--d-danger-soft);
  animation: vlxDemoVerdict 13s cubic-bezier(0.18, 0.9, 0.28, 1.2) infinite;
}
.vlx-demo-verdict .vlx-demo-ic { background: rgba(239, 68, 68, 0.2); color: #fff; }
.vlx-demo-verdict .vlx-demo-ic svg { stroke: #fff; }
.vlx-demo-verdict .vlx-demo-pip { background: var(--d-danger); color: #fff; }

/* Footer chip row: score + guardian/analyst standby */
.vlx-demo-foot {
  margin-top: auto;
  display: flex; align-items: center; gap: 8px;
  opacity: 0;
  animation: vlxDemoFoot 13s ease-in-out infinite;
}
.vlx-demo-chip {
  display: inline-flex; align-items: center; gap: 6px;
  padding: 6px 10px; border-radius: 999px;
  font-size: 10.5px; font-weight: 700; color: var(--d-ink);
  background: rgba(255, 255, 255, 0.045);
  border: 1px solid var(--d-panel-line);
}
.vlx-demo-chip b { color: var(--d-accent); font-weight: 800; }
.vlx-demo-chip--ok b { color: var(--d-ok); }

/* Caption beneath the window — honest "animated preview" label */
.vlx-demo-cap {
  position: absolute;
  left: 0; right: 0; bottom: 8px;
  text-align: center;
  font-size: 10.5px; letter-spacing: 0.06em;
  color: rgba(199, 207, 217, 0.45);
}

/* ── Timeline keyframes (one shared 13s loop) ──────────────────
 * Scene beats (of 13s):
 *   0.7s  inbound item slides in
 *   3.0s  scanning row appears, bar fills
 *   5.6s  verdict pops (danger), scan fades
 *   7.4s  footer chips (score + standby) rise
 *   11.4s hold, then fade for the loop seam
 */
@keyframes vlxDemoInbound {
  0%, 3%   { opacity: 0; transform: translateY(10px) scale(0.99); }
  6%, 92%  { opacity: 1; transform: none; }
  98%,100% { opacity: 0; transform: translateY(-6px); }
}
@keyframes vlxDemoScan {
  0%, 20%  { opacity: 0; transform: translateY(8px); }
  24%, 42% { opacity: 1; transform: none; }
  48%,100% { opacity: 0; transform: translateY(-4px); }
}
@keyframes vlxDemoScanbar {
  0%, 20%  { width: 6%; }
  44%      { width: 100%; }
  48%,100% { width: 100%; }
}
@keyframes vlxDemoVerdict {
  0%, 42%  { opacity: 0; transform: translateY(12px) scale(0.96); }
  48%      { opacity: 1; transform: translateY(0) scale(1.015); }
  52%, 92% { opacity: 1; transform: none; }
  98%,100% { opacity: 0; transform: translateY(-6px); }
}
@keyframes vlxDemoFoot {
  0%, 56%  { opacity: 0; transform: translateY(8px); }
  62%, 92% { opacity: 1; transform: none; }
  98%,100% { opacity: 0; }
}
@keyframes vlxDemoSpin { to { transform: rotate(360deg); } }
@keyframes vlxDemoPulse {
  0%   { box-shadow: 0 0 0 0 rgba(52, 211, 153, 0.55); }
  70%  { box-shadow: 0 0 0 7px rgba(52, 211, 153, 0); }
  100% { box-shadow: 0 0 0 0 rgba(52, 211, 153, 0); }
}

/* Small screens: tighten the inbound subject so the fake URL/email
 * doesn't overflow the card on narrow mobiles. */
@media (max-width: 560px) {
  .vlx-demo-sub { font-size: 10px; }
  .vlx-demo-ttl { font-size: 11.5px; }
  .vlx-demo-foot { flex-wrap: wrap; }
  /* Let the demo flow to natural height on phones so the verdict + footer
     cards are never clipped by the aspect-locked, overflow:hidden frame.
     Covers BOTH the consumer .vlx-demo-frame and the business .biz-video-slot
     (app.css) that wraps the same demo. */
  .vlx-demo { position: static; }
  .vlx-demo-frame,
  .vlx-demo-frame--center,
  .biz-video-slot { aspect-ratio: auto; overflow: visible; }
  .vlx-demo-app { aspect-ratio: auto; height: auto; min-height: 0; }
  .vlx-demo-stage { height: auto; }
}

/* Accessibility: freeze on the "threat caught" final state for
 * anyone who prefers reduced motion — no loop, no spinner. */
@media (prefers-reduced-motion: reduce) {
  .vlx-demo-inbound,
  .vlx-demo-scan,
  .vlx-demo-scanbar::after,
  .vlx-demo-verdict,
  .vlx-demo-foot,
  .vlx-demo-dot,
  .vlx-demo-spin { animation: none !important; }
  .vlx-demo-scan { display: none; }
  .vlx-demo-inbound,
  .vlx-demo-verdict,
  .vlx-demo-foot { opacity: 1; transform: none; }
}

/* Off-screen pause — _shared/vlx-demo.js toggles .vlx-demo--paused via
   IntersectionObserver so every animation freezes while the demo is scrolled
   out of view (zero CPU/GPU off-screen). Pure presentation; the script only
   flips the class and no-ops under reduced motion. */
.vlx-demo--paused,
.vlx-demo--paused * { animation-play-state: paused !important; }
