/* Motion: hover and press feedback, entrances, tooltips, toasts, dialogs and
   loading states. Loaded after components.css. Durations come from tokens.css
   and drop to 0 for users who prefer reduced motion; entrance and decorative
   animations are only declared when motion is welcome. */

/* ---------- Keyframes ---------- */

@keyframes rise {
  from {
    opacity: 0;
    transform: translateY(10px);
  }
}

@keyframes fade-in {
  from {
    opacity: 0;
  }
}

@keyframes fade-out {
  to {
    opacity: 0;
  }
}

@keyframes drop-in {
  from {
    opacity: 0;
    transform: translateY(-6px) scale(0.97);
  }
}

@keyframes pop {
  0% { transform: scale(0.6); }
  60% { transform: scale(1.15); }
  100% { transform: scale(1); }
}

@keyframes shake {
  0%, 100% { transform: translateX(0); }
  20% { transform: translateX(-5px); }
  40% { transform: translateX(4px); }
  60% { transform: translateX(-3px); }
  80% { transform: translateX(2px); }
}

@keyframes ripple {
  to {
    opacity: 0;
    transform: translate(-50%, -50%) scale(1);
  }
}

@keyframes float {
  0%, 100% { transform: translateY(0); }
  50% { transform: translateY(-5px); }
}

@keyframes pulse-ring {
  0% { box-shadow: 0 0 0 0 var(--pulse-color, var(--color-pulse-danger)); }
  70% { box-shadow: 0 0 0 7px transparent; }
  100% { box-shadow: 0 0 0 0 transparent; }
}

@keyframes glow {
  0% { box-shadow: 0 0 0 1px var(--color-accent), 0 0 0 0 var(--color-pulse); }
  100% { box-shadow: 0 0 0 1px var(--color-accent), 0 0 0 10px transparent; }
}

@keyframes countdown {
  from { transform: scaleX(1); }
  to { transform: scaleX(0); }
}

@keyframes page-progress {
  0% { transform: scaleX(0); }
  20% { transform: scaleX(0.35); }
  60% { transform: scaleX(0.7); }
  100% { transform: scaleX(0.92); }
}

@keyframes toast-enter {
  from {
    opacity: 0;
    transform: translateX(24px) scale(0.96);
  }
}

@keyframes toast-leave {
  to {
    opacity: 0;
    transform: translateX(32px) scale(0.96);
  }
}

@keyframes modal-out {
  to {
    opacity: 0;
    transform: translateY(6px) scale(0.98);
  }
}

@keyframes spin-in {
  from {
    opacity: 0;
    transform: rotate(-90deg) scale(0.6);
  }
}

/* ---------- Links and text ---------- */

html {
  scroll-behavior: smooth;
}

@media (prefers-reduced-motion: reduce) {
  html {
    scroll-behavior: auto;
  }
}

a {
  transition: color var(--duration-fast), text-decoration-color var(--duration-base),
    text-underline-offset var(--duration-base) var(--ease-out);
}

a:hover {
  text-underline-offset: 0.3em;
}

/* Quiet links (footer, menus) reveal their underline on hover. */
.footer__links a,
.auth-page__switch a {
  text-decoration-line: underline;
  text-decoration-color: transparent;
}

.footer__links a:hover,
.auth-page__switch a:hover {
  text-decoration-color: currentColor;
}

.field__label {
  transition: color var(--duration-fast);
}

.field:focus-within .field__label {
  color: var(--color-accent);
}

/* ---------- Buttons ---------- */

/* :where() keeps specificity at zero so absolutely positioned buttons
   (password toggle) keep their own position. */
:where(.btn) {
  position: relative;
}

.btn {
  transition: background var(--duration-fast), border-color var(--duration-fast),
    color var(--duration-fast), box-shadow var(--duration-base) var(--ease-out),
    transform var(--duration-base) var(--ease-out);
}

.btn .icon {
  transition: transform var(--duration-base) var(--ease-out);
}

@media (hover: hover) {
  .btn--primary:hover {
    transform: translateY(-1px);
    box-shadow: var(--shadow-accent);
  }

  .btn--danger:hover {
    transform: translateY(-1px);
    box-shadow: var(--shadow-danger);
  }

  .btn--secondary:hover {
    transform: translateY(-1px);
    box-shadow: var(--shadow-sm);
  }

  /* Trailing icons (e.g. arrows) nudge forward. */
  .btn:hover > .icon:last-child:not(:first-child) {
    transform: translateX(3px);
  }

  .btn--icon:hover .icon {
    transform: scale(1.12);
  }
}

.btn:active {
  transform: translateY(0) scale(0.97);
  box-shadow: none;
  transition-duration: 60ms;
}

