/* ════════════════════════════════════════════════════════════════════════════
   AURON — MOTION LAYER  ·  "HUD power-on"
   A self-contained, additive animation system. Loaded AFTER styles.css, so it
   layers premium motion onto the existing HUD aesthetic without touching it.
   Everything keys off the existing tokens (--accent-rgb, --bg-elev-*, --r-*).
   All reveal-hiding is gated behind body.anim-ready (set by animations.js only),
   so if JS never runs, nothing is ever hidden — content is always visible.
   Honors prefers-reduced-motion at the bottom.
   ════════════════════════════════════════════════════════════════════════════ */

:root {
  --mo-out:    cubic-bezier(0.16, 1, 0.3, 1);     /* decel — entrances        */
  --mo-spring: cubic-bezier(0.34, 1.4, 0.5, 1);   /* gentle overshoot — modals */
  --mo-snap:   cubic-bezier(0.5, 0, 0.2, 1);      /* press / state            */
  --mo-d1: 0.32s; --mo-d2: 0.5s; --mo-d3: 0.7s;
  --mo-stagger: 42ms;
}

/* ─────────────────────── 1 · STAGGERED REVEALS ────────────────────────────
   JS adds .mo-hide (initial state) + .mo-in (play) and sets --mo-i (index) for
   stagger. animation-fill-mode: both → ends visible even if the trigger races. */
body.anim-ready .mo-hide { opacity: 0; }
body.anim-ready .mo-hide.mo-in {
  animation: moRise var(--mo-d2) var(--mo-out) both;   /* `both` holds the visible
                       end-state — `backwards` would revert to .mo-hide opacity:0. */
  animation-delay: calc(var(--mo-i, 0) * var(--mo-stagger));
}
@keyframes moRise {
  from { opacity: 0; transform: translateY(16px) scale(0.985); filter: blur(2px); }
  60%  { opacity: 1; filter: blur(0); }
  to   { opacity: 1; transform: none; filter: blur(0); }
}

/* ─────────────────── 2 · VIEW "POWER-ON" (pure CSS, per switch) ────────────
   .view toggles display:none↔grid, so these replay on EVERY view change.
   The whole view fades up; the topbar gets a cyan scan-line sweep underneath. */
.view { animation: moViewIn 0.45s var(--mo-out) both; }
@keyframes moViewIn {
  from { opacity: 0; transform: translateY(8px); }
  to   { opacity: 1; transform: none; }
}
.topbar { position: relative; }
.topbar::after {
  content: ""; position: absolute; left: 0; bottom: -1px; height: 1px; width: 100%;
  background: linear-gradient(90deg, transparent, rgb(var(--accent-rgb) / 0.9), transparent);
  transform: scaleX(0); transform-origin: left;
  animation: moSweep 0.9s var(--mo-out) 0.1s both;
  opacity: 0.7; pointer-events: none;
}
@keyframes moSweep { to { transform: scaleX(1); opacity: 0; } }

/* Headline / hero text rises in on each view */
.view h1, .ap-label, .page-title,
.view-voice h2, .view-skills h2, .view-connectors h2 {
  animation: moRise 0.6s var(--mo-out) both;
}

/* ───────────────────── 3 · TACTILE MICRO-INTERACTIONS ──────────────────────
   Buttons: a light sheen sweeps across on hover; a crisp press on click.
   Targets the app's real button classes; purely additive transitions. */
.primary-btn, .ghost-btn, .danger-btn, .pill, .conn-btn, .seg-btn,
.mode-btn, .ap-mode-btn, .icon-btn, .voice-mode-btn {
  position: relative; overflow: hidden;
  transition: transform 0.16s var(--mo-snap), box-shadow 0.22s var(--mo-out),
              border-color 0.22s var(--mo-out), background 0.22s var(--mo-out);
}
.primary-btn::before, .ghost-btn::before, .conn-btn::before {
  content: ""; position: absolute; inset: 0;
  background: linear-gradient(110deg, transparent 30%, rgb(255 255 255 / 0.14) 50%, transparent 70%);
  transform: translateX(-130%); transition: transform 0.6s var(--mo-out);
  pointer-events: none;
}
.primary-btn:hover::before, .ghost-btn:hover::before, .conn-btn:hover::before { transform: translateX(130%); }
.primary-btn:hover, .conn-btn:hover { transform: translateY(-1px); box-shadow: 0 6px 20px rgb(var(--accent-blue-rgb) / 0.35); }
.ghost-btn:hover { transform: translateY(-1px); border-color: rgb(var(--accent-rgb) / 0.4); }
.primary-btn:active, .ghost-btn:active, .danger-btn:active, .pill:active, .conn-btn:active { transform: translateY(0) scale(0.97); }

