/*
 * CampaignKit motion
 *
 * Small, decorative animations. Nothing here delays a click or navigation:
 * every effect only dresses up something that already happened. Only
 * transform/opacity/background are animated, and the reduced-motion block
 * at the bottom turns all of it off.
 *
 * Prototype and rationale: https://claude.ai/artifact/J7Ce5jL1Z4ftfPwkKd6ZRX
 */

:root {
  --ck-fox: url("/assets/logo_mark-65d74623.png");
  --ck-violet: #6d28d9;
  --ck-fresh: #eff6ff;          /* primary-50 */
  --ck-pill: #eff6ff;           /* matches the old bg-primary-50 active link */
  --ck-shimmer: rgba(59, 130, 246, 0.12);
  --ck-ring-track: #e5e7eb;     /* dark-200 */
}

.dark {
  --ck-fox: url("/assets/logo_mark_dark-8689bb95.png");
  --ck-violet: #8b5cf6;
  --ck-fresh: rgba(30, 58, 138, 0.35);
  --ck-pill: rgba(30, 58, 138, 0.2);   /* primary-900/20 */
  --ck-shimmer: rgba(96, 165, 250, 0.14);
  --ck-ring-track: #374151;     /* dark-700 */
}

/* ---------------------------------------------------------------------------
 * A. Fox progress bar
 * Turbo shows .turbo-progress-bar when a visit takes longer than 500ms.
 * `html` prefix outranks the stylesheet Turbo injects at runtime.
 * ------------------------------------------------------------------------ */
