/* ============================================================
   Hueflow — motion
   Every interactive element gets a little personality here.
   ============================================================ */

/* ---------- transitions ---------- */

.btn,
.mode-btn,
.nav-link,
.icon-btn,
.swatch-btn,
.chip,
.mood-card,
.export-opt,
.use-case,
.add-swatch,
.dropzone,
.saved-card {
  transition:
    transform var(--fast) var(--spring),
    background-color var(--fast) var(--ease-out),
    border-color var(--fast) var(--ease-out),
    color var(--fast) var(--ease-out),
    box-shadow var(--fast) var(--ease-out);
}

/* One light source from above, so nothing lifts on hover — hover brightens
   the face and a press pushes the object physically down into the surface. */
.btn:active,
.mode-btn:active,
.chip:active,
.mood-card:active,
.icon-btn:active,
.export-opt:active,
.nav-link:active { transform: translateY(1px); }

.btn,
.icon-btn,
.chip,
.mood-card {
  transition:
    filter .15s var(--ease),
    transform .05s var(--ease),
    box-shadow .05s var(--ease),
    color var(--fast) var(--ease-out);
}

/* the mode buttons also ease their face back after the confirm flash */
.mode-btn {
  transition:
    filter .15s var(--ease),
    transform .05s var(--ease),
    background-image var(--med) var(--ease),
    box-shadow var(--med) var(--ease),
    color var(--med) var(--ease);
}
.mode-btn .i { transition: color var(--med) var(--ease); }
.mode-btn.is-confirm::before { animation: mode-confirm 560ms ease-in-out; }
.mode-btn.is-confirm .i { animation: mode-confirm-ink 560ms ease-in-out; }

.swatch-btn {
  transition:
    opacity var(--fast) var(--ease-out),
    transform var(--med) var(--spring),
    background-color var(--fast) var(--ease-out);
}
.swatch-btn:active { transform: scale(0.86); }
.swatch:hover .swatch-btn:nth-child(2) { transition-delay: 40ms; }
.swatch:hover .swatch-btn:nth-child(3) { transition-delay: 80ms; }

.add-swatch:hover { filter: brightness(1.2); }
.add-swatch:hover .plus { transform: rotate(90deg) scale(1.08); }
.add-swatch .plus { transition: transform var(--med) var(--spring); }

.use-case:hover { filter: brightness(1.15); }

.saved-card:hover { transform: translateY(-3px); box-shadow: var(--shadow-2); }
.saved-strip span { transition: flex-grow var(--med) var(--ease-out); }
.saved-card:hover .saved-strip span:hover { flex-grow: 1.9; }

.brand-mark span { transition: transform var(--med) var(--spring); }
.brand:hover .brand-mark span:nth-child(1) { transform: translate(-2px, -2px); }
.brand:hover .brand-mark span:nth-child(2) { transform: translate(2px, -2px); }
.brand:hover .brand-mark span:nth-child(3) { transform: translate(-2px, 2px); }
.brand:hover .brand-mark span:nth-child(4) { transform: translate(2px, 2px); }

.swatch {
  transition:
    background-color var(--med) var(--ease-out),
    border-color var(--fast) var(--ease-out),
    box-shadow var(--fast) var(--ease-out),
    flex-grow 420ms var(--ease-out),
    flex-basis 420ms var(--ease-out),
    padding 420ms var(--ease-out),
    border-width 420ms var(--ease-out),
    opacity 300ms var(--ease-out);
}
.swatch:hover .swatch-hex { transform: translateY(-2px); }
.swatch:hover .swatch-name { transform: translateY(-1px); }
.swatch-hex,
.swatch-name {
  transition:
    color var(--med) var(--ease-out),
    opacity var(--med) var(--ease-out),
    transform var(--med) var(--spring);
}