/* Click ripple (spawned by animations.js) */
.mo-ripple {
  position: absolute; border-radius: 999px; pointer-events: none;
  background: radial-gradient(circle, rgb(var(--accent-rgb) / 0.45), transparent 70%);
  transform: translate(-50%, -50%) scale(0); animation: moRipple 0.6s var(--mo-out) forwards;
}
@keyframes moRipple { to { transform: translate(-50%, -50%) scale(1); opacity: 0; } }

/* Nav items: slide + a growing accent rail on hover/active */
.nav-item { position: relative; transition: color 0.2s var(--mo-out), transform 0.2s var(--mo-out); }
.nav-item::before {
  content: ""; position: absolute; left: 0; top: 18%; bottom: 18%; width: 2px; border-radius: 2px;
  background: var(--accent); transform: scaleY(0); transform-origin: center;
  transition: transform 0.26s var(--mo-spring); box-shadow: 0 0 10px rgb(var(--accent-rgb) / 0.6);
}
.nav-item:hover { transform: translateX(3px); }
.nav-item:hover::before, .nav-item.active::before { transform: scaleY(1); }

/* Inputs: an animated focus glow ring */
#input, .set-input, .set-textarea, .mem-feed-search, #voice-sample-text, #voice-sample-title,
.modal input, .modal textarea, .login-creds input {
  transition: border-color 0.25s var(--mo-out), box-shadow 0.3s var(--mo-out), background 0.25s var(--mo-out);
}
#input:focus, .set-input:focus, .set-textarea:focus, .mem-feed-search:focus,
#voice-sample-text:focus, #voice-sample-title:focus, .modal input:focus, .modal textarea:focus,
.login-creds input:focus {
  box-shadow: 0 0 0 3px rgb(var(--accent-rgb) / 0.16), 0 0 22px rgb(var(--accent-rgb) / 0.12);
  border-color: rgb(var(--accent-rgb) / 0.55);
}

/* Cards: lift + accent-edge glow on hover (rises above the existing hover) */
.project-card, .conn-tile, .mem-atom, .ap-card, .aside-card, .skill-card, .skill-row, .history-item {
  transition: transform 0.24s var(--mo-out), box-shadow 0.28s var(--mo-out), border-color 0.28s var(--mo-out);
}
.project-card:hover, .conn-tile:hover, .ap-card:hover, .skill-card:hover, .skill-row:hover, .history-item:hover {
  transform: translateY(-3px);
  box-shadow: 0 14px 34px rgb(0 0 0 / 0.4), 0 0 0 1px rgb(var(--accent-rgb) / 0.22);
}

/* Suggestion / starter chips: gentle hover */
.suggestion, .starter, .palette-item { transition: transform 0.18s var(--mo-out), background 0.2s var(--mo-out); }
.suggestion:hover, .starter:hover { transform: translateX(4px); }

/* ───────────────────────── 4 · MODALS / OVERLAYS ───────────────────────────
   Backdrops fade their blur in; the panel springs up. Applies to every modal
   the app already uses (they toggle .hidden, so this replays on each open). */
.modal-backdrop:not(.hidden), .paywall-overlay:not(.hidden), .palette-backdrop:not(.hidden),
.school-modal-backdrop:not(.hidden), .auth-overlay:not(.hidden) {
  animation: moBackdrop 0.3s var(--mo-out) both;
}
@keyframes moBackdrop { from { opacity: 0; backdrop-filter: blur(0); } to { opacity: 1; } }
.modal-backdrop:not(.hidden) > .modal, .modal-backdrop:not(.hidden) > .import-modal,
.palette-backdrop:not(.hidden) > *, .school-modal-backdrop:not(.hidden) > * {
  animation: moPanel 0.42s var(--mo-spring) both;
}
@keyframes moPanel {
  from { opacity: 0; transform: translateY(18px) scale(0.96); }
  to   { opacity: 1; transform: none; }
}

