/* ============================================================================
   Motion layer
   ----------------------------------------------------------------------------
   Every interactive surface on the site gets: a resting state, a hover state, a
   pressed state, and a transition between them. Nothing changes instantly.

   The rule this follows throughout is that hover should feel like the element is
   lifting toward you and press should feel like it is being pushed in - which is
   how a real button behaves, and it is what makes an interface feel physical
   rather than like a diagram that repaints.

   Three timings, used consistently:
     --t-fast   120ms   press, and anything that must feel instant
     --t-mid    260ms   hover, focus, colour
     --t-slow   620ms   entrances and page transitions

   Loaded last so it wins on specificity ties without needing !important.
   ============================================================================ */

:root {
  --t-fast: 120ms;
  --t-mid: 260ms;
  --t-slow: 620ms;
  --lift: cubic-bezier(0.22, 1, 0.36, 1);
  --spring: cubic-bezier(0.34, 1.56, 0.64, 1);   /* overshoots, for things that pop */
}

/* Anything that can be interacted with animates. Declared broadly on purpose:
   the complaint was that things snap, and the fix is a default, not a list. */
a, button, summary, input, .card, .mc-panel, .mc-slot, .note, .cal li,
.stat, .hotbar__slot, .rank-row, .kit-item, .loot, .crate-row {
  transition:
    transform var(--t-mid) var(--lift),
    box-shadow var(--t-mid) var(--lift),
    border-color var(--t-mid) var(--lift),
    background-color var(--t-mid) var(--lift),
    color var(--t-mid) var(--lift),
    opacity var(--t-mid) var(--lift);
}

/* Press: everything clickable compresses slightly and snaps back fast. */
a:active, button:active, summary:active,
.card:active, .mc-slot:active, .hotbar__slot:active {
  transform: scale(0.972);
  transition-duration: var(--t-fast);
}

/* ------------------------------------------------------------------ buttons */

.mc-btn {
  position: relative;
  overflow: hidden;
  will-change: transform;
}
.mc-btn:hover {
  transform: translateY(-3px);
  box-shadow: 0 10px 26px rgba(0, 0, 0, 0.45), 0 0 0 1px rgba(255, 255, 255, 0.06);
}
.mc-btn:active { transform: translateY(-1px) scale(0.98); }

/* A sheen that sweeps across on hover. Pure CSS, no element needed. */
.mc-btn::after {
  content: '';
  position: absolute; inset: 0;
  background: linear-gradient(105deg, transparent 38%,
              rgba(255, 255, 255, 0.22) 50%, transparent 62%);
  transform: translateX(-120%);
  transition: transform 620ms var(--lift);
  pointer-events: none;
}
.mc-btn:hover::after { transform: translateX(120%); }

/* Ripple, positioned from the pointer by js/motion.js. */
.ripple {
  position: absolute;
  border-radius: 50%;
  transform: translate(-50%, -50%) scale(0);
  background: radial-gradient(circle, rgba(255, 255, 255, 0.42), transparent 68%);
  animation: ripple 560ms var(--lift) forwards;
  pointer-events: none;
}
@keyframes ripple { to { transform: translate(-50%, -50%) scale(1); opacity: 0; } }

/* -------------------------------------------------------------------- cards */

.card, .mc-panel, .note {
  position: relative;
  will-change: transform;
}
.card:hover, .mc-panel:hover {
  transform: translateY(-6px);
  border-color: rgba(108, 194, 74, 0.45);
  box-shadow: 0 18px 40px rgba(0, 0, 0, 0.5);
}

/* A light that follows the pointer. --mx/--my are written by js/motion.js. */
.card::before, .mc-panel::before {
  content: '';
  position: absolute; inset: 0;
  border-radius: inherit;
  background: radial-gradient(320px circle at var(--mx, 50%) var(--my, 50%),
              rgba(108, 194, 74, 0.13), transparent 62%);
  opacity: 0;
  transition: opacity var(--t-mid) var(--lift);
  pointer-events: none;
}
.card:hover::before, .mc-panel:hover::before { opacity: 1; }

.card__icon {
  display: inline-block;
  transition: transform 420ms var(--spring);
}
.card:hover .card__icon { transform: translateY(-4px) scale(1.16) rotate(-6deg); }

/* --------------------------------------------------------------------- nav */

.nav a {
  position: relative;
}
.nav a::after {
  content: '';
  position: absolute; left: 0; right: 0; bottom: -6px;
  height: 2px;
  background: var(--grass);
  transform: scaleX(0);
  transform-origin: right;
  transition: transform 320ms var(--lift);
}
.nav a:hover::after { transform: scaleX(1); transform-origin: left; }
.nav a.is-active::after { transform: scaleX(1); }
.nav a:hover { color: var(--text); transform: translateY(-1px); }

.brand:hover .brand__cube {
  transform: rotate(-14deg) scale(1.12);
  transition: transform 420ms var(--spring);
}
.brand__cube { transition: transform 420ms var(--spring); }

/* ------------------------------------------------------------------- slots */

.mc-slot, .hotbar__slot {
  position: relative;
  overflow: hidden;
}
.mc-slot:hover, .hotbar__slot:hover {
  transform: translateY(-5px) scale(1.04);
  border-color: rgba(108, 194, 74, 0.6);
  box-shadow: 0 12px 22px rgba(0, 0, 0, 0.45);
  z-index: 2;
}
.mc-slot:hover .item-icon, .hotbar__slot:hover span {
  transform: scale(1.14) translateY(-2px);
}
.mc-slot .item-icon, .hotbar__slot span {
  transition: transform 380ms var(--spring);
}