.password-field__toggle:active {
  transform: translateY(-50%) scale(0.92);
}

/* Click ripple, added by motion.js inside a clipping layer. */
.btn__ripples {
  position: absolute;
  inset: 0;
  overflow: hidden;
  border-radius: inherit;
  pointer-events: none;
}

.btn__ripple {
  position: absolute;
  width: var(--ripple-size, 100px);
  height: var(--ripple-size, 100px);
  border-radius: 50%;
  background: var(--color-ripple);
  opacity: 1;
  transform: translate(-50%, -50%) scale(0);
  animation: ripple 550ms var(--ease-out) forwards;
}

.btn--secondary .btn__ripple,
.btn--ghost .btn__ripple {
  background: var(--color-ripple-dark);
}

/* Busy state while a form submits: the label stays (keeps the width) but
   fades, and a spinner takes its place. */
.btn[data-busy] {
  pointer-events: none;
}

.btn[data-busy] > :not(.btn__ripples) {
  opacity: 0;
}

.btn[data-busy]::after {
  content: "";
  position: absolute;
  inset: 0;
  margin: auto;
  width: 1rem;
  height: 1rem;
  border: 2px solid currentColor;
  border-right-color: transparent;
  border-radius: 50%;
  animation: spin 0.7s linear infinite;
}

/* ---------- Tooltips (icon-only buttons and [data-tooltip]) ---------- */

@media (hover: hover) {
  [data-tooltip] {
    position: relative;
  }

  .password-field__toggle[data-tooltip] {
    position: absolute;
  }

  [data-tooltip]::before {
    content: attr(data-tooltip);
    position: absolute;
    top: calc(100% + 6px);
    left: 50%;
    z-index: var(--z-dropdown);
    padding: var(--space-1) var(--space-2);
    border-radius: var(--radius-sm);
    background: var(--color-text);
    color: var(--color-text-inverse);
    font-size: var(--text-xs);
    font-weight: var(--weight-medium);
    line-height: var(--leading-snug);
    white-space: nowrap;
    pointer-events: none;
    opacity: 0;
    transform: translate(-50%, -3px);
    transition: opacity var(--duration-fast), transform var(--duration-base) var(--ease-out);
  }

  [data-tooltip]:hover::before,
  [data-tooltip]:focus-visible::before {
    opacity: 1;
    transform: translate(-50%, 0);
    transition-delay: 350ms;
  }

  [data-tooltip][data-busy]::before {
    display: none;
  }

  /* Buttons at the right edge open their tooltip to the left. */
  .navbar__end [data-tooltip]::before {
    left: auto;
    right: 0;
    transform: translateY(-3px);
  }

  .navbar__end [data-tooltip]:hover::before,
  .navbar__end [data-tooltip]:focus-visible::before {
    transform: none;
  }
}

/* ---------- Navbar and user menu ---------- */

.navbar__logo {
  transition: transform var(--duration-slow) var(--ease-spring);
}

.navbar__brand:hover .navbar__logo {
  transform: rotate(-10deg) scale(1.08);
}

.navbar__status {
  transition: background var(--duration-fast), border-color var(--duration-fast),
    transform var(--duration-base) var(--ease-out);
}

.navbar__status:hover {
  transform: translateY(-1px);
  border-color: var(--color-border-strong);
}

.user-menu__trigger {
  transition: background var(--duration-fast);
}

.user-menu__trigger .icon--chevron {
  transition: transform var(--duration-base) var(--ease-out);
}

.user-menu[open] .user-menu__trigger .icon--chevron {
  transform: rotate(180deg);
}

.avatar {
  transition: box-shadow var(--duration-base), transform var(--duration-base) var(--ease-spring);
}

.user-menu__trigger:hover .avatar,
.user-menu[open] .avatar {
  box-shadow: 0 0 0 2px var(--color-bg), 0 0 0 4px var(--color-accent-border);
}

.user-menu__item {
  transition: background var(--duration-fast), color var(--duration-fast);
}

.user-menu__item .icon {
  transition: transform var(--duration-base) var(--ease-out), color var(--duration-fast);
}

.user-menu__item:hover .icon {
  transform: translateX(2px);
  color: var(--color-accent);
}

/* ---------- Form fields ---------- */

.select {
  transition: border-color var(--duration-fast), box-shadow var(--duration-fast);
}

.checkbox__input {
  transition: transform var(--duration-fast);
}

.checkbox:hover .checkbox__input {
  transform: scale(1.06);
}

/* ---------- Cards, plans and lists ---------- */

.plan-card {
  transition: transform var(--duration-slow) var(--ease-out),
    box-shadow var(--duration-slow) var(--ease-out), border-color var(--duration-base);
}

.plan-feature .icon {
  transition: transform var(--duration-base) var(--ease-spring);
}

