/* ============================================================
   VELTRIX OS — 2050 Living Holographic Layer (v2 — rewrite)
   Loaded AFTER app.css. Never edits app.css. Pure visual layer.
   Root cause of v1 being invisible: --vs-bg-card was fully opaque
   (#0f1420), so backdrop-filter had nothing translucent to blur,
   and --vs-border was a flat gray with no indigo tint. Both fixed
   at the source in app.css; this file now layers shadows/glow/
   motion on top of variables that are already correct.
   Naming convention: every new class/keyframe uses the `vx-` prefix.
   ============================================================ */

/* ── Typography ─────────────────────────────────────────────
   Space Grotesk <link> lives in the layout head (font-display:swap
   is set there). Tabular numbers stop KPI digits from jittering
   width during the count-up animation. */
h1, h2, h3, h4,
[class*="kpi"], [class*="stat"], [class*="value"] {
  font-family: 'Space Grotesk', 'Inter', system-ui, sans-serif;
}
.vx-kpi-value {
  font-family: 'Space Grotesk', 'Inter', system-ui, sans-serif;
  font-feature-settings: "tnum";
  font-variant-numeric: tabular-nums;
}

/* ── Theme smooth transition ─────────────────────────────────── */
:root, body {
  transition: background-color 0.5s ease, color 0.4s ease;
}
body, .vs-sidebar, .vs-topbar, .vs-main,
.dash-card, .dash-kpi-card, .dash-owner-card, .vx-card {
  transition: background 0.5s ease, background-color 0.5s ease, border-color 0.4s ease, box-shadow 0.4s ease;
}

/* ── Ambient orbs — large, clearly visible radial glows ──────── */
#orb-1, #orb-2, #orb-3 {
  position: fixed;
  border-radius: 50%;
  pointer-events: none;
  z-index: 0;
  will-change: transform;
}
#particle-canvas {
  position: fixed;
  inset: 0;
  width: 100vw;
  height: 100vh;
  z-index: 0;
  pointer-events: none;
}
.vs-main { position: relative; z-index: 1; }

#orb-1 {
  top: -200px; right: -100px;
  width: 900px; height: 900px;
  background: radial-gradient(circle, rgba(99,102,241,.35) 0%, transparent 70%);
  filter: blur(60px);
  animation: orb-drift-1 20s ease-in-out infinite alternate;
}
#orb-2 {
  bottom: -200px; left: -150px;
  width: 700px; height: 700px;
  background: radial-gradient(circle, rgba(139,92,246,.28) 0%, transparent 70%);
  filter: blur(50px);
  animation: orb-drift-2 28s ease-in-out infinite alternate-reverse;
}
#orb-3 {
  top: 40%; left: 40%;
  transform: translate(-50%, -50%);
  width: 500px; height: 500px;
  background: radial-gradient(circle, rgba(6,182,212,.18) 0%, transparent 70%);
  filter: blur(70px);
  animation: orb-drift-3 35s ease-in-out infinite alternate;
}
@keyframes orb-drift-1 { from { transform: translate(0,0); } to { transform: translate(-80px,60px); } }
@keyframes orb-drift-2 { from { transform: translate(0,0); } to { transform: translate(60px,-80px); } }
@keyframes orb-drift-3 { from { transform: translate(-50%,-50%); } to { transform: translate(calc(-50% + 40px), calc(-50% - 30px)); } }

/* Light mode — same glows, ~40% the alpha so they read as soft warmth
   rather than visible smudges on a white background */
[data-theme="light"] #orb-1 { background: radial-gradient(circle, rgba(99,102,241,.07) 0%, transparent 70%); }
[data-theme="light"] #orb-2 { background: radial-gradient(circle, rgba(139,92,246,.055) 0%, transparent 70%); }
[data-theme="light"] #orb-3 { background: radial-gradient(circle, rgba(6,182,212,.035) 0%, transparent 70%); }

[data-theme="vastu"] #orb-1 { background: radial-gradient(circle, rgba(245,158,11,.3) 0%, transparent 70%); }
[data-theme="vastu"] #orb-3 { background: radial-gradient(circle, rgba(251,191,36,.18) 0%, transparent 70%); }
/* orb-2 deliberately stays purple in vastu per spec */

/* ── Glassmorphism — now that --vs-bg-card/-alt/-input are real
   rgba() values at the source (app.css), backdrop-filter has
   something translucent to blur. No background override needed
   here anymore; we only add the blur + depth on top. Browsers
   without backdrop-filter support simply keep the flat translucent
   color with no blur — never opaque-broken, never fully invisible. */