/* ───────────────────────── 5 · CHAT MESSAGES ───────────────────────────────
   Each message materializes; the assistant avatar pulses once as it arrives. */
.msg { animation: moMsgIn 0.5s var(--mo-out) both; }
@keyframes moMsgIn {
  from { opacity: 0; transform: translateY(12px); }
  to   { opacity: 1; transform: none; }
}
.msg.assistant .msg-avatar, .msg .msg-avatar { animation: moAvatar 0.7s var(--mo-out) both; }
@keyframes moAvatar {
  from { transform: scale(0.5); opacity: 0; }
  60%  { transform: scale(1.12); }
  to   { transform: scale(1); opacity: 1; }
}
/* live "thinking" dots while a reply streams (added by animations.js if absent) */
.mo-typing { display: inline-flex; gap: 4px; }
.mo-typing i { width: 6px; height: 6px; border-radius: 50%; background: var(--accent); animation: moDot 1.1s ease-in-out infinite; }
.mo-typing i:nth-child(2) { animation-delay: 0.18s; }
.mo-typing i:nth-child(3) { animation-delay: 0.36s; }
@keyframes moDot { 0%,80%,100% { opacity: 0.25; transform: translateY(0); } 40% { opacity: 1; transform: translateY(-4px); } }

/* ───────────────────── 6 · AMBIENT HUD (subtle, always-on) ──────────────────
   The brand orb gets a slow breathing halo. Sidebar brand glow. Kept faint so
   it never competes with the chat/constellation FX. */
.brand-icon, .orb, .composer .send-btn, #send-btn {
  /* a soft accent breathing on the key "alive" elements */
}
.brand-icon::after, .orb::after {
  content: ""; position: absolute; inset: -4px; border-radius: inherit;
  box-shadow: 0 0 18px rgb(var(--accent-rgb) / 0.45); opacity: 0.5;
  animation: moBreathe 3.4s ease-in-out infinite; pointer-events: none;
}
.brand-icon, .orb { position: relative; }
@keyframes moBreathe { 0%,100% { opacity: 0.32; } 50% { opacity: 0.7; } }

/* Connected-status dot: live ping */
.status-dot, .conn-dot.connected, .dot-live {
  position: relative;
}
.status-dot::after {
  content: ""; position: absolute; inset: 0; border-radius: 50%;
  box-shadow: 0 0 0 0 rgb(var(--accent-rgb) / 0.5); animation: moPing 2.2s var(--mo-out) infinite;
}
@keyframes moPing { to { box-shadow: 0 0 0 7px rgb(var(--accent-rgb) / 0); } }

/* Badges / pills that appear: a tiny pop */
.pw-popular, .pw-tag, .badge-new { animation: moPop 0.5s var(--mo-spring) both; }
@keyframes moPop { from { opacity: 0; transform: scale(0.6); } to { opacity: 1; transform: scale(1); } }

/* ───────────────── 7 · SKELETON SHIMMER (loading states) ────────────────── */
.skeleton, .skel-card, .skel-line {
  background: linear-gradient(90deg, var(--bg-elev-1) 25%, var(--bg-elev-3) 37%, var(--bg-elev-1) 63%);
  background-size: 400% 100%; animation: moShimmer 1.4s ease-in-out infinite;
}
@keyframes moShimmer { from { background-position: 100% 0; } to { background-position: -100% 0; } }

/* ════════════════════════ 8b · REFINEMENTS (round 2) ════════════════════════ */

/* Sidebar boots up — its sections cascade in once on load. Pure CSS + fill:both,
   so it always ends visible (never depends on JS). */
