/* OddHobb moments — signature motion, zero dependencies.
   Every moment is class-triggered: add the class, the moment plays, remove to
   reset. One moment per screen. Loaders always bind real progress. */

@keyframes oh-draw { to { stroke-dashoffset: 0; } }
@keyframes oh-flood { to { fill-opacity: 1; } }
@keyframes oh-drop {
  0% { transform: translateY(-46px) scale(1.04); opacity: 0; }
  55% { transform: translateY(0) scale(1); opacity: 1; }
  70% { transform: translateY(2px) scale(1, .92); }
  100% { transform: translateY(0) scale(1); opacity: 1; }
}
@keyframes oh-wax {
  0% { transform: scale(.4); opacity: 0; }
  60% { transform: scale(1.12); opacity: .8; }
  100% { transform: scale(1); opacity: .55; }
}
@keyframes oh-ribbon-pull {
  0% { stroke-dashoffset: var(--len, 1000); }
  70% { stroke-dashoffset: calc(var(--len, 1000) * -0.04); }
  100% { stroke-dashoffset: 0; }
}
@keyframes oh-cinch {
  0%, 100% { transform: scale(1); }
  40% { transform: scale(.9); }
}
@keyframes oh-coin {
  0% { transform: rotateY(0deg); }
  100% { transform: rotateY(360deg); }
}
@keyframes oh-edge {
  0%, 100% { filter: brightness(1); }
  25%, 75% { filter: brightness(.82); }
}
@keyframes oh-swing {
  0% { transform: rotate(14deg); }
  100% { transform: rotate(-14deg); }
}
@keyframes oh-snow {
  0% { transform: translateY(-10px); opacity: 0; }
  15% { opacity: .9; }
  100% { transform: translateY(120px); opacity: 0; }
}
@keyframes oh-haptic-pop {
  0% { transform: scale(1); }
  40% { transform: scale(1.12); }
  100% { transform: scale(1); }
}

/* boot: etch then flood */
.moment-flood path, .moment-flood circle {
  fill-opacity: 0;
  animation: oh-draw 1.1s ease forwards, oh-flood .5s ease 1.0s forwards;
}
.moment-flood path:nth-of-type(2) { animation-delay: .35s, 1.35s; }
.moment-flood circle { animation-delay: .8s, 1.8s; }

/* wax press: glyph drops, wax blooms */
.moment-press .press-glyph { animation: oh-drop .55s cubic-bezier(.2, 1.4, .4, 1) both; }
.moment-press .press-wax { animation: oh-wax .8s ease-out both; transform-origin: center; }

/* ribbon mode: pulled strokes, cinching knot, falling snow */
.moment-ribbon path {
  stroke-dasharray: var(--len, 1000);
  animation: oh-ribbon-pull 1.4s cubic-bezier(.3, .7, .3, 1) both;
}
.moment-ribbon path:nth-of-type(2) { animation-delay: .45s; }
.moment-ribbon .knot { animation: oh-cinch .5s ease 1.5s both; transform-origin: center; }
.moment-ribbon .flake { animation: oh-snow 3s linear infinite; }

/* coin spin: waiting with honesty (bind a real job beneath) */
.moment-coin .coin { animation: oh-coin 2.4s linear infinite; transform-origin: center; }
.moment-coin .coin path, .moment-coin .coin circle {
  animation: oh-edge 2.4s linear infinite;
}

/* bauble swing: damped pendulum after a tap */
.moment-swing .swing { animation: oh-swing 1.6s ease-in-out infinite alternate; transform-origin: 50% 0; }

/* keep-selected pop (pairs with navigator.vibrate on snap) */
.moment-pop { animation: oh-haptic-pop .25s ease; }

/* orbit waiter: job waits (sculpt, render top-up). Pure CSS, no asset. */
@keyframes oh-orbit { to { transform: rotate(360deg); } }
.moment-orbit{width:44px;height:44px;position:relative}
.moment-orbit i{position:absolute;left:50%;top:50%;width:8px;height:8px;margin:-4px;
  border-radius:50%;background:#c4891a}
.moment-orbit i:nth-child(1){transform:rotate(0deg) translateX(18px)}
.moment-orbit i:nth-child(2){transform:rotate(120deg) translateX(18px);opacity:.55}
.moment-orbit i:nth-child(3){transform:rotate(240deg) translateX(18px);opacity:.3}
.moment-orbit{animation:oh-orbit 1.2s linear infinite}

@media (prefers-reduced-motion: reduce) {
  .moment-flood path, .moment-flood circle, .moment-press .press-glyph,
  .moment-press .press-wax, .moment-ribbon path, .moment-coin .coin,
  .moment-swing .swing { animation: none; }
}