.dash-card, .dash-kpi-card, .dash-owner-card, .vx-card,
[data-vx-animate] > div,
*[style*="background:var(--vs-bg-card)"], *[style*="background: var(--vs-bg-card)"] {
  position: relative;
  overflow: hidden;
}
@supports (backdrop-filter: blur(1px)) or (-webkit-backdrop-filter: blur(1px)) {
  .dash-card, .dash-kpi-card, .dash-owner-card, .vx-card,
  [data-vx-animate] > div,
  *[style*="background:var(--vs-bg-card)"], *[style*="background: var(--vs-bg-card)"] {
    backdrop-filter: blur(16px);
    -webkit-backdrop-filter: blur(16px);
  }
}
[data-theme="dark"] .dash-card, [data-theme="dark"] .dash-kpi-card, [data-theme="dark"] .dash-owner-card, [data-theme="dark"] .vx-card,
[data-theme="vastu"] .dash-card, [data-theme="vastu"] .dash-kpi-card, [data-theme="vastu"] .dash-owner-card, [data-theme="vastu"] .vx-card {
  box-shadow: 0 8px 32px rgba(0,0,0,.4), 0 1px 0 rgba(255,255,255,.05) inset, 0 0 0 1px rgba(99,102,241,.15);
  transition: transform 0.35s cubic-bezier(.25,.8,.25,1), box-shadow 0.35s cubic-bezier(.25,.8,.25,1), border-color 0.35s cubic-bezier(.25,.8,.25,1);
}
[data-theme="light"] .dash-card, [data-theme="light"] .dash-kpi-card, [data-theme="light"] .dash-owner-card, [data-theme="light"] .vx-card {
  box-shadow: 0 4px 24px rgba(99,102,241,.12), 0 1px 3px rgba(0,0,0,.08);
  border-color: rgba(99,102,241,.18);
  transition: transform 0.35s cubic-bezier(.25,.8,.25,1), box-shadow 0.35s cubic-bezier(.25,.8,.25,1), border-color 0.35s cubic-bezier(.25,.8,.25,1);
}

/* Holographic diagonal sheen (::before) — ::after stays free for the
   JS-driven mouse-follow specular highlight from CardTilt */
.dash-card::before, .dash-kpi-card::before, .dash-owner-card::before, .vx-card::before {
  content: '';
  position: absolute;
  inset: 0;
  border-radius: inherit;
  background: linear-gradient(135deg, rgba(255,255,255,.05) 0%, transparent 60%);
  pointer-events: none;
  z-index: 0;
}
.vx-tilt-active::after {
  content: '';
  position: absolute;
  inset: 0;
  border-radius: inherit;
  background: radial-gradient(circle at var(--vx-mx, 50%) var(--vx-my, 50%), rgba(255,255,255,.12), transparent 60%);
  pointer-events: none;
  z-index: 1;
  opacity: 0;
  transition: opacity .2s ease;
}
.vx-tilt-active:hover::after { opacity: 1; }
.dash-card, .dash-kpi-card, .dash-owner-card, .vx-card { transform-style: preserve-3d; }

/* ── Card hover — must be unmistakable, !important beats inline
   style attrs that would otherwise win on specificity ──────────── */
.dash-card:hover, .dash-kpi-card:hover, .dash-owner-card:hover, .vx-card:hover {
  transform: translateY(-5px) scale(1.01) !important;
  box-shadow: 0 20px 60px rgba(99,102,241,.35), 0 0 0 1px rgba(99,102,241,.5), 0 0 30px rgba(99,102,241,.2) !important;
  border-color: rgba(99,102,241,.6) !important;
}
[data-theme="light"] .dash-card:hover, [data-theme="light"] .dash-kpi-card:hover,
[data-theme="light"] .dash-owner-card:hover, [data-theme="light"] .vx-card:hover {
  box-shadow: 0 20px 60px rgba(99,102,241,.2), 0 0 0 1px rgba(99,102,241,.45) !important;
}

