/* ============================================================================
   HTMLOL Motion Kit — htmlol-motion.css   v1.0
   Drop-in, framework-agnostic. Pairs with htmlol-motion.js.
   Principles: fun · quick · impressive. Animate transform/opacity only.
   Override the tokens below in your own :root to retheme.
   ========================================================================== */

:root {
  --mo-yellow: #FEE715;   /* Blazing Yellow */
  --mo-ink:    #2D2C2A;   /* Deep Caverns  */
  --mo-paper:  #F0EFEE;   /* Wispy Clouds  */

  /* durations */
  --mo-snap:   120ms;     /* hovers, toggles, taps */
  --mo-base:   180ms;     /* most UI transitions   */
  --mo-settle: 220ms;     /* panels, drawers       */
  --mo-boing-dur: 460ms;  /* winks, pops, bursts   */

  /* easings */
  --mo-ease:  cubic-bezier(.22,1,.36,1);     /* confident ease-out */
  --mo-boing: cubic-bezier(.34,1.56,.64,1);  /* springy overshoot  */
}

/* ---- 1. The wink (signature 180° flip — rewards only) ------------------ */
.mo-wink { transition: transform var(--mo-boing-dur) var(--mo-boing); }
.mo-wink.is-winking { transform: rotate(180deg); }
.mo-wink--hover:hover, .mo-wink--hover:focus-visible { transform: rotate(180deg); }

/* nav micro-wink — a tease, not the full flip */
.mo-navwink { transition: transform var(--mo-snap) var(--mo-ease); transform-origin: 50% 60%; }
.mo-navwink:hover, .mo-navwink:focus-visible { transform: rotate(-18deg); }

/* ---- 2. Hover lift / tilt --------------------------------------------- */
.mo-lift { transition: transform var(--mo-base) var(--mo-ease), box-shadow var(--mo-base) var(--mo-ease); }
.mo-lift:hover { transform: translateY(-7px) rotate(-1.6deg); box-shadow: 0 18px 32px -16px rgba(0,0,0,.45); }

/* ---- 3. Highlighter sweep --------------------------------------------- */
.mo-hl {
  background-image: linear-gradient(var(--mo-yellow), var(--mo-yellow));
  background-repeat: no-repeat; background-position: 0 88%; background-size: 0% 64%;
  padding: 0 .15em;
  transition: background-size var(--mo-boing-dur) var(--mo-ease), color calc(var(--mo-base)) ease 120ms;
}
.mo-hl:hover, .mo-hl.is-marked { background-size: 100% 64%; color: var(--mo-ink); }

/* ---- 4. "Ship it" punch + sparks (JS adds .spark) --------------------- */
.mo-punch { animation: mo-punch var(--mo-boing-dur) var(--mo-boing); }
@keyframes mo-punch { 0%{transform:scale(1)} 42%{transform:scale(1.16)} 100%{transform:scale(1)} }
.mo-spark { position: absolute; width: 9px; height: 9px; background: var(--mo-yellow);
            border-radius: 2px; pointer-events: none; z-index: 9999; }

/* ---- 5. Live loading line + shimmer bar ------------------------------- */
.mo-load-line { transition: opacity var(--mo-base) ease; }
.mo-bar { height: 6px; border-radius: 3px; background: rgba(45,44,42,.16); overflow: hidden; }
.mo-bar > i { display: block; height: 100%; width: 38%; border-radius: 3px; background: var(--mo-yellow);
              animation: mo-slide 1.15s ease-in-out infinite; }
@keyframes mo-slide { 0%{transform:translateX(-110%)} 100%{transform:translateX(360%)} }

/* ---- 6. Success pop (chips, checks) ----------------------------------- */
.mo-pop { animation: mo-pop var(--mo-boing-dur) var(--mo-boing) forwards; }
@keyframes mo-pop { 0%{transform:scale(0)} 62%{transform:scale(1.16)} 100%{transform:scale(1)} }

/* ---- 7. Save dot (hollow → fill → check via .is-saving/.is-saved) ----- */
.mo-savedot { width: 14px; height: 14px; border-radius: 50%; border: 2px solid currentColor;
              display: inline-block; position: relative; transition: background var(--mo-base) var(--mo-ease); }
.mo-savedot.is-saving { background: var(--mo-yellow); animation: mo-pulse 1s ease-in-out infinite; }
.mo-savedot.is-saved  { background: var(--mo-yellow); border-color: var(--mo-yellow); animation: mo-pop var(--mo-boing-dur) var(--mo-boing); }
.mo-savedot.is-saved::after { content: ""; position: absolute; left: 3px; top: 1px; width: 4px; height: 7px;
   border: solid var(--mo-ink); border-width: 0 2px 2px 0; transform: rotate(45deg); }
@keyframes mo-pulse { 0%,100%{opacity:1} 50%{opacity:.45} }

/* ---- 8. Toast (slide up + auto out) ----------------------------------- */
.mo-toast-wrap { position: fixed; left: 50%; bottom: 24px; transform: translateX(-50%);
                 display: flex; flex-direction: column; gap: 8px; z-index: 99999; pointer-events: none; }
