/* Motion: gentle kUInetic entrances (scripts/motion.js) and the floating on/off button.
   kUInetic itself is MIT, vendored at scripts/vendor/kuinetic.all.js (see kuinetic-LICENSE.md). */

/* Pre-paint cloak. scripts/motion-boot.js sets <html data-oh-cloak> from <head>; these blocks stay
   hidden until kUInetic stamps data-kui-state on them, so they never flash visible first.
   Fail-open: each block also un-hides itself after 2s with no JS, and motion-boot.js removes the
   attribute after 3s. Keep this list in step with the selectors in scripts/motion.js. */
html[data-oh-cloak] .oh-main :is(
  .oh-hero > div > *,
  .oh-intro > *,
  .oh-hero-art,
  .oh-section > .oh-head,
  .oh-section > .oh-split > *,
  .oh-section > .oh-panel,
  .oh-section > .oh-chapter,
  .oh-section > .oh-notice,
  .oh-section > .oh-measure,
  .oh-section > .oh-faq,
  .oh-section > .oh-actions,
  .oh-steps > *,
  .oh-grid-2 > *,
  .oh-timeline > *
):not([data-kui-state]) {
  opacity: 0;
  animation: oh-cloak-release 1ms linear 2s forwards;
}
@keyframes oh-cloak-release { to { opacity: 1; } }

/* Motion off: hold every effect at its finished state. !important beats the inline animation
   styles kUInetic writes and its layered rules. */
html[data-oh-motion="off"] [data-kui],
html[data-oh-motion="off"] [data-kui] .kui-split-item {
  animation: none !important; opacity: 1 !important; translate: none !important;
  scale: none !important; filter: none !important; clip-path: none !important; transform: none !important;
}
html[data-oh-motion="off"] path[data-kui] { stroke-dasharray: none !important; stroke-dashoffset: 0 !important; }

/* Replay when motion is switched back on: one gentle fade-up, staggered by --oh-i. */
.oh-replay { animation: oh-replay 650ms cubic-bezier(0.16, 1, 0.3, 1) both !important; animation-delay: calc(var(--oh-i, 0) * 70ms) !important; }
@keyframes oh-replay { from { opacity: 0; translate: 0 14px; } to { opacity: 1; translate: 0 0; } }

/* ---------- floating on/off button ---------- */
.oh-motion-fab {
  position: fixed; right: max(16px, env(safe-area-inset-right)); bottom: max(16px, env(safe-area-inset-bottom)); z-index: 40;
  width: 44px; height: 44px; padding: 0; border-radius: 50%; display: grid; place-items: center; cursor: pointer;
  border: 1px solid var(--oh-rule); background: var(--oh-white); color: var(--oh-midnight);
  box-shadow: 0 10px 24px -12px rgba(16, 46, 66, 0.45);
  transition: transform 0.2s ease, background-color 0.2s ease, color 0.2s ease, border-color 0.2s ease;
}
.oh-motion-fab:hover { transform: translateY(-2px); }
.oh-motion-fab:focus-visible { outline: 2px solid var(--oh-turquoise); outline-offset: 3px; }
.oh-motion-fab svg { width: 20px; height: 20px; }
.oh-motion-fab[aria-pressed="true"] { background: var(--oh-turquoise); color: var(--oh-white); border-color: transparent; }
.oh-motion-fab .oh-fab-off { display: none; }
.oh-motion-fab[aria-pressed="false"] .oh-fab-on { display: none; }
.oh-motion-fab[aria-pressed="false"] .oh-fab-off { display: block; }
.oh-motion-fab .oh-fab-lines { transition: translate 0.3s cubic-bezier(0.16, 1, 0.3, 1), opacity 0.3s ease; }
.oh-motion-fab:hover .oh-fab-lines { translate: -2px 0; opacity: 0.75; }
/* Tooltip to the left of the button, text from data-tip (set by scripts/motion.js). */
.oh-motion-fab::after {
  content: attr(data-tip); position: absolute; right: calc(100% + 10px); top: 50%; translate: 4px -50%;
  padding: 6px 10px; border-radius: 6px; white-space: nowrap; pointer-events: none;
  font: 600 12px/1 var(--oh-sans); letter-spacing: 0.02em;
  background: var(--oh-midnight); color: var(--oh-white);
  opacity: 0; transition: opacity 0.15s ease, translate 0.15s ease;
}
.oh-motion-fab:hover::after, .oh-motion-fab:focus-visible::after { opacity: 1; translate: 0 -50%; }
@media (hover: none) { .oh-motion-fab::after { display: none; } }
/* Toggle feedback: the icon slides in from the left, like the ball it draws. */
.oh-motion-fab.is-toggled svg { animation: oh-fab-whoosh 0.55s cubic-bezier(0.16, 1, 0.3, 1); }
@keyframes oh-fab-whoosh { from { translate: -8px 0; opacity: 0; } }

@media (prefers-reduced-motion: reduce) {
  .oh-replay, .oh-motion-fab.is-toggled svg { animation: none !important; }
  .oh-motion-fab, .oh-motion-fab .oh-fab-lines, .oh-motion-fab::after { transition: none; }
}