/* ── KPI breathing glow — out of phase like a living organism ─── */
@keyframes kpi-breathe {
  0%   { box-shadow: 0 0 0 0 rgba(99,102,241,.1); }
  50%  { box-shadow: 0 0 30px 5px rgba(99,102,241,.25), 0 8px 32px rgba(0,0,0,.3); }
  100% { box-shadow: 0 0 0 0 rgba(99,102,241,.1); }
}
.dash-kpi-grid .vx-card { animation: kpi-breathe 3s infinite ease-in-out; }
.dash-kpi-grid .vx-card:nth-child(1) { animation-delay: 0s; }
.dash-kpi-grid .vx-card:nth-child(2) { animation-delay: .8s; }
.dash-kpi-grid .vx-card:nth-child(3) { animation-delay: 1.6s; }
.dash-kpi-grid .vx-card:nth-child(4) { animation-delay: 2.4s; }
.dash-kpi-grid + .dash-kpi-grid .vx-card:nth-child(1) { animation-delay: .4s; }
.dash-kpi-grid + .dash-kpi-grid .vx-card:nth-child(2) { animation-delay: 1.2s; }
.dash-kpi-grid + .dash-kpi-grid .vx-card:nth-child(3) { animation-delay: 2s; }
.dash-kpi-grid + .dash-kpi-grid .vx-card:nth-child(4) { animation-delay: 2.8s; }
/* Hover/tilt/flash all win over the idle breathing animation so the
   effects never visually fight over box-shadow at the same time */
.vx-card:hover, .vx-card.vx-tilt-active, .vx-card.flash, .vx-card.vx-kpi-glow-flash {
  animation-play-state: paused;
}

/* ── Card entrance — staggered fade-up, increasing by .07s ──────
   nth-child covers the 8 KPI cards across both grids; dash-card
   sections get the same treatment via nth-of-type within dash-wrap. */
@keyframes stagger-in {
  from { opacity: 0; transform: translateY(24px); }
  to   { opacity: 1; transform: translateY(0); }
}
[data-vx-animate] .vx-card {
  animation: stagger-in 0.5s ease-out both;
}
.dash-kpi-grid .vx-card:nth-child(1) { animation-delay: .05s; }
.dash-kpi-grid .vx-card:nth-child(2) { animation-delay: .12s; }
.dash-kpi-grid .vx-card:nth-child(3) { animation-delay: .19s; }
.dash-kpi-grid .vx-card:nth-child(4) { animation-delay: .26s; }
.dash-kpi-grid + .dash-kpi-grid .vx-card:nth-child(1) { animation-delay: .33s; }
.dash-kpi-grid + .dash-kpi-grid .vx-card:nth-child(2) { animation-delay: .4s; }
.dash-kpi-grid + .dash-kpi-grid .vx-card:nth-child(3) { animation-delay: .47s; }
.dash-kpi-grid + .dash-kpi-grid .vx-card:nth-child(4) { animation-delay: .54s; }
[data-vx-animate] .dash-card { animation: stagger-in 0.5s ease-out both; }
[data-vx-animate] .dash-col-left > .dash-card:nth-of-type(1) { animation-delay: .61s; }
[data-vx-animate] .dash-col-left > .dash-card:nth-of-type(2) { animation-delay: .68s; }
[data-vx-animate] .dash-col-left > .dash-card:nth-of-type(3) { animation-delay: .75s; }
[data-vx-animate] > .dash-card:nth-of-type(1) { animation-delay: .82s; }
[data-vx-animate] > .dash-card:nth-of-type(2) { animation-delay: .89s; }

/* Existing dash-flash keyframe (declared inline in dashboard.blade.php
   for the live-refresh ring) is equal specificity but declared later
   in document order than this stylesheet, so it still wins while
   .flash is present — untouched, not duplicated here. */

/* ── Sidebar ──────────────────────────────────────────────────── */
/* This file loads after app.css (see layout <head>), so at equal
   selector specificity its declarations win the cascade — every value
   here was hardcoded to indigo regardless of [data-theme], which is
   why fixes made only in app.css for light/vastu kept getting silently
   overridden. Rewritten to read the same theme tokens app.css defines,
   so this file can no longer drift out of sync with them again. */
