{
  "version": "1.1.0",
  "classification": "Reconstructed and original reference contracts; not a claim about Raycast private code.",
  "contracts": [
    {
      "id": "control-press",
      "owner": ".button",
      "trigger": "Pointer press / release",
      "from": "scale(1)",
      "to": "scale(.98)",
      "duration": "100 ms",
      "easing": "ease-in-out",
      "delay": "0 ms",
      "interruption": "Release or drag away reverses from the current interpolated value. Disabled controls have no transform."
    },
    {
      "id": "control-color",
      "owner": ".button, .nav-link, .input-wrap",
      "trigger": "Hover, keyboard focus or focus-within",
      "from": "Declared resting paint",
      "to": "Declared hover/focus paint",
      "duration": "200 ms",
      "easing": "ease; button shadow uses ease-in-out",
      "delay": "0 ms",
      "interruption": "The next state replaces the target. No queued animation or delayed action."
    },
    {
      "id": "card-lift",
      "owner": ".panel-link, .extension-card",
      "trigger": "Pointer enters / leaves",
      "from": "translateY(0)",
      "to": "Panel link: translateY(-3px); extension card: translateY(-2px)",
      "duration": "200 ms",
      "easing": "ease",
      "delay": "0 ms",
      "interruption": "Reverse on pointer leave. Reduced motion keeps the transform at none."
    },
    {
      "id": "switch",
      "owner": ".toggle input::before",
      "trigger": "Native checked state",
      "from": "translateX(0)",
      "to": "translateX(12px)",
      "duration": "200 ms",
      "easing": "ease",
      "delay": "0 ms",
      "interruption": "A new checked value replaces the target. Checked state, label and accessibility tree update immediately."
    },
    {
      "id": "tooltip",
      "owner": ".tooltip",
      "trigger": "Hover or focus; Escape dismisses",
      "from": "opacity 0 / hidden",
      "to": "opacity 1 / visible",
      "duration": "100 ms",
      "easing": "ease",
      "delay": "0 ms",
      "interruption": "Escape hides the tooltip until focus or pointer enters again. It owns no focus."
    },
    {
      "id": "spinner",
      "owner": ".button .spinner",
      "trigger": "Visible pending specimen",
      "from": "rotate(0)",
      "to": "rotate(1turn)",
      "duration": "800 ms per loop",
      "easing": "linear",
      "delay": "0 ms",
      "interruption": "A disabled pending control prevents repeat activation. Reduced motion replaces rotation with a static complete ring and visible status text."
    },
    {
      "id": "skeleton",
      "owner": ".skeleton",
      "trigger": "Collection loading state",
      "from": "background-position 0% 0%",
      "to": "background-position -200% 0",
      "duration": "1800 ms per loop",
      "easing": "ease-in-out",
      "delay": "0 ms",
      "interruption": "State replacement removes the loading DOM. Reduced motion uses a static fill; the Loading status remains readable."
    },
    {
      "id": "dialog",
      "owner": "Native dialog; assets/reference.js",
      "trigger": "Named trigger, Escape, close button or backdrop",
      "from": "Closed",
      "to": "Open modal, then closed",
      "duration": "0 ms; no entrance choreography",
      "easing": "None",
      "delay": "0 ms",
      "interruption": "Repeated open is ignored. Escape closes once and returns focus to the actual connected opener. Dismissal does not clear the search query."
    },
    {
      "id": "form-feedback",
      "owner": "[data-local-form]",
      "trigger": "Valid submit",
      "from": "Editable draft",
      "to": "Checking, then success / error / offline",
      "duration": "450 ms local simulation",
      "easing": "None; semantic state change",
      "delay": "0 ms",
      "interruption": "A pending guard ignores repeat submissions. All controls restore their previous disabled state; failed drafts remain intact."
    },
    {
      "id": "route-and-detail",
      "owner": "Native links and collection focus handlers",
      "trigger": "Follow a reference link or change page",
      "from": "Current document or collection page",
      "to": "Target document or next page of items",
      "duration": "Native navigation; no fabricated transition duration",
      "easing": "None",
      "delay": "No artificial delay",
      "interruption": "The browser owns load cancellation and history. A collection page change focuses its first result; filtering resets its page index."
    },
    {
      "id": "media-lifecycle",
      "owner": "assets/media-lifecycle.mjs",
      "trigger": "Document hidden or pagehide",
      "from": "Optional user-started audio/video",
      "to": "Paused",
      "duration": "Synchronous event handler",
      "easing": "None",
      "delay": "0 ms",
      "interruption": "Preserve current time while the document exists. Visibility restoration does not restart playback. Native controls own explicit resume and seeking."
    },
    {
      "id": "hero-artwork",
      "owner": ".hero-backdrop; RAY-002 exception",
      "trigger": "Page load",
      "from": "Frozen captured frame",
      "to": "Same frame",
      "duration": "Static local reconstruction",
      "easing": "None",
      "delay": "None",
      "interruption": "Original WebGL animation is not reproduced. The WebP derivative is pixel-identical to the retained PNG; no motion-dependent information is removed."
    }
  ],
  "sharedMode": "prefers-reduced-motion removes nonessential interpolation and infinite animation. Native state, text and focus remain available. No JS animation frame loop is installed."
}