@media (hover: hover) {
  .plan-card:hover {
    transform: translateY(-4px);
    box-shadow: var(--shadow-raised);
    border-color: var(--color-accent-border);
  }

  .plan-card--current:hover {
    border-color: var(--color-accent);
    box-shadow: 0 0 0 1px var(--color-accent), var(--shadow-raised);
  }

  .plan-card:hover .plan-feature:not(.plan-feature--excluded) .icon {
    transform: scale(1.2);
  }

  .feature {
    transition: transform var(--duration-slow) var(--ease-out);
  }

  .feature:hover {
    transform: translateY(-3px);
  }

  .feature__icon {
    transition: transform var(--duration-slow) var(--ease-spring), background var(--duration-base);
  }

  .feature:hover .feature__icon {
    transform: scale(1.08) rotate(-4deg);
  }

  .member-row .avatar:hover {
    transform: scale(1.08);
  }
}

.result-item__title a,
.citation,
.pagination__link {
  transition: color var(--duration-fast), background var(--duration-fast),
    border-color var(--duration-fast), transform var(--duration-base) var(--ease-out);
}

a.citation:hover {
  transform: translateX(2px);
}

.badge {
  transition: background var(--duration-fast), border-color var(--duration-fast);
}

/* Details-based panels: content fades in when opened. */
.filter-panel[open] .filter-panel__body,
.research-steps[open] .research-steps__list {
  animation: drop-in var(--duration-base) var(--ease-out);
}

/* ---------- Page progress (top bar during navigation, motion.js) ---------- */

.page-progress {
  position: fixed;
  inset: 0 0 auto;
  z-index: var(--z-toast);
  height: 2px;
  background: var(--color-accent);
  box-shadow: 0 0 8px var(--color-glow);
  transform: scaleX(0);
  transform-origin: left;
  opacity: 0;
  pointer-events: none;
}

.page-progress[data-active] {
  opacity: 1;
  /* Short delay: fast page loads never show the bar. */
  transition: opacity var(--duration-base) 150ms;
  animation: page-progress 6s cubic-bezier(0.1, 0.6, 0.3, 1) 150ms forwards;
}

/* ---------- Toasts ---------- */

.toast {
  position: relative;
  overflow: hidden;
  animation: toast-enter var(--duration-slow) var(--ease-spring);
}

.toast__icon {
  animation: spin-in var(--duration-slow) var(--ease-spring) 80ms backwards;
}

.toast[data-leaving] {
  opacity: 1;
  transform: none;
  transition: none;
  animation: toast-leave var(--duration-base) var(--ease-in) forwards;
}

/* Auto-hide countdown along the bottom edge; pauses on hover and focus. */
.toast[data-timed]::after {
  content: "";
  position: absolute;
  inset: auto 0 0;
  height: 2px;
  background: var(--toast-accent, var(--color-info));
  opacity: 0.45;
  transform-origin: left;
  animation: countdown var(--toast-duration, 5s) linear forwards;
}

.toast[data-paused]::after {
  animation-play-state: paused;
}

/* ---------- Dialogs ---------- */

.modal::backdrop {
  animation: fade-in var(--duration-base) var(--ease-out);
}

.modal[data-closing] {
  animation: modal-out var(--duration-base) var(--ease-in) forwards;
}

.modal[data-closing]::backdrop {
  animation: fade-out var(--duration-base) var(--ease-in) forwards;
}

/* Onboarding tour: animateClose() waits for modal-out on the dialog. */
.tour[open] {
  animation: fade-in var(--duration-base) var(--ease-out);
}

.tour[data-closing] {
  animation: modal-out var(--duration-base) var(--ease-in) forwards;
}

@media (prefers-reduced-motion: no-preference) {
  .tour__spotlight,
  .tour__card {
    transition: top var(--duration-base) var(--ease-out), left var(--duration-base) var(--ease-out),
      width var(--duration-base) var(--ease-out), height var(--duration-base) var(--ease-out);
  }
}

/* ---------- Entrances (only when motion is welcome) ---------- */