.mo-toast { background: var(--mo-ink); color: var(--mo-paper); border-left: 4px solid var(--mo-yellow);
            font: 500 13px/1.4 system-ui, sans-serif; padding: 11px 16px; border-radius: 8px;
            box-shadow: 0 12px 30px -12px rgba(0,0,0,.5); animation: mo-toast-in var(--mo-settle) var(--mo-boing); }
.mo-toast.is-out { animation: mo-toast-out var(--mo-base) var(--mo-ease) forwards; }
@keyframes mo-toast-in  { from{opacity:0;transform:translateY(14px)} to{opacity:1;transform:translateY(0)} }
@keyframes mo-toast-out { to{opacity:0;transform:translateY(10px)} }

/* ---- 9. Gentle error wiggle (never a red flash) ----------------------- */
.mo-wiggle { animation: mo-wiggle 380ms var(--mo-ease); }
@keyframes mo-wiggle { 0%,100%{transform:translateX(0)} 20%{transform:translateX(-5px)} 40%{transform:translateX(5px)} 60%{transform:translateX(-3px)} 80%{transform:translateX(3px)} }
.mo-errunderline { box-shadow: inset 0 -3px 0 var(--mo-yellow); }

/* ---- 10. Editor magic ------------------------------------------------- */
/* diff flash — pulse a yellow ring on the element that just changed */
.mo-diff { animation: mo-diff var(--mo-settle) var(--mo-ease); }
@keyframes mo-diff { 0%{box-shadow:0 0 0 0 rgba(254,231,21,.9)} 100%{box-shadow:0 0 0 6px rgba(254,231,21,0)} }
/* image drop catch + plop */
.mo-drop.is-dragover { outline: 2px dashed var(--mo-yellow); outline-offset: -6px; background: rgba(254,231,21,.08); }
.mo-plop { animation: mo-plop var(--mo-boing-dur) var(--mo-boing); }
@keyframes mo-plop { 0%{transform:scale(.6);opacity:0} 60%{transform:scale(1.08);opacity:1} 100%{transform:scale(1)} }
/* upload shimmer (toggle .is-uploading) */
.mo-shimmer.is-uploading { background-image: linear-gradient(100deg, transparent 30%, rgba(254,231,21,.55) 50%, transparent 70%);
   background-size: 220% 100%; animation: mo-shimmer 1.1s ease-in-out infinite; }
@keyframes mo-shimmer { 0%{background-position:180% 0} 100%{background-position:-80% 0} }
/* tab open / close */
.mo-tab-in  { animation: mo-tab-in  var(--mo-settle) var(--mo-boing); }
.mo-tab-out { animation: mo-tab-out var(--mo-snap)  var(--mo-ease) forwards; }
@keyframes mo-tab-in  { from{opacity:0;transform:translateY(-8px) scale(.96)} to{opacity:1;transform:none} }
@keyframes mo-tab-out { to{opacity:0;transform:scale(.9)} }

/* ---- 11. Scroll reveal (JS toggles .is-visible) ----------------------- */
[data-mo-reveal] { opacity: 0; transform: translateY(18px); transition: opacity var(--mo-settle) var(--mo-ease), transform var(--mo-settle) var(--mo-ease); }
[data-mo-reveal].is-visible { opacity: 1; transform: none; }

/* ---- 12. Page wipe (signature transition; JS injects the overlay) ----- */
.mo-wipe { position: fixed; inset: 0; background: var(--mo-yellow); z-index: 100000;
           transform: scaleX(0); transform-origin: left; pointer-events: none; }
.mo-wipe.in  { animation: mo-wipe-in  340ms var(--mo-ease) forwards; }
.mo-wipe.out { animation: mo-wipe-out 340ms var(--mo-ease) forwards; transform-origin: right; }
@keyframes mo-wipe-in  { from{transform:scaleX(0)} to{transform:scaleX(1)} }
@keyframes mo-wipe-out { from{transform:scaleX(1)} to{transform:scaleX(0)} }

/* ---- 13. Easter egg: 🙃 rain ----------------------------------------- */
.mo-rain-bit { position: fixed; top: -40px; z-index: 100001; pointer-events: none; user-select: none;
               animation: mo-fall linear forwards; }
@keyframes mo-fall { to { transform: translateY(110vh) rotate(360deg); opacity: .2; } }

/* ---- focus ring (on-brand, accessible) -------------------------------- */
.mo-focus:focus-visible { outline: none; box-shadow: 0 0 0 2px var(--mo-ink), 0 0 0 5px var(--mo-yellow); }

/* ============ Respect reduced motion — keep results, drop the show ===== */
@media (prefers-reduced-motion: reduce) {
  .mo-wink, .mo-navwink, .mo-lift, .mo-hl, .mo-load-line, .mo-savedot { transition: none !important; }
  .mo-punch, .mo-pop, .mo-bar > i, .mo-toast, .mo-wiggle, .mo-diff, .mo-plop,
  .mo-shimmer.is-uploading, .mo-tab-in, .mo-tab-out, .mo-savedot.is-saving,
  .mo-wipe.in, .mo-wipe.out, .mo-rain-bit { animation: none !important; }
  .mo-hl:hover, .mo-hl.is-marked { background-size: 100% 64%; color: var(--mo-ink); }
  [data-mo-reveal] { opacity: 1; transform: none; transition: none; }
  .mo-lift:hover { transform: none; }
}