html .turbo-progress-bar {
  height: 3px;
  background: linear-gradient(90deg, #2563eb, var(--ck-violet));
  border-radius: 0 3px 3px 0;
}

html .turbo-progress-bar::after {
  content: "";
  position: absolute;
  right: -9px;
  top: -3px;
  width: 18px;
  height: 19px;
  background: var(--ck-fox) center / contain no-repeat;
  animation: ck-bob 0.5s ease-in-out infinite alternate;
}

@keyframes ck-bob {
  to { transform: translateY(-1.5px) rotate(-4deg); }
}

/* ---------------------------------------------------------------------------
 * B. Page crossfade (Turbo view transitions, enabled by the meta tag in the
 * layout). Navbar and sidebar are captured separately and held still; only
 * the page content fades across. Browsers without view transitions skip it.
 * ------------------------------------------------------------------------ */
.ck-navbar { view-transition-name: ck-navbar; }
aside[data-sidebar-target="sidebar"] { view-transition-name: ck-sidebar; }

::view-transition-old(root) {
  animation: 160ms ease-in both ck-vt-out;
}

::view-transition-new(root) {
  animation: 260ms cubic-bezier(0.2, 0.7, 0.2, 1) 60ms both ck-vt-in;
}

::view-transition-group(ck-navbar),
::view-transition-group(ck-sidebar),
::view-transition-new(ck-navbar),
::view-transition-new(ck-sidebar) {
  animation: none;
}

::view-transition-old(ck-navbar),
::view-transition-old(ck-sidebar) {
  display: none;
}

@keyframes ck-vt-out {
  to { opacity: 0; transform: translateY(-3px); }
}

@keyframes ck-vt-in {
  from { opacity: 0; transform: translateY(6px); }
}

/* ---------------------------------------------------------------------------
 * I. Sidebar active highlight glides between items.
 * sidebar_controller moves the active link's background onto a pill element;
 * giving the pill a view-transition-name lets the browser morph it from the
 * old item to the new one during B.
 * ------------------------------------------------------------------------ */
aside .sidebar-link.ck-sidebar-active {
  position: relative;
  isolation: isolate;
  background-color: transparent;
}

.ck-sidebar-pill {
  position: absolute;
  inset: 0;
  z-index: -1;
  border-radius: inherit;
  background: var(--ck-pill);
  view-transition-name: ck-sidebar-pill;
}

::view-transition-group(ck-sidebar-pill) {
  animation-duration: 300ms;
  animation-timing-function: cubic-bezier(0.3, 0.7, 0.2, 1);
}

/* ---------------------------------------------------------------------------
 * C. Content settles in: direct children rise into place, 40ms apart.
 * Only put .ck-settle on containers rendered with the page, never inside a
 * frame that auto-refreshes, or the cards will re-animate every refresh.
 * ------------------------------------------------------------------------ */
.ck-settle > * {
  animation: ck-settle 0.4s cubic-bezier(0.2, 0.7, 0.2, 1) both;
}

.ck-settle > :nth-child(2) { animation-delay: 40ms; }
.ck-settle > :nth-child(3) { animation-delay: 80ms; }
.ck-settle > :nth-child(4) { animation-delay: 120ms; }
.ck-settle > :nth-child(5) { animation-delay: 160ms; }
.ck-settle > :nth-child(n + 6) { animation-delay: 200ms; }

@keyframes ck-settle {
  from { opacity: 0; transform: translateY(8px); }
}

/* ---------------------------------------------------------------------------
 * D. Fox loader (app/views/shared/_fox_loader.html.erb)
 * ------------------------------------------------------------------------ */
.ck-fox-loader {
  display: inline-flex;
  align-items: center;
  gap: 0.75rem;
}

.ck-fox-loader--md {
  display: flex;
  flex-direction: column;
  justify-content: center;
  gap: 0.625rem;
}

.ck-fox-loader__spinner {
  position: relative;
  flex: none;
  width: 3.5rem;
  height: 3.5rem;
  border-radius: 50%;
  box-shadow: inset 0 0 0 3px var(--ck-ring-track);
}

.ck-fox-loader__spinner::before {
  content: "";
  position: absolute;
  inset: 0;
  border-radius: 50%;
  background: conic-gradient(from 0deg, transparent 0 55%, #3b82f6 80%, var(--ck-violet) 100%);
  -webkit-mask: radial-gradient(farthest-side, transparent calc(100% - 3px), #000 calc(100% - 3px));
  mask: radial-gradient(farthest-side, transparent calc(100% - 3px), #000 calc(100% - 3px));
  animation: ck-spin 1.1s linear infinite;
}

.ck-fox-loader__spinner::after {
  content: "";
  position: absolute;
  inset: 22%;
  background: var(--ck-fox) center / contain no-repeat;
  animation: ck-breathe 2.2s ease-in-out infinite;
}

.ck-fox-loader--sm { gap: 0.5rem; }

.ck-fox-loader--sm .ck-fox-loader__spinner {
  width: 1.5rem;
  height: 1.5rem;
  box-shadow: inset 0 0 0 2px var(--ck-ring-track);
}

.ck-fox-loader--sm .ck-fox-loader__spinner::before {
  -webkit-mask: radial-gradient(farthest-side, transparent calc(100% - 2px), #000 calc(100% - 2px));
  mask: radial-gradient(farthest-side, transparent calc(100% - 2px), #000 calc(100% - 2px));
}

.ck-fox-loader--sm .ck-fox-loader__spinner::after { inset: 18%; }

@keyframes ck-spin {
  to { transform: rotate(360deg); }
}

@keyframes ck-breathe {
  50% { transform: scale(0.92); }
}

/* ---------------------------------------------------------------------------
 * E. Lazy frame skeletons: swap Tailwind's opacity pulse for a blue shimmer.
 * Scoped to frames that haven't finished loading, so animate-pulse used in
 * loaded content (live dots etc.) is untouched.
 * ------------------------------------------------------------------------ */
turbo-frame:not([complete]) .animate-pulse {
  animation: none;
}

turbo-frame:not([complete]) .animate-pulse[class^="bg-dark-"],
turbo-frame:not([complete]) .animate-pulse[class*=" bg-dark-"],
turbo-frame:not([complete]) .animate-pulse [class^="bg-dark-"],
turbo-frame:not([complete]) .animate-pulse [class*=" bg-dark-"] {
  background-image: linear-gradient(100deg, transparent 20%, var(--ck-shimmer) 50%, transparent 80%);
  background-size: 200% 100%;
  background-repeat: no-repeat;
  animation: ck-shimmer 1.6s ease-in-out infinite;
}

@keyframes ck-shimmer {
  from { background-position: 130% 0; }
  to { background-position: -30% 0; }
}

/* ---------------------------------------------------------------------------
 * F. Logo nod: the fox tilts its head on hover (navbar and login).
 * ------------------------------------------------------------------------ */
.ck-logo-mark {
  transform-origin: 50% 88%;
}

.ck-logo:hover .ck-logo-mark {
  animation: ck-nod 0.75s cubic-bezier(0.3, 0.7, 0.3, 1);
}

@keyframes ck-nod {
  25% { transform: rotate(-11deg) translateY(-3px); }
  55% { transform: rotate(6deg); }
  78% { transform: rotate(-2deg); }
}

/* ---------------------------------------------------------------------------
 * G. Napping fox empty state (app/views/shared/_napping_fox.html.erb)
 * ------------------------------------------------------------------------ */
.ck-nap {
  position: relative;
  width: 4rem;
  height: 4.25rem;
  margin: 0 auto 1rem;
}

.ck-nap__fox {
  display: block;
  width: 100%;
  height: 100%;
  background: var(--ck-fox) center / contain no-repeat;
  transform-origin: 50% 100%;
  filter: saturate(0.8);
  animation: ck-snore 3.6s ease-in-out infinite;
}

.ck-nap__z {
  position: absolute;
  right: -0.5rem;
  top: 0;
  font-weight: 800;
  font-size: 0.85rem;
  line-height: 1;
  color: #3b82f6;
  opacity: 0;
  animation: ck-zz 3.6s ease-out infinite;
}

.ck-nap__z:nth-of-type(2) { animation-delay: 1.2s; font-size: 0.7rem; }
.ck-nap__z:nth-of-type(3) { animation-delay: 2.4s; font-size: 0.6rem; }

@keyframes ck-snore {
  50% { transform: scaleY(1.035) scaleX(0.99); }
}

@keyframes ck-zz {
  0% { opacity: 0; transform: translate(0, 6px); }
  20% { opacity: 0.9; }
  100% { opacity: 0; transform: translate(14px, -22px); }
}

/* ---------------------------------------------------------------------------
 * H. Sidebar icons react on hover. Classes are added per icon in
 * _sidebar.html.erb (ck-icon-<name>); unlisted icons get a gentle lift.
 * ------------------------------------------------------------------------ */
.sidebar-link .sidebar-link-icon {
  transform-origin: 50% 60%;
}

.sidebar-link:hover .sidebar-link-icon { animation: ck-lift 0.45s cubic-bezier(0.3, 0.7, 0.3, 1); }

.sidebar-link:hover .ck-icon-chat-bubble-left-right,
.sidebar-link:hover .ck-icon-megaphone,
.sidebar-link:hover .ck-icon-bolt { animation: ck-wiggle 0.5s ease-in-out; }

.sidebar-link:hover .ck-icon-users,
.sidebar-link:hover .ck-icon-user-group,
.sidebar-link:hover .ck-icon-rectangle-group { animation: ck-hop 0.5s ease-out; }

.sidebar-link:hover .ck-icon-link,
.sidebar-link:hover .ck-icon-key { animation: ck-snap 0.5s cubic-bezier(0.3, 0.7, 0.3, 1.4); }

/* The cog's teeth repeat every 45deg, so a 90deg turn ends where it began. */
.sidebar-link:hover .ck-icon-cog { animation: ck-turn 0.6s cubic-bezier(0.3, 0.7, 0.3, 1); }

.sidebar-link:hover .ck-icon-document-arrow-down { animation: ck-drop 0.5s ease-out; }

.sidebar-link:hover .ck-icon-exclamation-triangle,
.sidebar-link:hover .ck-icon-shield-exclamation { animation: ck-shake 0.45s ease-in-out; }

/* Bar-chart icons: the heroicon is one <path> of three bars, so scale the
   whole glyph up from the baseline instead. */
.sidebar-link:hover .ck-icon-chart-bar,
.sidebar-link:hover .ck-icon-chart-bar-square,
.sidebar-link:hover .ck-icon-table-cells { transform-origin: 50% 100%; animation: ck-grow 0.42s cubic-bezier(0.2, 0.8, 0.3, 1.2); }

@keyframes ck-lift { 40% { transform: translateY(-3px) scale(1.06); } }
@keyframes ck-wiggle { 20% { transform: rotate(-11deg); } 45% { transform: rotate(8deg); } 70% { transform: rotate(-4deg); } }
@keyframes ck-hop { 30% { transform: translateY(-3px); } 55% { transform: translateY(0); } 75% { transform: translateY(-1.5px); } }
@keyframes ck-snap { 40% { transform: rotate(-30deg) scale(0.92); } }
@keyframes ck-turn { to { transform: rotate(90deg); } }
@keyframes ck-drop { 35% { transform: translateY(3px); } 65% { transform: translateY(-1px); } }
@keyframes ck-shake { 25% { transform: translateX(-2px); } 50% { transform: translateX(2px); } 75% { transform: translateX(-1px); } }
@keyframes ck-grow { from { transform: scaleY(0.2); } }

/* ---------------------------------------------------------------------------
 * K. Live Report: a new feed row briefly glows blue, then fades to its own
 * background (keyframe has no `to`, so it ends on the element's real color).
 * ------------------------------------------------------------------------ */
.ck-fresh {
  animation: ck-fresh 2.2s ease-out;
}

@keyframes ck-fresh {
  0%, 25% { background-color: var(--ck-fresh); }
}

/* ---------------------------------------------------------------------------
 * L. Launch: Activate button (launch_controller). On submit the paper plane
 * flies off and the button fills while the request is in flight.
 * ------------------------------------------------------------------------ */
.ck-launch {
  position: relative;
  overflow: hidden;
  isolation: isolate;
}

.ck-launch::before {
  content: "";
  position: absolute;
  inset: 0;
  z-index: -1;
  background: #047857;          /* green-700 */
  transform: scaleX(0);
  transform-origin: left;
  transition: transform 0.6s cubic-bezier(0.6, 0, 0.3, 1);
}

.ck-launch.ck-launching::before { transform: scaleX(1); }

.ck-launch.ck-launching .ck-launch-plane {
  animation: ck-fly 0.5s cubic-bezier(0.5, 0, 0.8, 0.4) forwards;
}

@keyframes ck-fly {
  to { transform: translate(70px, -26px) rotate(-18deg); opacity: 0; }
}

/* ---------------------------------------------------------------------------
 * M. Flash toasts: slide in from the right, countdown bar drains, hover pauses.
 * ------------------------------------------------------------------------ */
.ck-toast {
  position: relative;
  overflow: hidden;
  animation: ck-toast-in 0.45s cubic-bezier(0.2, 0.9, 0.3, 1.15);
}

.ck-toast.ck-toast-out {
  animation: ck-toast-out 0.25s ease-in forwards;
}

.ck-toast__drain {
  position: absolute;
  left: 0;
  bottom: 0;
  height: 2px;
  width: 100%;
  background: currentColor;
  opacity: 0.45;
  transform-origin: left;
  animation: ck-drain var(--ck-toast-duration, 8s) linear forwards;
}

.ck-toast:hover .ck-toast__drain {
  animation-play-state: paused;
}

@keyframes ck-toast-in {
  from { transform: translateX(115%); }
}

@keyframes ck-toast-out {
  to { transform: translateX(115%); opacity: 0; }
}

@keyframes ck-drain {
  from { transform: scaleX(1); }
  to { transform: scaleX(0); }
}

/* ---------------------------------------------------------------------------
 * Fox splash (app/views/shared/_fox_splash.html.erb + company_selector).
 *   --switching: shown on click while the company switch request runs
 *   --arrive:    the reloaded page picks the fox up where it left off, then fades
 *   --intro:     first dashboard visit per sign-in; pops in with the wordmark
 * Intro/arrive never block clicks; only the in-flight switch does.
 * ------------------------------------------------------------------------ */
.ck-fox-splash {
  position: fixed;
  inset: 0;
  z-index: 70;
  display: grid;
  place-items: center;
  background: rgba(249, 250, 251, 0.88);   /* dark-50 */
  -webkit-backdrop-filter: blur(6px);
  backdrop-filter: blur(6px);
  pointer-events: none;
}

.dark .ck-fox-splash { background: rgba(17, 24, 39, 0.88); }  /* dark-900 */

/* During the page crossfade (B) the navbar is its own layer above the root
 * snapshot, so a splash inside the root only darkened the content and then
 * jumped over the nav once the transition ended. Its own layer keeps it on
 * top (paint order, z-index 70) the whole time, with no crossfade of its own. */
.ck-fox-splash { view-transition-name: ck-fox-splash; }

::view-transition-old(ck-fox-splash) { display: none; }
::view-transition-group(ck-fox-splash),
::view-transition-new(ck-fox-splash) { animation: none; }

.ck-fox-splash__inner {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 0.75rem;
}

.ck-fox-splash__spinner {
  width: 6rem;
  height: 6rem;
}

.ck-fox-splash__wordmark { height: 5rem; width: auto; margin-top: -1.25rem; }  /* image has built-in top padding */

.ck-fox-splash__label {
  font-size: 0.95rem;
  font-weight: 600;
  color: #374151;   /* dark-700 */
}

.dark .ck-fox-splash__label { color: #d1d5db; }  /* dark-300 */

.ck-fox-splash--switching {
  pointer-events: auto;
  animation: ck-splash-in 0.15s ease-out both;
}

.ck-fox-splash--arrive {
  animation: ck-splash-out 0.35s ease-in 0.35s forwards;
}

.ck-fox-splash--intro {
  animation: ck-splash-out 0.35s ease-in 0.8s forwards;
}

.ck-fox-splash--intro .ck-fox-splash__inner {
  animation: ck-splash-pop 0.45s cubic-bezier(0.2, 0.9, 0.3, 1.2) both;
}

@keyframes ck-splash-in {
  from { opacity: 0; }
}

@keyframes ck-splash-out {
  to { opacity: 0; visibility: hidden; }
}

@keyframes ck-splash-pop {
  from { opacity: 0; transform: scale(0.85); }
}

/* ---------------------------------------------------------------------------
 * Reduced motion: switch everything above off. Loaders keep a static ring and
 * the progress bar still shows, just without movement.
 * ------------------------------------------------------------------------ */
@media (prefers-reduced-motion: reduce) {
  html .turbo-progress-bar::after,
  .ck-settle > *,
  .ck-fox-loader__spinner::before,
  .ck-fox-loader__spinner::after,
  .ck-nap__fox,
  .ck-nap__z,
  .ck-logo:hover .ck-logo-mark,
  .sidebar-link:hover .sidebar-link-icon,
  .ck-fresh,
  .ck-launch.ck-launching .ck-launch-plane,
  .ck-toast,
  .ck-toast.ck-toast-out,
  .ck-toast__drain,
  turbo-frame:not([complete]) .animate-pulse,
  turbo-frame:not([complete]) .animate-pulse * {
    animation: none !important;
  }

  .ck-launch::before { transition: none; }

  /* Decorative splashes skip entirely; the switching one stays, just static. */
  .ck-fox-splash--intro,
  .ck-fox-splash--arrive { display: none; }
  .ck-fox-splash--switching { animation: none; }

  ::view-transition-group(*),
  ::view-transition-old(*),
  ::view-transition-new(*) {
    animation: none !important;
  }
}
