/* How the app answers a pointer — hover, press, focus, refusal.
 *
 * This file is loaded LAST on purpose: it is the authority on interaction,
 * so it wins over anything in style.css by source order alone and never has
 * to escalate specificity or reach for !important. Panels must not write
 * :hover/:active rules of their own — they pick one of the shared classes
 * below and get the feel for free.
 *
 * Everything moves with transform/filter/box-shadow only. None of those
 * affect layout, so no amount of feel can shift the grid under the cursor.
 * Timings and distances come from css/theme.css; see the reduced-motion
 * block at the bottom for the opt-out.
 *
 * The vocabulary:
 *   .btn / .ptab      buttons and tabs           (raised — they depress)
 *   .slot / .eq-slot  inventory + paperdoll      (inset wells — they light up)
 *   .craft-slot       the craft bench's squares
 *   .mp-row           material picker rows
 *   .tile             the world map
 *   .act-card         activity cards             (hover lift only)
 *   .node-row.clickable, .quest-strip, a
 */

/* ---- the shared transition ---- */
.btn,
.slot,
.eq-slot,
.craft-slot,
.mp-row,
.tile,
.act-card,
.node-row.clickable,
.quest-strip,
.eq-doll .slot,
.stock-grid .slot {
  transition:
    transform var(--t-lift) var(--ease-snap),
    box-shadow var(--t-lift) var(--ease-out),
    filter var(--t-lift) var(--ease-out),
    background var(--t-lift) var(--ease-out),
    border-color var(--t-lift) var(--ease-out),
    color var(--t-lift) var(--ease-out);
}

/* ---- raised things: they rise to meet you, then depress ---- */
.btn:not(:disabled):hover,
.mp-row:not(:disabled):hover,
.craft-slot:not(.disabled):hover {
  transform: translateY(var(--lift));
  box-shadow: 0 3px 8px rgba(0, 0, 0, .45);
}
.btn:not(:disabled):active,
.mp-row:not(:disabled):active,
.craft-slot:not(.disabled):active {
  transform: translateY(var(--press)) scale(.975);
  box-shadow: none;
  filter: brightness(1.12);
  transition-duration: var(--t-press);
}

/* ---- inset wells: nothing to lift, so they light up and dip ---- */
.slot:not(.empty):hover,
.eq-slot:hover {
  box-shadow: inset 0 0 0 1px var(--accent-dim), 0 2px 7px rgba(0, 0, 0, .4);
  transform: translateY(-1px);
}
.slot:not(.empty):active,
.eq-slot:active {
  transform: translateY(1px) scale(.96);
  filter: brightness(1.15);
  transition-duration: var(--t-press);
}
/* the icon inside leads the motion — the well is the frame, not the thing */
.slot .slot-icon,
.eq-slot .slot-icon {
  transition: transform var(--t-lift) var(--ease-snap);
}
.slot:not(.empty):hover .slot-icon,
.eq-slot:hover .slot-icon { transform: scale(1.12); }

/* ---- rows: they slide toward the thing they'd take you to ---- */
.node-row.clickable:hover,
.quest-strip:hover { transform: translateX(2px); }
.node-row.clickable:active,
.quest-strip:active {
  transform: translateX(2px) scale(.99);
  filter: brightness(1.1);
  transition-duration: var(--t-press);
}
.node-row .n-go { transition: transform var(--t-lift) var(--ease-snap); }
.node-row.clickable:hover .n-go {
  transform: translateX(3px);
  color: var(--accent);
}

/* ---- map tiles: the lift is in style.css; here is only the press ---- */
.tile:active {
  transform: translateY(0) scale(.94);
  transition-duration: var(--t-press);
}

/* ---- cards lift, but only the ones you can act on ---- */
.act-card:not(.locked):hover {
  transform: translateY(var(--lift));
  box-shadow: 0 5px 14px rgba(0, 0, 0, .4);
}
/* the running one is already the focus — it shouldn't also bob */
.act-card.active:hover { transform: none; }

/* ---- text links ---- */
#session-controls a {
  transition: filter var(--t-lift) var(--ease-out),
    transform var(--t-lift) var(--ease-snap);
}
#session-controls a:hover { filter: brightness(1.3); }
#session-controls a:active { transform: scale(.94); }

/* ---- keyboard users get the same affordances ---- */
:focus-visible {
  outline: 2px solid var(--accent);
  outline-offset: 2px;
  border-radius: 4px;
}
:focus:not(:focus-visible) { outline: none; }

/* ---- refusal: a disabled control still answers, it just says no ---- */
.btn:disabled,
.mp-row:disabled,
.craft-slot.disabled { transform: none; box-shadow: none; }
.fx-deny {
  animation: fxDeny .3s var(--ease-out);
}
@keyframes fxDeny {
  0%, 100% { transform: translateX(0); }
  22% { transform: translateX(-4px); }
  55% { transform: translateX(4px); }
  80% { transform: translateX(-2px); }
}

/* ---- the press mark: a ring off the pointer itself (ui/anim.js spark) ---- */
.fx-spark {
  position: fixed;
  z-index: 90;
  width: 12px;
  height: 12px;
  margin: -6px 0 0 -6px;
  border-radius: 50%;
  border: 2px solid var(--accent);
  pointer-events: none;
  animation: fxSpark .46s var(--ease-out) forwards;
}
.fx-spark.danger { border-color: var(--danger-light); }
.fx-spark.deny { border-color: var(--danger); }
@keyframes fxSpark {
  0% { transform: scale(.2); opacity: .9; border-width: 3px; }
  100% { transform: scale(3.4); opacity: 0; border-width: 1px; }
}

/* ---- opt-out: keep every state change, drop the movement ---- */
@media (prefers-reduced-motion: reduce) {
  .btn, .slot, .eq-slot, .craft-slot, .mp-row, .tile, .act-card,
  .node-row.clickable, .quest-strip, .slot-icon, .node-row .n-go,
  #session-controls a {
    transition-duration: 1ms !important;
    transform: none !important;
  }
  .fx-spark, .fx-deny { animation: none; }
}
