{
  "$schema": "https://ui.shadcn.com/schema/registry-item.json",
  "name": "motion",
  "title": "Motion",
  "description": "BoldKit Motion System — framework-agnostic CSS tokens, keyframes, and six signature recipes (press, stamp-in, shake, reveal, slide-hard, pulse-shadow). Mobile-optimized, honors prefers-reduced-motion.",
  "files": [
    {
      "path": "registry/default/styles/motion.css",
      "content": "/*!\n * BoldKit Motion System — L1 tokens + L2 recipes\n * https://boldkit.dev\n *\n * Framework-agnostic. Works with React, Vue, Svelte, Solid,\n * Astro, plain HTML — anywhere CSS works.\n *\n * Honors prefers-reduced-motion automatically.\n *\n * Install via shadcn CLI:\n *   npx shadcn@latest add \"https://boldkit.dev/r/motion.json\"\n *\n * Or import directly:\n *   import \"@boldkit/motion-css\";\n */\n\n/* ──────────────────────────────────────────────────────\n   L1 — Motion Tokens\n   ────────────────────────────────────────────────────── */\n\n:where(:root) {\n  /* Easing — stepped & hard, not smooth. Brutalism's soul. */\n  --bk-ease-step:    steps(4, end);\n  --bk-ease-step-2:  steps(2, end);\n  --bk-ease-snap:    cubic-bezier(0.22, 1, 0.3, 1.12);\n  --bk-ease-stamp:   cubic-bezier(0.7, 0, 0.84, 0);\n  --bk-ease-rubber:  cubic-bezier(0.34, 1.56, 0.64, 1);\n  --bk-ease-linear:  linear;\n\n  /* Durations */\n  --bk-dur-instant: 80ms;\n  --bk-dur-snap:    150ms;\n  --bk-dur-quick:   240ms;\n  --bk-dur-base:    400ms;\n  --bk-dur-slow:    700ms;\n\n  /* Distances */\n  --bk-shadow-offset:       4px;\n  --bk-shadow-offset-press: 0px;\n  --bk-translate-press:     2px;\n  --bk-reveal-offset:       16px;\n\n  /* Fallbacks — if consumer hasn't defined the BoldKit shadow color,\n     fall back to currentColor so the press shadow is still visible. */\n  --shadow-color: var(--shadow-color, 240 10% 10%);\n}\n\n/* ──────────────────────────────────────────────────────\n   L1 — Keyframes (bk-* namespaced)\n   ────────────────────────────────────────────────────── */\n\n@keyframes bk-stamp-in {\n  0%   { opacity: 0; transform: scale(0.6) rotate(-4deg); }\n  60%  { opacity: 1; transform: scale(1.04) rotate(0.5deg); }\n  100% { opacity: 1; transform: scale(1) rotate(0); }\n}\n@keyframes bk-press-shadow {\n  0%   { transform: translate(var(--bk-shadow-offset), var(--bk-shadow-offset)); }\n  100% { transform: translate(var(--bk-shadow-offset-press), var(--bk-shadow-offset-press)); }\n}\n@keyframes bk-reveal-up {\n  from { opacity: 0; transform: translateY(var(--bk-reveal-offset)); }\n  to   { opacity: 1; transform: translateY(0); }\n}\n@keyframes bk-reveal-down {\n  from { opacity: 0; transform: translateY(calc(var(--bk-reveal-offset) * -1)); }\n  to   { opacity: 1; transform: translateY(0); }\n}\n@keyframes bk-reveal-left {\n  from { opacity: 0; transform: translateX(var(--bk-reveal-offset)); }\n  to   { opacity: 1; transform: translateX(0); }\n}\n@keyframes bk-reveal-right {\n  from { opacity: 0; transform: translateX(calc(var(--bk-reveal-offset) * -1)); }\n  to   { opacity: 1; transform: translateX(0); }\n}\n@keyframes bk-slide-hard-x {\n  from { transform: translateX(100%); }\n  to   { transform: translateX(0); }\n}\n@keyframes bk-slide-hard-y {\n  from { transform: translateY(100%); }\n  to   { transform: translateY(0); }\n}\n@keyframes bk-shake-x {\n  0%, 100% { transform: translateX(0); }\n  20%      { transform: translateX(-6px); }\n  40%      { transform: translateX(6px); }\n  60%      { transform: translateX(-4px); }\n  80%      { transform: translateX(4px); }\n}\n@keyframes bk-pulse-shadow {\n  0%, 100% { transform: translate(var(--bk-shadow-offset), var(--bk-shadow-offset)); }\n  50%      { transform: translate(calc(var(--bk-shadow-offset) + 2px), calc(var(--bk-shadow-offset) + 2px)); }\n}\n\n/* ──────────────────────────────────────────────────────\n   L2 — Recipes\n   ────────────────────────────────────────────────────── */\n\n/* 1. PRESS — hard offset-shadow choreography on the snap curve. Mobile-safe.\n   Animates transform + box-shadow (not a negative-z pseudo) so it composes\n   correctly with a background colour: hover lifts and grows the shadow, active\n   presses into the page and collapses it. */\n.bk-press {\n  box-shadow: var(--bk-shadow-offset) var(--bk-shadow-offset) 0 hsl(var(--shadow-color));\n  transition: transform var(--bk-dur-snap) var(--bk-ease-snap),\n              box-shadow var(--bk-dur-snap) var(--bk-ease-snap);\n}\n.bk-press:hover {\n  transform: translate(calc(var(--bk-translate-press) * -1), calc(var(--bk-translate-press) * -1));\n  box-shadow: calc(var(--bk-shadow-offset) + var(--bk-translate-press)) calc(var(--bk-shadow-offset) + var(--bk-translate-press)) 0 hsl(var(--shadow-color));\n}\n.bk-press:active {\n  transform: translate(var(--bk-shadow-offset), var(--bk-shadow-offset));\n  box-shadow: var(--bk-shadow-offset-press) var(--bk-shadow-offset-press) 0 hsl(var(--shadow-color));\n  transition-duration: var(--bk-dur-instant);\n}\n@media (hover: none) {\n  .bk-press {\n    transition-duration: var(--bk-dur-instant);\n  }\n}\n\n/* 2. STAMP-IN — hard entrance */\n.bk-stamp-in        { animation: bk-stamp-in var(--bk-dur-base) var(--bk-ease-snap) both; }\n.bk-stamp-in-quick  { animation-duration: var(--bk-dur-quick); }\n.bk-stamp-in-slow   { animation-duration: var(--bk-dur-slow); }\n\n/* 3. SHAKE-X — error state */\n.bk-shake-x { animation: bk-shake-x var(--bk-dur-quick) var(--bk-ease-step-2); }\n\n/* 4. REVEAL — scroll-triggered (paired with L3 IntersectionObserver) */\n.bk-reveal { opacity: 0; }\n.bk-reveal-in              { animation: bk-reveal-up var(--bk-dur-quick) var(--bk-ease-snap) both; }\n.bk-reveal-up.bk-reveal-in    { animation-name: bk-reveal-up; }\n.bk-reveal-down.bk-reveal-in  { animation-name: bk-reveal-down; }\n.bk-reveal-left.bk-reveal-in  { animation-name: bk-reveal-left; }\n.bk-reveal-right.bk-reveal-in { animation-name: bk-reveal-right; }\n\n/* 5. SLIDE-HARD — stepped slide for drawers/sheets/tabs */\n.bk-slide-hard-x { animation: bk-slide-hard-x var(--bk-dur-quick) var(--bk-ease-step) both; }\n.bk-slide-hard-y { animation: bk-slide-hard-y var(--bk-dur-quick) var(--bk-ease-step) both; }\n\n/* 6. PULSE-SHADOW — attention/loading */\n.bk-pulse-shadow { position: relative; }\n.bk-pulse-shadow::after {\n  content: '';\n  position: absolute;\n  inset: 0;\n  z-index: -1;\n  background: hsl(var(--shadow-color));\n  transform: translate(var(--bk-shadow-offset), var(--bk-shadow-offset));\n  animation: bk-pulse-shadow 1.6s var(--bk-ease-snap) infinite;\n  pointer-events: none;\n}\n\n/* ──────────────────────────────────────────────────────\n   A11y — Universal reduced-motion guard\n   ────────────────────────────────────────────────────── */\n\n@media (prefers-reduced-motion: reduce) {\n  [class*=\"bk-press\"],\n  [class*=\"bk-stamp-in\"],\n  [class*=\"bk-shake\"],\n  [class*=\"bk-reveal\"],\n  [class*=\"bk-slide-hard\"],\n  [class*=\"bk-pulse-shadow\"] {\n    animation: none !important;\n    transition-duration: 0.01ms !important;\n  }\n}\n",
      "type": "registry:style",
      "target": "styles/motion.css"
    }
  ],
  "type": "registry:style"
}