.sidebar > * { animation: moRise 0.5s var(--mo-out) both; }
.sidebar > *:nth-child(1) { animation-delay: 0.02s; } .sidebar > *:nth-child(2) { animation-delay: 0.06s; }
.sidebar > *:nth-child(3) { animation-delay: 0.10s; } .sidebar > *:nth-child(4) { animation-delay: 0.14s; }
.sidebar > *:nth-child(5) { animation-delay: 0.18s; } .sidebar > *:nth-child(6) { animation-delay: 0.22s; }
.sidebar > *:nth-child(7) { animation-delay: 0.26s; } .sidebar > *:nth-child(n+8) { animation-delay: 0.30s; }

/* Toggle knobs glide (smooths whatever transform the app already sets; value untouched). */
.set-toggle .seg-knob, .toggle-btn .seg-knob { transition: transform 0.28s var(--mo-spring), background 0.2s var(--mo-out) !important; }

/* Settings tab content fades up when its tab is selected. */
.settings-tab-content.active { animation: moRise 0.4s var(--mo-out) both; }

/* Send button: lifts + glows on hover, springs on press. */
.send-btn, #send-btn, #project-send-btn { transition: transform 0.18s var(--mo-spring), box-shadow 0.24s var(--mo-out) !important; }
.send-btn:hover, #send-btn:hover, #project-send-btn:hover { transform: scale(1.06); box-shadow: 0 0 20px rgb(var(--accent-blue-rgb) / 0.5); }
.send-btn:active, #send-btn:active, #project-send-btn:active { transform: scale(0.92); }

/* Keyboard focus: a crisp accent ring (accessibility + premium feel). */
button:focus-visible, a:focus-visible, .nav-item:focus-visible, .pill:focus-visible,
[role="button"]:focus-visible, .seg-btn:focus-visible {
  outline: 2px solid rgb(var(--accent-rgb) / 0.6); outline-offset: 2px; border-radius: var(--r-sm);
}

/* The composer gets a soft accent glow when the input is focused (modern :has). */
.composer:has(textarea:focus) { box-shadow: 0 -1px 30px rgb(var(--accent-rgb) / 0.07); }

/* ════════════════════════ 8c · REFINEMENTS (round 3) ════════════════════════ */

/* View-switch "HUD refresh": a faint cyan scan-band sweeps across the screen on
   every view change (injected + removed by animations.js). Subtle + quick. */
.mo-wipe {
  position: fixed; inset: 0; z-index: 95; pointer-events: none; will-change: transform;
  background: linear-gradient(100deg, transparent 42%, rgb(var(--accent-rgb) / 0.05) 48%,
              rgb(var(--accent-rgb) / 0.13) 50%, rgb(var(--accent-rgb) / 0.05) 52%, transparent 58%);
  transform: translateX(-100%); animation: moWipe 0.6s var(--mo-out) forwards;
}
@keyframes moWipe { to { transform: translateX(100%); } }

/* Card cursor-spotlight: a soft accent glow tracks the pointer on hover
   (animations.js appends .mo-spot to the hovered card + tracks the cursor).
   Low alpha + on top → reads as a highlight, never obscures text. */
.mo-spot {
  position: absolute; inset: 0; border-radius: inherit; pointer-events: none; z-index: 1;
  background: radial-gradient(200px circle at var(--mx, 50%) var(--my, 50%),
              rgb(var(--accent-rgb) / 0.10), transparent 56%);
  opacity: 0; transition: opacity 0.3s var(--mo-out);
}
.mo-spot.on { opacity: 1; }

/* Active pill / tab / mode: a satisfying pop the moment it's selected. */
.pill.active, .seg-btn.active, .settings-tab.active, .ap-mode-btn.active, .voice-mode-btn.active,
.task-filter.active, .mode-btn.active, .conn-btn.active { animation: moPop 0.34s var(--mo-spring); }

/* ─────────────────────── 8 · REDUCED MOTION ────────────────────────────────
   Respect the user's OS setting — kill all decorative motion, keep it instant. */
@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after {
    animation-duration: 0.001ms !important; animation-iteration-count: 1 !important;
    transition-duration: 0.001ms !important;
  }
  body.anim-ready .mo-hide { opacity: 1 !important; }
}