.editor-preview { transition: background-color var(--med) var(--ease-out); }
.tab-underline { transition: transform var(--med) var(--spring), width var(--med) var(--spring); }
.ring-fill { transition: stroke-dashoffset var(--slow) var(--ease-out), stroke var(--med) var(--ease-out); }
.pairing span { transition: background-color var(--med) var(--ease-out), transform var(--fast) var(--spring); }
.pairing span:hover { transform: translateY(-4px) scale(1.06); }
.mock { transition: background-color var(--med) var(--ease-out), color var(--med) var(--ease-out), transform var(--fast) var(--spring); }
.mock:hover { transform: scale(1.05); }
.similar-chip { transition: transform var(--fast) var(--spring), filter var(--fast) var(--ease-out); }
/* no white outline — the chip has to show its colour honestly */
.similar-chip:hover { transform: translateY(-3px); filter: brightness(1.12); }

.sidebar-head .chev { transition: transform var(--med) var(--spring); }
.sidebar.is-collapsed .sidebar-head .chev { transform: rotate(180deg); }
.sidebar.is-collapsed .sidebar-body { display: none; }

/* ---------- keyframes ---------- */

@keyframes rise-in {
  from { opacity: 0; transform: translateY(26px) scale(0.94); }
  to   { opacity: 1; transform: none; }
}

@keyframes pop-in {
  0%   { opacity: 0; transform: scale(0.4); }
  70%  { transform: scale(1.14); }
  100% { opacity: 1; transform: scale(1); }
}

@keyframes bounce-lock {
  0%   { transform: scale(1); }
  35%  { transform: scale(0.72) rotate(-12deg); }
  70%  { transform: scale(1.22) rotate(8deg); }
  100% { transform: scale(1); }
}

@keyframes flash-white {
  0%   { box-shadow: 0 0 0 0 rgba(255, 255, 255, 0.55); }
  100% { box-shadow: 0 0 0 22px rgba(255, 255, 255, 0); }
}

@keyframes copied-pulse {
  0%   { transform: scale(1); }
  35%  { transform: scale(1.14); }
  100% { transform: scale(1); }
}