@media (prefers-reduced-motion: no-preference) {
  .page-header,
  .auth-card,
  .auth-page__switch,
  .hero .container > *,
  .error-page > * {
    animation: rise var(--duration-slow) var(--ease-out) backwards;
  }

  .auth-page__switch { animation-delay: 120ms; }
  .hero .container > :nth-child(2), .error-page > :nth-child(2) { animation-delay: calc(1 * var(--stagger)); }
  .hero .container > :nth-child(3), .error-page > :nth-child(3) { animation-delay: calc(2 * var(--stagger)); }
  .hero .container > :nth-child(4), .error-page > :nth-child(4) { animation-delay: calc(3 * var(--stagger)); }

  /* Staggered groups: each child rises a little after the previous one. */
  .page > .stack > *,
  .plan-grid > *,
  .landing-features .grid-auto > *,
  .meter-grid > *,
  .member-list > * {
    animation: rise var(--duration-slow) var(--ease-out) backwards;
    animation-delay: calc(80ms + var(--i, 0) * var(--stagger));
  }

  :is(.page > .stack, .plan-grid, .landing-features .grid-auto, .meter-grid, .member-list) > :nth-child(2) { --i: 1; }
  :is(.page > .stack, .plan-grid, .landing-features .grid-auto, .meter-grid, .member-list) > :nth-child(3) { --i: 2; }
  :is(.page > .stack, .plan-grid, .landing-features .grid-auto, .meter-grid, .member-list) > :nth-child(4) { --i: 3; }
  :is(.page > .stack, .plan-grid, .landing-features .grid-auto, .meter-grid, .member-list) > :nth-child(5) { --i: 4; }
  :is(.page > .stack, .plan-grid, .landing-features .grid-auto, .meter-grid, .member-list) > :nth-child(n + 6) { --i: 5; }

  .alert {
    animation: drop-in var(--duration-slow) var(--ease-out) backwards;
  }

  .field__error {
    animation: drop-in var(--duration-base) var(--ease-out) backwards;
  }

  /* A field that came back with a server-side error shakes once. */
  .field--invalid :is(.input, .select, .textarea) {
    animation: shake 380ms var(--ease-out) 150ms;
  }

  .checkbox__input:checked {
    animation: pop var(--duration-slow) var(--ease-spring);
  }

  .plan-card--current {
    animation: rise var(--duration-slow) var(--ease-out) backwards,
      glow 1.4s var(--ease-out) 500ms 2;
    animation-delay: calc(80ms + var(--i, 0) * var(--stagger)), 500ms;
  }

  .navbar__status--danger,
  .navbar__status--warning {
    animation: pulse-ring 1.8s var(--ease-out) 600ms 3;
  }

  .navbar__status--warning {
    --pulse-color: var(--color-pulse-warning);
  }

  .empty-state__icon {
    animation: float 4s ease-in-out infinite;
  }

  .navbar[data-open] .navbar__nav {
    animation: drop-in var(--duration-base) var(--ease-out);
  }

  .user-menu[open] .user-menu__panel {
    transform-origin: top right;
    animation: drop-in var(--duration-base) var(--ease-out);
  }

  /* Elements below the fold, revealed by motion.js when scrolled into view. */
  [data-reveal] {
    opacity: 0;
    transform: translateY(16px);
    transition: opacity 500ms var(--ease-out), transform 500ms var(--ease-out);
    transition-delay: calc(var(--i, 0) * var(--stagger));
  }

  [data-reveal="shown"] {
    opacity: 1;
    transform: none;
  }
}

/* ---------- Auto-hiding navbar and docking search bar ---------- */

@media (prefers-reduced-motion: no-preference) {
  .navbar {
    transition: transform var(--duration-slow) var(--ease-out);
  }

  /* The docked bar and sticky sidebars follow the navbar up and down. */
  .search-dock[data-docked] > .search-bar,
  .decision-layout__sticky {
    transition: top var(--duration-slow) var(--ease-out);
  }
}

/* Thinking indicator of the assistant (pulses while the model thinks). */
@keyframes thinking-pulse {
  0%, 100% { opacity: 1; transform: scale(1); }
  50% { opacity: 0.35; transform: scale(0.7); }
}

@media (prefers-reduced-motion: no-preference) {
  .thinking--live:not([data-done]) .thinking__pulse,
  .live-plan:not([data-done]) .thinking__pulse {
    animation: thinking-pulse 1.2s var(--ease-out) infinite;
  }
}

/* Loading placeholders: a highlight sweeps across (shows that something loads). */
@keyframes shimmer {
  from { background-position: 150% 0; }
  to { background-position: -50% 0; }
}

@media (prefers-reduced-motion: no-preference) {
  .skeleton {
    background-image: linear-gradient(
      90deg,
      transparent 0%,
      var(--color-bg-subtle) 45%,
      var(--color-surface) 50%,
      var(--color-bg-subtle) 55%,
      transparent 100%
    );
    background-size: 200% 100%;
    background-repeat: no-repeat;
    animation: shimmer 1.4s var(--ease-out) infinite;
  }
}

/* Planned research: tasks still being researched pulse softly. */
@media (prefers-reduced-motion: no-preference) {
  .live-plan__task[data-state="running"] .live-plan__name::before {
    --pulse-color: var(--color-pulse);
    animation: pulse-ring 1.6s var(--ease-out) infinite;
  }
}
