56 if (kinds.has("scroll-state")) return item.role === "background" && /scroll|scene|sticky|pin|embed/.test(tokenText);
57 return false;
58 });
59 const activeKinds = Array.from(kinds);
60 const primitive = modelFor(activeKinds);
61 const requirements = [];
62 if (sceneMedia.some((item) => item.src)) requirements.push("Render each listed source-backed media surface with the recorded playback flags and scene role.");
63 if (sceneMedia.some((item) => item.fallback?.policy === "fallback-only")) requirements.push("Treat recorded posters/backgrounds as loading, blocked-media, or error fallbacks only; do not visibly blend them behind active media.");
64 if (sceneMedia.some((item) => !item.src)) requirements.push("Recreate the recorded runtime visual surface and its scene behavior; do not replace it with unrelated static imagery.");
65 if (kinds.has("carousel")) requirements.push("Render a finite-width data-rp-viewport that clips or scrolls a wider data-rp-track, preserve the captured card geometry, separation mechanism, and exact initial active state, then manage the captured active-card state on click plus every captured hover state.");
66 if (kinds.has("scroll-state")) requirements.push("Implement both entry progress and internal scroll progress: preserve media framing/sideways expansion through the captured entry and pinned phases, while applying transforms only to the measured motion owner and keeping static copy outside the visual scale scope.");
67 if (kinds.has("tabs")) requirements.push("Implement visible labels as buttons and switch the captured content state without replacing the scene background.");
68 const acceptance = [];
69 if (sceneMedia.some((item) => item.src)) acceptance.push("The implementation references the exact source URLs and preserves applicable playback flags.");
70 if (sceneMedia.some((item) => item.fallback?.policy === "fallback-only")) acceptance.push("No full-cover poster or image remains visibly composited with the active video/iframe.");
71 if (sceneMedia.some((item) => !item.src)) acceptance.push("The implementation preserves the runtime surface's visual role and recorded state changes.");
72 if (kinds.has("carousel")) acceptance.push("The viewport is narrower than the content track, and clicking a card changes its active/expanded state rather than only scrolling.");
73 if (kinds.has("scroll-state")) acceptance.push("Each captured scroll phase produces the corresponding distinct media/copy geometry; add a midpoint phase if source evidence has only endpoints.");
74 if (kinds.has("tabs")) acceptance.push("Each visible tab changes the text/content state while the section remains a single scene.");
221 bootstrap: "Add exactly once near the end of the document: <script type=\"module\" src=\"/site-clone/rp-interactions-bootstrap.mjs\"></script>",
222 warning: "A raw browser script must not import a relative module from src/. Use the public bootstrap above, or use the framework's compiled source import without type=module.",
223 };
224 if (primitive === "active-card-rail") return {
225 ...common,
226 steps: [
227 "Put data-rp-viewport on a finite-width overflow-x:auto or overflow:hidden element.",
228 "Put data-rp-track on its wider max-content flex/grid row; never put overflow on a max-content track.",
229 "Put data-rp-item on every card and data-rp-activate on the card activation control.",
230 "Set data-rp-initial-state to the captured invariant. Use all-collapsed when the source has no active item; never pre-open a card for visual variety.",
231 "Reproduce the recorded separation mechanism (track gap, margins, divider, or inner inset) rather than guessing a generic gap.",
232 "Mark the element with the source hover treatment as data-rp-hover-target and reproduce that treatment with :hover/:focus-visible CSS.",
233 "Style data-rp-active=true to reproduce the observed expanded/collapsed ratio; keep active links above any activation hit target.",
234 ],
235 };
236 if (primitive === "scroll-scene") return {
237 ...common,
238 steps: [
239 "Give the scene enough scroll height and mark only the measured pinned/scaled wrapper with data-rp-visual.",
240 "Mark independently positioned copy with data-rp-content. Do not nest it inside a scaling visual wrapper unless the source evidence explicitly records content scaling.",
241 "Use --rp-entry-progress for the approach expansion and --rp-scroll-progress for pinned/release phases.",
242 "When the source uses side curtains/masks, mark both with data-rp-curtain and reduce their widths as entry progress increases.",
243 "If tabs exist, give controls and panels matching data-rp-state values.",
244 "Do not render a fallback poster at the same time as an opaque active video/iframe.",
245 ],
246 };
247 if (primitive === "content-switcher") return {
248 ...common,
249 steps: [
250 "Give each visible control data-rp-item, data-rp-activate, and a unique data-rp-state.",
251 "Give its content panel the matching data-rp-panel and data-rp-state.",