// [nexus] Phase 12 — PromoteTransition. // // CSS-first animation container that drives the 700ms compress-and-rise // moment from spec §5.6. When `state` is `prompting` or `creating`: // // 0–200ms : chat ribbon collapses 100% → 30vh (inset shadow fades in) // 200–500ms: brainstormer panel slides up from below into bottom 70% // 500–700ms: SOURCE CONVERSATION label fades in above the ribbon // // On `idle` / `done` the overlay unmounts. `prefers-reduced-motion` is // honored via inline CSS — transitions are set to `none`. // // This component is intentionally CSS-only; no motion library dependency. import { useEffect, useRef } from "react"; import { cn } from "@/lib/utils"; export type PromoteTransitionState = "idle" | "prompting" | "creating" | "done" | "error"; export interface PromoteTransitionProps { /** The hook's promote state kind. */ state: PromoteTransitionState; /** * The compressed chat ribbon. Caller passes whatever the source view * should look like — usually the current ChatMessageList in a scrollable * container. */ children: React.ReactNode; /** * The rising brainstormer panel content. Usually . */ panelChildren: React.ReactNode; className?: string; } // Inlined styles for the transition so we do NOT need to touch the global // stylesheet. A {/* SOURCE CONVERSATION label */}
Source Conversation
{/* Compressed chat ribbon */}
{children}
{/* Rising brainstormer panel */}
{panelChildren}
); }