[data-theme="dark"] .vs-sidebar, [data-theme="vastu"] .vs-sidebar {
  background: linear-gradient(180deg, rgba(6,8,16,.98) 0%, rgba(8,10,20,.96) 100%);
}
.vs-sidebar { position: relative; }
.vs-sidebar::before {
  content: '';
  display: block;
  position: absolute;
  top: 0; left: 0; right: 0;
  height: 3px;
  width: 100%;
  background: linear-gradient(90deg, var(--vs-accent), var(--vs-violet), var(--vs-accent-hover));
  z-index: 1;
}
[data-theme="light"] .vs-sidebar::before { display: none; }
.vs-nav-item.active {
  border-left: 3px solid var(--vs-accent);
  background: var(--vs-sidebar-active-bg);
  box-shadow: inset 3px 0 0 var(--vs-accent), 4px 0 20px var(--vs-accent-glow);
}
.vs-nav-item.active .vs-nav-icon { filter: drop-shadow(0 0 6px var(--vs-accent)); }
.vs-nav-item:not(.active):hover {
  transform: translateX(4px);
  background: var(--vs-accent-glow);
  transition: background .2s ease, transform .2s ease;
}
.vs-logo-text {
  background: linear-gradient(135deg, var(--logo-gradient-start), var(--logo-gradient-end));
  -webkit-background-clip: text;
  background-clip: text;
  -webkit-text-fill-color: transparent;
  color: transparent;
  font-weight: 800;
}
.vs-user-card .vs-avatar { box-shadow: 0 0 0 2px #22c55e, 0 0 12px rgba(34,197,94,.4); }
@keyframes vx-badge-pulse { 0%, 100% { transform: scale(1); } 50% { transform: scale(1.15); } }
.vs-nav-badge { animation: vx-badge-pulse 2s infinite; }

/* ── Topbar ───────────────────────────────────────────────────── */
[data-theme="dark"] .vs-topbar, [data-theme="vastu"] .vs-topbar {
  background: rgba(4,6,15,.85);
  backdrop-filter: blur(20px);
  -webkit-backdrop-filter: blur(20px);
  border-bottom: 1px solid var(--vs-border);
}
[data-theme="light"] .vs-topbar {
  background: rgba(255,255,255,.9);
  backdrop-filter: blur(20px);
  -webkit-backdrop-filter: blur(20px);
  border-bottom: 1px solid var(--vs-border);
}
@keyframes ai-pulse {
  0%, 100% { box-shadow: 0 0 0 0 rgba(34,197,94,.5); }
  50% { box-shadow: 0 0 12px 4px rgba(34,197,94,.3); }
}
#ws-dot { animation: ai-pulse 2s infinite; }

/* ── Business heartbeat overlay ───────────────────────────────
   --vx-heartbeat-speed / --vx-heartbeat-color are set on :root by
   BusinessHeartbeat in JS based on the health score already on page,
   inline-overriding the theme-scoped defaults below. Those defaults
   only matter when JS hasn't run yet or the health score is
   unavailable — kept theme-aware so that fallback path can't paint an
   indigo wash on a light/vastu sidebar either. */
[data-theme="light"] { --vx-heartbeat-color: rgba(199,93,58,.15); }
[data-theme="vastu"] { --vx-heartbeat-color: rgba(217,119,6,.15); }
.vs-sidebar { isolation: isolate; }
.vs-sidebar::after {
  content: '';
  position: absolute;
  inset: 0;
  pointer-events: none;
  z-index: 0;
  background: linear-gradient(180deg, transparent 0%, var(--vx-heartbeat-color, rgba(99,102,241,.15)) 100%);
  animation: vx-heartbeat-pulse var(--vx-heartbeat-speed, 3s) ease-in-out infinite;
}
@keyframes vx-heartbeat-pulse { 0%, 100% { opacity: 0; } 50% { opacity: 1; } }

/* ── Data ripple effect — sidebar icon → KPI card wave ───────── */
.vx-ripple {
  position: fixed;
  border-radius: 50%;
  border: 2px solid rgba(99,102,241,.6);
  pointer-events: none;
  z-index: 9500;
  transform: translate(-50%,-50%);
  width: 10px; height: 10px;
  opacity: 1;
  animation: vx-ripple-expand .6s ease-out forwards;
}
@keyframes vx-ripple-expand { to { width: 320px; height: 320px; opacity: 0; border-width: 1px; } }
.vx-kpi-glow-flash { animation: vx-kpi-glow-flash .8s ease-out; }
@keyframes vx-kpi-glow-flash {
  0% { box-shadow: 0 0 0 0 rgba(34,197,94,0); }
  30% { box-shadow: 0 0 32px 4px rgba(34,197,94,.45); }
  100% { box-shadow: 0 0 0 0 rgba(34,197,94,0); }
}
.vx-count-flash { color: #22c55e !important; transition: color .3s ease; }

/* ── Mobile — simplify, never break layout ─────────────────────── */
@media (max-width: 768px) {
  #orb-1, #orb-2, #orb-3 { display: none; }
  #particle-canvas { display: none; }
}

/* ── Reduced motion — disable animation, keep colors/glass ────── */
@media (prefers-reduced-motion: reduce) {
  #orb-1, #orb-2, #orb-3,
  .dash-kpi-grid .vx-card,
  .vs-nav-badge,
  #ws-dot,
  .vs-sidebar::after,
  [data-vx-animate] .vx-card,
  [data-vx-animate] .dash-card {
    animation: none !important;
  }
  .dash-card:hover, .dash-kpi-card:hover, .dash-owner-card:hover, .vx-card:hover,
  .vs-nav-item:not(.active):hover {
    transform: none !important;
  }
  #particle-canvas { display: none !important; }
}