/* the same 560ms beat as a dice roll, eased in and out of the accent */
@keyframes mode-confirm {
  0%, 100% { opacity: 0; }
  45%      { opacity: 1; }
}
@keyframes mode-confirm-ink {
  0%, 100% { color: var(--text-2); }
  45%      { color: #fff; }
}

@keyframes roll-dice {
  0%   { transform: rotate(0) scale(1); }
  30%  { transform: rotate(150deg) scale(0.82); }
  65%  { transform: rotate(300deg) scale(1.18); }
  100% { transform: rotate(360deg) scale(1); }
}

@keyframes wiggle {
  0%, 100% { transform: rotate(0); }
  25%  { transform: rotate(-7deg); }
  50%  { transform: rotate(6deg); }
  75%  { transform: rotate(-4deg); }
}

@keyframes modal-in {
  from { opacity: 0; transform: translateY(22px) scale(0.94); }
  to   { opacity: 1; transform: none; }
}

@keyframes backdrop-in {
  from { opacity: 0; }
  to   { opacity: 1; }
}

@keyframes toast-in {
  from { opacity: 0; transform: translateY(22px) scale(0.9); }
  to   { opacity: 1; transform: none; }
}

@keyframes toast-out {
  to { opacity: 0; transform: translateY(-8px) scale(0.96); }
}

@keyframes confetti-fly {
  from { opacity: 1; transform: translate(0, 0) rotate(0); }
  to   { opacity: 0; transform: translate(var(--dx), var(--dy)) rotate(var(--rot)); }
}

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

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

@keyframes spin-once {
  from { transform: rotate(0); }
  to   { transform: rotate(360deg); }
}

/* ---------- applied animations ---------- */

.swatch.is-entering { animation: rise-in var(--slow) var(--ease-out) backwards; }
.swatch.is-flash::after {
  content: "";
  position: absolute;
  inset: 0;
  border-radius: inherit;
  animation: flash-white 520ms var(--ease-out) forwards;
  pointer-events: none;
}
.swatch-btn.lock.is-toggling { animation: bounce-lock 420ms var(--spring); }
.is-rolling .i { animation: roll-dice 560ms var(--ease-out); }
/* Surprise Me carries both classes at once, and `.mode-btn.is-confirm .i`
   outranks `.is-rolling .i` — without this the confirm ink silently replaced
   the dice tumble. Run the two together. */
.mode-btn.is-confirm.is-rolling .i {
  animation:
    roll-dice 560ms var(--ease-out),
    mode-confirm-ink 560ms ease-in-out;
}
.swatch-hex.is-copied-pulse { animation: copied-pulse 560ms var(--spring); }
.swatch-corner-btn {
  transition:
    opacity var(--fast) var(--ease-out),
    transform var(--med) var(--spring),
    background-color var(--fast) var(--ease-out),
    color var(--fast) var(--ease-out);
}
/* the corner stack unfurls rather than appearing all at once */
.swatch:hover .swatch-corner-btn.duplicate { transition-delay: 45ms; }
.swatch:hover .swatch-corner-btn.edit { transition-delay: 90ms; }
.drag-dots { transition: opacity var(--med) var(--ease-out); }
.drag-dots i { transition: transform var(--med) var(--spring); }
.swatch:hover .drag-dots i:nth-child(1) { transform: translateY(-2px); }
.swatch:hover .drag-dots i:nth-child(2) { transform: translateY(-3px); }
.swatch:hover .drag-dots i:nth-child(3) { transform: translateY(-2px); }
.edge-dot { transition: opacity var(--fast) var(--ease-out), transform var(--med) var(--spring); }

.btn.is-spinning .i { animation: spin-once 520ms var(--ease-out); }
.nav-link.is-wiggling { animation: wiggle 460ms var(--ease-out); }
.field.is-invalid { animation: shake 340ms var(--ease-out); }
/* the confirmation tick keeps the button's own colour — green on these
   dark surfaces was hard to read */
.copy-btn.is-copied { color: var(--text); animation: pop-in 320ms var(--spring); }

.empty-art span { animation: float-y 2.6s var(--ease-out) infinite; }
.empty-art span:nth-child(1) { animation-delay: 0s; background: #3a7fff; }
.empty-art span:nth-child(2) { animation-delay: 0.12s; background: #ff6b6b; }
.empty-art span:nth-child(3) { animation-delay: 0.24s; background: #fff3e0; }
.empty-art span:nth-child(4) { animation-delay: 0.36s; background: #00d4a6; }
.empty-art span:nth-child(5) { animation-delay: 0.48s; background: #ffb648; }

.modal { animation: modal-in 300ms var(--spring); }
.modal-backdrop { animation: backdrop-in 220ms var(--ease-out); }
.toast { animation: toast-in 320ms var(--spring); }
.toast.is-leaving { animation: toast-out 220ms var(--ease-out) forwards; }
.confetti-bit { animation: confetti-fly var(--dur, 900ms) cubic-bezier(0.16, 0.7, 0.35, 1) forwards; }

.extracted span,
.feeling-preview span,
.similar-chip { animation: pop-in 320ms var(--spring) backwards; }
.saved-card { animation: rise-in 380ms var(--ease-out) backwards; }
.mood-card { animation: rise-in 320ms var(--ease-out) backwards; }

/* ---------- reduced motion ---------- */

@media (prefers-reduced-motion: reduce) {
  *,
  *::before,
  *::after {
    animation-duration: 0.001ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: 0.001ms !important;
    scroll-behavior: auto !important;
  }
  .swatch:hover .swatch-hex,
  .swatch:hover .swatch-name,
  .swatch:hover .drag-dots i { transform: none; }
  .swatch:hover .swatch-corner-btn,
  .swatch:hover .swatch-btn { transform: none; opacity: 1; transition-delay: 0s; }
  .swatch:hover,
  .btn:hover,
  .mode-btn:hover,
  .icon-btn:hover,
  .saved-card:hover,
  .similar-chip:hover,
  .pairing span:hover,
  .mock:hover,
  .add-swatch:hover { transform: none; flex-grow: 1; }

  /* the + still needs to appear, it just does so instantly */
  .edge-add:hover .edge-dot { transform: none; opacity: 1; }
}