/* ------------------------------------------------------------------- lists */

.note:hover { transform: translateX(6px); }
.cal li:hover {
  transform: translateX(5px);
  border-color: rgba(108, 194, 74, 0.4);
}
.cal li:hover .cal__day { transform: rotate(-8deg) scale(1.1); }
.cal__day { transition: transform 380ms var(--spring); }

.loot:hover, .rank-row:hover, .kit-item:hover {
  background: rgba(255, 255, 255, 0.045);
  transform: translateX(4px);
}

.stat:hover { transform: translateY(-4px) scale(1.03); }
.stat__num { transition: color var(--t-mid) var(--lift); }
.stat:hover .stat__num { color: var(--grass); }

/* ------------------------------------------------------------------- links */

a.u-grass, .footer a {
  position: relative;
  background-image: linear-gradient(var(--grass), var(--grass));
  background-size: 0% 1px;
  background-repeat: no-repeat;
  background-position: left 100%;
  transition: background-size 320ms var(--lift), color var(--t-mid) var(--lift);
}
a.u-grass:hover, .footer a:hover { background-size: 100% 1px; }

/* ----------------------------------------------------------------- details */

details summary { cursor: pointer; list-style: none; }
details summary::-webkit-details-marker { display: none; }
details summary::before {
  content: '▸';
  display: inline-block;
  margin-right: 10px;
  color: var(--grass);
  transition: transform 320ms var(--spring);
}
details[open] summary::before { transform: rotate(90deg); }
details summary:hover { color: var(--grass); }

/* --------------------------------------------------- page + scroll entrances */

/* Route change. The old page is not animated out - waiting for an exit before
   the new page appears makes navigation feel slower than snapping did. The new
   one rises in while the old is already gone. */
#main.is-entering { animation: page-in var(--t-slow) var(--lift) both; }
@keyframes page-in {
  from { opacity: 0; transform: translateY(22px); }
}

/* Scroll reveal.
   The hidden/shown pair lives in core.css and uses .is-visible; this only adds
   the per-item stagger. Declaring the base state again here would mean two
   places can hide an element and only one of them knows how to show it - which
   is exactly how the intro captions ended up permanently invisible. */
[data-reveal] { transition-delay: calc(var(--i, 0) * 55ms); }

/* Section headings sweep their underline in when revealed. */
.section__title { position: relative; }
.section__title::after {
  content: '';
  position: absolute; left: 0; bottom: -10px;
  height: 2px; width: 56px;
  background: var(--grass);
  transform: scaleX(0);
  transform-origin: left;
  transition: transform 620ms var(--lift) 160ms;
}
.section__title.is-visible::after,
[data-reveal].is-visible .section__title::after { transform: scaleX(1); }

/* -------------------------------------------------------------------- misc */

.topbar__search:hover {
  transform: translateY(-2px);
  border-color: rgba(108, 194, 74, 0.45);
}
.topbar__search kbd { transition: transform 320ms var(--spring); }
.topbar__search:hover kbd { transform: scale(1.12); }

/* Focus must be visible and must not be replaced by the hover treatment. */
:focus-visible {
  outline: 2px solid var(--grass);
  outline-offset: 3px;
  border-radius: 3px;
}

/* ------------------------------------------------------------------ reduced */
/* Honour the setting properly: kill movement, keep the state changes. Colour and
   opacity still respond, so the interface stays legible and obviously alive
   without anything travelling across the screen. */
@media (prefers-reduced-motion: reduce) {
  html:not([data-motion="full"]) *,
  html:not([data-motion="full"]) *::before,
  html:not([data-motion="full"]) *::after {
    animation-duration: 0.01ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: 0.01ms !important;
  }
  html:not([data-motion="full"]) .card:hover,
  html:not([data-motion="full"]) .mc-panel:hover,
  html:not([data-motion="full"]) .mc-btn:hover,
  html:not([data-motion="full"]) .mc-slot:hover,
  html:not([data-motion="full"]) .hotbar__slot:hover,
  html:not([data-motion="full"]) .note:hover,
  html:not([data-motion="full"]) .cal li:hover,
  html:not([data-motion="full"]) .stat:hover { transform: none; }
}

/* The toggle itself. */
.motion-toggle {
  display: inline-flex; align-items: center; gap: 8px;
  padding: 7px 12px; cursor: pointer;
  background: var(--panel); border: 1px solid var(--line); border-radius: 5px;
  color: var(--text-soft);
  font-family: var(--font-pixel); font-size: .6rem;
  letter-spacing: .14em; text-transform: uppercase;
}
.motion-toggle:hover { color: var(--grass); border-color: rgba(108,194,74,.45); }
.motion-toggle__dot {
  width: 9px; height: 9px; border-radius: 50%;
  background: var(--text-dim);
  box-shadow: 0 0 0 0 rgba(108,194,74,.5);
}
[data-motion="full"] .motion-toggle__dot,
html:not([data-motion="off"]) .motion-toggle[data-on="1"] .motion-toggle__dot {
  background: var(--grass);
  animation: motion-pulse 2.2s ease-in-out infinite;
}
@keyframes motion-pulse {
  50% { box-shadow: 0 0 0 6px rgba(108,194,74,0); }
}
