@nodaro/prompts 1.17.2 → 1.19.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -9,6 +9,7 @@
9
9
 
10
10
  import { resolveTerm, type PickerHintMode } from "./term.js"
11
11
  import { overlayEntry } from "./catalog-overlay.js"
12
+ import { joinHintFragments } from "./hint-join.js"
12
13
 
13
14
  export type CameraMotionCategory =
14
15
  | "default"
@@ -78,28 +79,28 @@ export const CAMERA_MOTIONS: ReadonlyArray<CameraMotion> = [
78
79
  label: "Pan Left",
79
80
  category: "pan",
80
81
  description: "Rotate camera horizontally to the left",
81
- promptHint: "slow camera pan left, rotating horizontally",
82
+ promptHint: "The camera stays in exactly the same position and slowly pivots on the spot, rotating its aim to the left like a head turning, sweeping across the scene.\nThe camera does not travel anywhere: its position, its height and its distance to everything in the scene all stay constant, and only its aiming direction changes.\nBecause the camera is rotating rather than moving, there is no parallax at all: near and distant elements slide across the frame together at the same rate, from left to right, with no shift between them.\nThe subject drifts out toward the right edge of the frame as the camera turns away, and new parts of the scene enter from the left.\nNo zoom, no push-in, no sideways travel, no orbiting.",
82
83
  },
83
84
  {
84
85
  id: "pan-right",
85
86
  label: "Pan Right",
86
87
  category: "pan",
87
88
  description: "Rotate camera horizontally to the right",
88
- promptHint: "slow camera pan right, rotating horizontally",
89
+ promptHint: "The camera stays in exactly the same position and slowly pivots on the spot, rotating its aim to the right like a head turning, sweeping across the scene.\nThe camera does not travel anywhere: its position, its height and its distance to everything in the scene all stay constant, and only its aiming direction changes.\nBecause the camera is rotating rather than moving, there is no parallax at all: near and distant elements slide across the frame together at the same rate, from right to left, with no shift between them.\nThe subject drifts out toward the left edge of the frame as the camera turns away, and new parts of the scene enter from the right.\nNo zoom, no push-in, no sideways travel, no orbiting.",
89
90
  },
90
91
  {
91
92
  id: "whip-pan-left",
92
93
  label: "Whip Pan Left",
93
94
  category: "pan",
94
95
  description: "Fast whip pan left with motion blur",
95
- promptHint: "fast whip pan to the left with heavy motion blur",
96
+ promptHint: "The camera stays in exactly the same position and whips violently fast on the spot, snapping its aim to the left in one abrupt blurred sweep across the scene.\nThe camera does not travel anywhere: its position, its height and its distance to everything in the scene all stay constant, and only its aiming direction changes.\nThe rotation is so fast that the whole frame smears into heavy horizontal motion blur and the scene becomes briefly unreadable mid-sweep.\nBecause the camera is rotating rather than moving, there is no parallax at all: near and distant elements streak across the frame together at the same rate, from left to right.\nThe subject is flung out past the right edge of the frame almost immediately.\nNo zoom, no push-in, no sideways travel, no orbiting.",
96
97
  },
97
98
  {
98
99
  id: "whip-pan-right",
99
100
  label: "Whip Pan Right",
100
101
  category: "pan",
101
102
  description: "Fast whip pan right with motion blur",
102
- promptHint: "fast whip pan to the right with heavy motion blur",
103
+ promptHint: "The camera stays in exactly the same position and whips violently fast on the spot, snapping its aim to the right in one abrupt blurred sweep across the scene.\nThe camera does not travel anywhere: its position, its height and its distance to everything in the scene all stay constant, and only its aiming direction changes.\nThe rotation is so fast that the whole frame smears into heavy horizontal motion blur and the scene becomes briefly unreadable mid-sweep.\nBecause the camera is rotating rather than moving, there is no parallax at all: near and distant elements streak across the frame together at the same rate, from right to left.\nThe subject is flung out past the left edge of the frame almost immediately.\nNo zoom, no push-in, no sideways travel, no orbiting.",
103
104
  },
104
105
 
105
106
  // Tilt — rotation on horizontal axis
@@ -108,14 +109,14 @@ export const CAMERA_MOTIONS: ReadonlyArray<CameraMotion> = [
108
109
  label: "Tilt Up",
109
110
  category: "tilt",
110
111
  description: "Tilt camera upward",
111
- promptHint: "camera tilts upward, revealing upward from the ground",
112
+ promptHint: "The camera is locked to a tripod head at a fixed point in space and pivots on that head, tilting its aim upward like a head lifting to look higher.\nThe camera's height stays exactly the same for the entire shot, and the tripod stays planted in the same spot: the lens sweeps upward while the camera body itself never rises, never lowers and never travels.\nBecause the camera is rotating rather than moving, there is no parallax at all: near and distant elements slide down the frame together at the same rate, with no shift between them.\nWhatever occupied the bottom of the opening frame slides down and out past the bottom edge, and whatever lay above the top edge is progressively revealed as the aim rises.\nNo zoom, no push-in.",
112
113
  },
113
114
  {
114
115
  id: "tilt-down",
115
116
  label: "Tilt Down",
116
117
  category: "tilt",
117
118
  description: "Tilt camera downward",
118
- promptHint: "camera tilts downward, revealing downward from above",
119
+ promptHint: "The camera is locked to a tripod head at a fixed point in space and pivots on that head, tilting its aim downward like a head lowering to look lower.\nThe camera's height stays exactly the same for the entire shot, and the tripod stays planted in the same spot: the lens sweeps downward while the camera body itself never rises, never lowers and never travels.\nBecause the camera is rotating rather than moving, there is no parallax at all: near and distant elements slide up the frame together at the same rate, with no shift between them.\nWhatever occupied the top of the opening frame slides up and out past the top edge, and whatever lay below the bottom edge is progressively revealed as the aim lowers.\nNo zoom, no push-in.",
119
120
  },
120
121
 
121
122
  // Zoom — lens only
@@ -124,28 +125,28 @@ export const CAMERA_MOTIONS: ReadonlyArray<CameraMotion> = [
124
125
  label: "Zoom In",
125
126
  category: "zoom",
126
127
  description: "Lens zoom toward subject",
127
- promptHint: "slow zoom in on the subject, fixed camera position",
128
+ promptHint: "The camera is locked to a tripod planted in one spot and never moves at all. Only the lens changes: its focal length slowly increases, magnifying the image so the frame closes in on the subject.\nBecause the camera body does not travel, the perspective of the scene never changes: there is NO parallax whatsoever, nothing slides past anything else, and the spatial relationship between near and distant elements stays exactly as it was.\nEverything in the frame simply grows larger together at the same rate and the edges of the picture crop away, as if the whole photograph were being enlarged from its centre.\nThe subject fills progressively more of the frame while the background behind it flattens and compresses.\nNo camera travel, no dolly, no push-in, no walking forward, no orbiting.",
128
129
  },
129
130
  {
130
131
  id: "zoom-out",
131
132
  label: "Zoom Out",
132
133
  category: "zoom",
133
134
  description: "Lens zoom away from subject",
134
- promptHint: "slow zoom out, fixed camera position",
135
+ promptHint: "The camera is locked to a tripod planted in one spot and never moves at all. Only the lens changes: its focal length slowly decreases, widening the view so the frame opens out away from the subject.\nBecause the camera body does not travel, the perspective of the scene never changes: there is NO parallax whatsoever, nothing slides past anything else, and the spatial relationship between near and distant elements stays exactly as it was.\nEverything in the frame simply shrinks together at the same rate and more of the surroundings enters from all four edges, as if the whole photograph were being reduced towards its centre.\nThe subject fills progressively less of the frame while more and more of the wider environment is revealed around it.\nNo camera travel, no dolly, no pull-back, no walking backward, no orbiting.",
135
136
  },
136
137
  {
137
138
  id: "crash-zoom-in",
138
139
  label: "Crash Zoom In",
139
140
  category: "zoom",
140
141
  description: "Snappy whip-style zoom in",
141
- promptHint: "fast crash zoom in, snappy whip-style sudden dramatic zoom toward subject",
142
+ promptHint: "The camera is locked to a tripod planted in one spot and never moves at all. Only the lens changes: its focal length rockets up in one violent instant, snapping the frame hard onto the subject.\nThe zoom is so abrupt that the image judders and smears with motion blur during the snap, and the magnification slams to a stop rather than easing in.\nBecause the camera body does not travel, the perspective of the scene never changes: there is NO parallax whatsoever, nothing slides past anything else, and the spatial relationship between near and distant elements stays exactly as it was.\nEverything in the frame simply explodes larger together at the same rate and the edges of the picture crop violently away, as if the photograph were being blown up from its centre in a single jolt.\nNo camera travel, no dolly, no push-in, no walking forward, no orbiting.",
142
143
  },
143
144
  {
144
145
  id: "crash-zoom-out",
145
146
  label: "Crash Zoom Out",
146
147
  category: "zoom",
147
148
  description: "Snappy whip-style zoom out",
148
- promptHint: "fast crash zoom out, snappy whip-style sudden dramatic pull back",
149
+ promptHint: "The camera is locked to a tripod planted in one spot and never moves at all. Only the lens changes: its focal length drops away in one violent instant, snapping the frame wide open away from the subject.\nThe zoom is so abrupt that the image judders and smears with motion blur during the snap, and the widening slams to a stop rather than easing out.\nBecause the camera body does not travel, the perspective of the scene never changes: there is NO parallax whatsoever, nothing slides past anything else, and the spatial relationship between near and distant elements stays exactly as it was.\nEverything in the frame simply collapses smaller together at the same rate and a great deal more of the surroundings floods in from all four edges at once, as if the photograph were being shrunk towards its centre in a single jolt.\nNo camera travel, no dolly, no pull-back, no walking backward, no orbiting.",
149
150
  },
150
151
 
151
152
  // Dolly — physical forward/back
@@ -154,51 +155,51 @@ export const CAMERA_MOTIONS: ReadonlyArray<CameraMotion> = [
154
155
  label: "Dolly In",
155
156
  category: "dolly",
156
157
  description: "Push camera toward subject (parallax)",
157
- promptHint: "dolly in, camera pushes forward toward the subject with natural parallax",
158
+ promptHint: "The camera glides steadily FORWARD through the scene, physically travelling deeper into it and closing the distance to the subject. Nothing new is added to the scene; the viewpoint simply advances.\nThe lens never changes: the focal length is fixed for the entire shot, so nothing is magnified. The image changes only because the camera has moved to a new place.\nThe gap between the camera and the subject SHRINKS continuously: the subject grows steadily larger in the frame as the camera gets closer, and by the end it is much nearer and much bigger than at the start.\nEVERY part of the scene is in motion together, all of it expanding outward from the centre of the frame as the viewpoint advances, and the only difference between them is how fast: the closer something is to the camera the faster it grows and spreads toward the edges, and the further away it is the more gently and slowly it grows. It is one smooth continuous gradient of speed across every depth in the picture. Nothing anywhere in the frame is frozen or static, and nothing slides forward independently of the rest.\nNo zoom, no change of focal length, no sideways travel, no orbiting, no holding a constant distance, no following alongside.",
158
159
  },
159
160
  {
160
161
  id: "dolly-out",
161
162
  label: "Dolly Out",
162
163
  category: "dolly",
163
164
  description: "Pull camera away (parallax)",
164
- promptHint: "dolly out, camera pulls back away from the subject with natural parallax",
165
+ promptHint: "The camera glides steadily BACKWARD through the scene, physically retreating and opening up the distance to the subject. Nothing new is added to the scene; the viewpoint simply withdraws.\nThe lens never changes: the focal length is fixed for the entire shot, so nothing is shrunk optically. The image changes only because the camera has moved to a new place.\nThe gap between the camera and the subject GROWS continuously: the subject becomes steadily smaller in the frame as the camera pulls further away, and by the end it is much further off and much smaller than at the start.\nEVERY part of the scene is in motion together, all of it contracting inward toward the centre of the frame as the viewpoint retreats, and the only difference between them is how fast: the closer something is to the camera the faster it shrinks and slides in from the edges, and the further away it is the more gently and slowly it shrinks. It is one smooth continuous gradient of speed across every depth in the picture. Nothing anywhere in the frame is frozen or static, and nothing slides backward independently of the rest.\nNew foreground elements keep entering from behind the camera at the edges of the frame as it retreats.\nNo zoom, no change of focal length, no sideways travel, no orbiting, no holding a constant distance, no following alongside.",
165
166
  },
166
167
  {
167
168
  id: "dolly-zoom",
168
169
  label: "Dolly Zoom",
169
170
  category: "dolly",
170
171
  description: "Vertigo effect: dolly opposes zoom",
171
- promptHint: "dolly zoom vertigo effect, background scale changes while subject stays the same size",
172
+ promptHint: "Two opposite things happen at once, in perfect balance, and the tension between them IS the shot.\nFIRST, the camera body travels steadily FORWARD, physically advancing deeper into the scene and closing the distance to the subject.\nSECOND, at exactly the same time and at exactly the matching rate, the lens widens: the focal length decreases continuously throughout the move.\nBecause the two exactly cancel each other, THE SUBJECT NEVER CHANGES SIZE. It stays locked at the same scale and the same position in the frame from the first moment to the last, as if pinned there, and nothing about it grows or shrinks.\nWhat changes instead is DEPTH. As the camera advances and the lens widens, everything behind the subject appears to travel away from it and settle further and further off, so the distance between the subject and the far background stretches open and keeps stretching. What was close behind the subject ends up looking far behind it. The space reads as progressively deeper and longer, as though it were being drawn out lengthwise, while the subject itself stays exactly as it was.\nThe frame stays perfectly upright and level throughout. The camera never rolls, never tilts, never turns; the horizontal and vertical lines of the scene stay horizontal and vertical the whole time.\nNo cuts, no sideways travel, no orbiting, no rolling, no rotation of the frame, no tilting, and above all no change in the size of the subject.",
172
173
  },
173
174
  {
174
175
  id: "push-in",
175
176
  label: "Push In",
176
177
  category: "dolly",
177
- description: "Slow subtle push toward subject",
178
- promptHint: "slow push in, gentle forward movement toward the subject",
179
- term: "slow push-in",
178
+ description: "Fast forceful push toward subject",
179
+ promptHint: "The camera surges FORWARD hard and fast, driving deep into the scene and closing the distance to the subject in one assertive rush. Nothing new is added to the scene; the viewpoint simply advances.\nThe move is quick and forceful enough to be felt: the picture takes on a slight motion blur as it rushes in, and the advance carries real momentum rather than drifting gently.\nThe lens never changes: the focal length is fixed for the entire shot, so nothing is magnified. The image changes only because the camera has moved to a new place.\nThe gap between the camera and the subject SHRINKS rapidly: the subject swells quickly larger in the frame, and by the end it is far nearer and far bigger than at the start.\nEVERY part of the scene is in motion together, all of it expanding outward from the centre of the frame as the viewpoint advances, and the only difference between them is how fast: the closer something is to the camera the faster it grows and spreads toward the edges, and the further away it is the more gently and slowly it grows. It is one smooth continuous gradient of speed across every depth in the picture. Nothing anywhere in the frame is frozen or static, and nothing slides forward independently of the rest.\nNo zoom, no change of focal length, no sideways travel, no orbiting, no holding a constant distance, no following alongside.",
180
+ term: "fast push-in",
180
181
  },
181
182
  {
182
183
  id: "pull-out",
183
184
  label: "Pull Out",
184
185
  category: "dolly",
185
- description: "Slow subtle pull back from subject",
186
- promptHint: "slow pull out, gentle backward movement away from the subject",
187
- term: "slow pull-out",
186
+ description: "Fast forceful pull back from subject",
187
+ promptHint: "The camera pulls BACKWARD hard and fast, tearing away from the subject and opening up the distance in one decisive rush. Nothing new is added to the scene; the viewpoint simply withdraws.\nThe move is quick and forceful enough to be felt: the picture takes on a slight motion blur as it rushes back, and the retreat carries real momentum rather than drifting gently.\nThe lens never changes: the focal length is fixed for the entire shot, so nothing is shrunk optically. The image changes only because the camera has moved to a new place.\nThe gap between the camera and the subject GROWS rapidly: the subject shrinks quickly in the frame, and by the end it is far away and far smaller than at the start.\nEVERY part of the scene is in motion together, all of it contracting inward toward the centre of the frame as the viewpoint retreats, and the only difference between them is how fast: the closer something is to the camera the faster it shrinks and slides in from the edges, and the further away it is the more gently and slowly it shrinks. It is one smooth continuous gradient of speed across every depth in the picture. Nothing anywhere in the frame is frozen or static, and nothing slides backward independently of the rest.\nNew foreground elements keep entering from behind the camera at the edges of the frame as it retreats.\nNo zoom, no change of focal length, no sideways travel, no orbiting, no holding a constant distance, no following alongside.",
188
+ term: "fast pull-out",
188
189
  },
189
190
  {
190
191
  id: "breathing",
191
192
  label: "Breathing Camera",
192
193
  category: "dolly",
193
194
  description: "Subtle continuous push/pull oscillation",
194
- promptHint: "breathing camera, subtle continuous breathing-like push-in and pull-out oscillation with an organic handheld feel",
195
+ promptHint: "The camera breathes: it drifts gently FORWARD a small way, then eases back BACKWARD to about where it began, then forward again, in a slow continuous cycle that repeats several times across the shot, like the rise and fall of quiet breathing. Nothing new is added to the scene; only the viewpoint sways in and out.\nThis reversal is deliberate and is the whole point of the move. There is no pause and no hard stop at either end: the forward drift slows, turns over smoothly, and becomes the backward drift, then turns over again. The cycle is soft and rhythmic, never sharp.\nThe travel each way is small and the pace is slow and organic, never mechanical: the picture stays sharp with no motion blur, and it feels like a handheld operator quietly breathing behind the camera rather than a rig being driven.\nThe lens never changes: the focal length is fixed for the entire shot, so nothing is magnified. The image changes only because the camera has swayed to a slightly different place.\nThe gap between the camera and the subject accordingly shrinks a little, then opens a little, then shrinks again: the subject swells and settles gently in the frame in time with the cycle.\nEVERY part of the scene moves together with it, all of it expanding outward from the centre on each drift forward and contracting inward on each drift back, and the only difference between them is how fast: what is closest sways most, what is furthest hardly changes. It is one smooth continuous gradient across every depth. Nothing anywhere is frozen or static.\nNo zoom, no change of focal length, no sideways travel, no orbiting, no cuts.",
195
196
  },
196
197
  {
197
198
  id: "push-pull",
198
199
  label: "Push-Pull / Swing",
199
200
  category: "dolly",
200
201
  description: "Camera swings toward subject then away",
201
- promptHint: "push-pull swing, the camera moves toward the subject then back away in a single move, a swinging approach-and-retreat that creates emphasis or hesitation",
202
+ promptHint: "The camera drives decisively FORWARD a good distance, then reverses and pulls back BACKWARD past where it began, then drives forward again, in a deliberate push-and-pull cycle repeated across the shot. Nothing new is added to the scene; only the viewpoint swings in and out.\nThis reversal is deliberate and is the whole point of the move. Each stroke is firm and purposeful, with real travel behind it and a clear change of direction at each end, as if a rig were being driven in and hauled out again by hand. It is emphatic and mechanical, not gentle or organic, and the swing is far larger and more forceful than a quiet drift.\nThe lens never changes: the focal length is fixed for the entire shot, so nothing is magnified. The image changes only because the camera has travelled to a different place.\nThe gap between the camera and the subject accordingly closes sharply, opens up wide, then closes again: the subject looms noticeably larger, falls well back, and looms again in time with the cycle.\nEVERY part of the scene moves together with it, all of it expanding outward from the centre on each drive forward and rushing inward on each pull back, and the only difference between them is how fast: what is closest sweeps most, what is furthest shifts least. It is one smooth continuous gradient across every depth. Nothing anywhere is frozen or static.\nNo zoom, no change of focal length, no sideways travel, no orbiting, no cuts.",
202
203
  term: "push-pull swing",
203
204
  },
204
205
  {
@@ -206,7 +207,7 @@ export const CAMERA_MOTIONS: ReadonlyArray<CameraMotion> = [
206
207
  label: "Creep-In",
207
208
  category: "dolly",
208
209
  description: "Imperceptibly slow push-in over time",
209
- promptHint: "creep-in, imperceptibly slow push-in over many seconds, building dread or tension",
210
+ promptHint: "The camera creeps FORWARD almost imperceptibly slowly, edging deeper into the scene by the smallest amount and closing the distance to the subject only very slightly. Nothing new is added to the scene; the viewpoint simply inches forward.\nThe move is so gradual it is barely noticeable moment to moment: the picture stays completely sharp with no motion blur at all, the advance never accelerates, and only by comparing the end against the beginning is it clear the camera moved at all. It creates a slow, quiet, unsettling drift rather than any sense of momentum.\nThe lens never changes: the focal length is fixed for the entire shot, so nothing is magnified. The image changes only because the camera has crept to a slightly new place.\nThe gap between the camera and the subject SHRINKS very slightly and very steadily: the subject grows just a little larger in the frame across the whole shot.\nEVERY part of the scene is in motion together, all of it expanding outward from the centre of the frame by tiny degrees as the viewpoint edges forward, and the only difference between them is how fast: what is closest creeps outward most, what is furthest hardly changes at all. It is one smooth continuous gradient across every depth in the picture. Nothing anywhere is frozen or static, and nothing slides forward independently of the rest.\nNo zoom, no change of focal length, no sideways travel, no orbiting, no acceleration, no holding a constant distance.",
210
211
  term: "slow creeping push-in",
211
212
  },
212
213
  {
@@ -214,7 +215,7 @@ export const CAMERA_MOTIONS: ReadonlyArray<CameraMotion> = [
214
215
  label: "Creep-Out",
215
216
  category: "dolly",
216
217
  description: "Imperceptibly slow pull-out over time",
217
- promptHint: "creep-out, imperceptibly slow pull-out over many seconds, isolating the subject in space",
218
+ promptHint: "The camera creeps BACKWARD almost imperceptibly slowly, easing away from the scene by the smallest amount and opening the distance to the subject only very slightly. Nothing new is added to the scene; the viewpoint simply inches back.\nThe move is so gradual it is barely noticeable moment to moment: the picture stays completely sharp with no motion blur at all, the retreat never accelerates, and only by comparing the end against the beginning is it clear the camera moved at all. It creates a slow, quiet, unsettling drift rather than any sense of momentum.\nThe lens never changes: the focal length is fixed for the entire shot, so nothing is shrunk optically. The image changes only because the camera has crept to a slightly new place.\nThe gap between the camera and the subject GROWS very slightly and very steadily: the subject becomes just a little smaller in the frame across the whole shot.\nEVERY part of the scene is in motion together, all of it contracting inward toward the centre of the frame by tiny degrees as the viewpoint edges back, and the only difference between them is how fast: what is closest creeps inward most, what is furthest hardly changes at all. It is one smooth continuous gradient across every depth in the picture. Nothing anywhere is frozen or static, and nothing slides backward independently of the rest.\nNo zoom, no change of focal length, no sideways travel, no orbiting, no acceleration, no holding a constant distance.",
218
219
  term: "slow creeping pull-out",
219
220
  },
220
221
 
@@ -224,14 +225,14 @@ export const CAMERA_MOTIONS: ReadonlyArray<CameraMotion> = [
224
225
  label: "Truck Left",
225
226
  category: "truck",
226
227
  description: "Slide camera body laterally left",
227
- promptHint: "truck left, camera slides laterally to the left",
228
+ promptHint: "The camera glides steadily SIDEWAYS to the left, physically travelling laterally across the scene while continuing to aim straight ahead in exactly the same direction the whole time. It never turns or pivots; its aim stays locked forward and only its position slides left.\nThe lens never changes: the focal length is fixed for the entire shot, so nothing is magnified. The camera is passing across the scene, not approaching or retreating.\nThe framing is NOT locked onto anything: nothing is kept centred or held in place. EVERY single thing visible in the opening frame, including whatever sits at its very centre, slides steadily to the right across the picture and eventually passes out past the right edge as the viewpoint travels on past it.\nThe only difference between them is how fast: whatever is closest to the camera sweeps across and off the right edge quickly, things further back drift right more gently, and the most distant parts ease right slowest of all. It is one smooth continuous gradient of speed across every depth. Nothing anywhere is frozen, and nothing travels along with the camera.\nNew elements keep entering from the left edge as the camera advances sideways past them.\nNo zoom, no change of focal length, no turning, no pivoting, no rotation of the aim, no forward or backward travel, no tracking or following.",
228
229
  },
229
230
  {
230
231
  id: "truck-right",
231
232
  label: "Truck Right",
232
233
  category: "truck",
233
234
  description: "Slide camera body laterally right",
234
- promptHint: "truck right, camera slides laterally to the right",
235
+ promptHint: "The camera glides steadily SIDEWAYS to the right, physically travelling laterally across the scene while continuing to aim straight ahead in exactly the same direction the whole time. It never turns or pivots; its aim stays locked forward and only its position slides right.\nThe lens never changes: the focal length is fixed for the entire shot, so nothing is magnified. The camera is passing across the scene, not approaching or retreating.\nThe framing is NOT locked onto anything: nothing is kept centred or held in place. EVERY single thing visible in the opening frame, including whatever sits at its very centre, slides steadily to the left across the picture and eventually passes out past the left edge as the viewpoint travels on past it.\nThe only difference between them is how fast: whatever is closest to the camera sweeps across and off the left edge quickly, things further back drift left more gently, and the most distant parts ease left slowest of all. It is one smooth continuous gradient of speed across every depth. Nothing anywhere is frozen, and nothing travels along with the camera.\nNew elements keep entering from the right edge as the camera advances sideways past them.\nNo zoom, no change of focal length, no turning, no pivoting, no rotation of the aim, no forward or backward travel, no tracking or following.",
235
236
  },
236
237
 
237
238
  // Pedestal — vertical slide
@@ -240,14 +241,14 @@ export const CAMERA_MOTIONS: ReadonlyArray<CameraMotion> = [
240
241
  label: "Pedestal Up",
241
242
  category: "pedestal",
242
243
  description: "Raise camera body vertically",
243
- promptHint: "pedestal up, camera rises vertically while keeping the horizon level",
244
+ promptHint: "The camera is mounted on a column that raises it straight UPWARD, and it rises vertically, climbing steadily higher. The scene itself is entirely unchanged; nothing in it moves, falls, appears or is added. Only the viewpoint ascends.\nThe camera's aim never changes: it keeps pointing straight ahead at exactly the same angle for the entire shot, perfectly level, never tipping up or down as it climbs. Only its height changes.\nThe lens never changes either: the focal length is fixed, so nothing is magnified.\nBecause the camera physically travels upward, there is STRONG parallax: EVERY part of the scene is in motion together, all of it sliding downward through the frame as the viewpoint climbs, and the only difference between them is how fast. What is nearest the camera sinks and passes out of the bottom edge quickly, what is further back drifts down more gently, and the most distant parts ease down slowest of all. It is one smooth continuous gradient of speed across every depth. Nothing anywhere in the frame is frozen or static.\nWhatever lay above the top edge of the opening frame is revealed as the camera reaches its height, entering from the top and settling into view.\nNo zoom, no change of focal length, no tilting, no tipping the aim upward, no forward or sideways travel.",
244
245
  },
245
246
  {
246
247
  id: "pedestal-down",
247
248
  label: "Pedestal Down",
248
249
  category: "pedestal",
249
250
  description: "Lower camera body vertically",
250
- promptHint: "pedestal down, camera descends vertically while keeping the horizon level",
251
+ promptHint: "The camera is mounted on a column that lowers it straight DOWNWARD, and it descends vertically, sinking steadily lower. The scene itself is entirely unchanged; nothing in it moves, falls, appears or is added. Only the viewpoint descends.\nThe camera's aim never changes: it keeps pointing straight ahead at exactly the same angle for the entire shot, perfectly level, never tipping up or down as it sinks. Only its height changes.\nThe lens never changes either: the focal length is fixed, so nothing is magnified.\nBecause the camera physically travels downward, there is STRONG parallax: EVERY part of the scene is in motion together, all of it sliding upward through the frame as the viewpoint sinks, and the only difference between them is how fast. What is nearest the camera climbs and passes out of the top edge quickly, what is further back drifts up more gently, and the most distant parts ease up slowest of all. It is one smooth continuous gradient of speed across every depth. Nothing anywhere in the frame is frozen or static.\nWhatever lay below the bottom edge of the opening frame is revealed as the camera sinks to its level, entering from the bottom and settling into view.\nNo zoom, no change of focal length, no tilting, no tipping the aim downward, no forward or sideways travel.",
251
252
  },
252
253
 
253
254
  // Roll — rotation on lens axis
@@ -286,37 +287,37 @@ export const CAMERA_MOTIONS: ReadonlyArray<CameraMotion> = [
286
287
  id: "orbit-left",
287
288
  label: "Orbit Left",
288
289
  category: "orbit",
289
- description: "Full circle around subject to the left",
290
- promptHint: "camera orbits around the subject to the left in a circular path",
290
+ description: "Large partial orbit around subject to the left",
291
+ promptHint: "camera orbits around the subject in a circular path, the background sliding to the left across the frame",
291
292
  },
292
293
  {
293
294
  id: "orbit-right",
294
295
  label: "Orbit Right",
295
296
  category: "orbit",
296
- description: "Full circle around subject to the right",
297
- promptHint: "camera orbits around the subject to the right in a circular path",
297
+ description: "Large partial orbit around subject to the right",
298
+ promptHint: "camera orbits around the subject in a circular path, the background sliding to the right across the frame",
298
299
  },
299
300
  {
300
301
  id: "arc-left",
301
302
  label: "Arc Left",
302
303
  category: "orbit",
303
304
  description: "Partial arc around subject left",
304
- promptHint: "camera arcs to the left around the subject",
305
+ promptHint: "slow camera arc around the subject through a partial arc, the background sliding to the left across the frame",
305
306
  },
306
307
  {
307
308
  id: "arc-right",
308
309
  label: "Arc Right",
309
310
  category: "orbit",
310
311
  description: "Partial arc around subject right",
311
- promptHint: "camera arcs to the right around the subject",
312
+ promptHint: "The camera slowly moves sideways to the right while curving around the subject, continuously turning toward the subject to keep the same centered framing.\nThe camera maintains constant distance from the subject.\nAs the viewpoint changes, strong natural parallax is visible: nearby environmental elements shift right noticeably while distant background elements shift right more slowly.\nThe shot ends from a slightly different three-quarter viewing angle.\nNo zoom, no push-in, no pull-out.",
312
313
  },
313
314
  {
314
315
  id: "orbit-360",
315
316
  label: "Full 360 Orbit",
316
317
  category: "orbit",
317
318
  description: "Full circular arc around subject",
318
- promptHint: "full 360 degree orbit, the camera arcs a complete revolution around the subject",
319
- term: "full 360 degree orbit",
319
+ promptHint: "The camera moves sideways to the right while curving around the subject, continuously turning toward the subject to keep the same centered framing, and keeps travelling in the same direction without pausing until it has passed the subject's right side, then behind it, then its left side, and comes back to where it began.\nThe camera maintains constant distance and constant height from the subject throughout.\nAs the viewpoint changes, strong natural parallax is visible: nearby environmental elements sweep right past the frame edge while distant background elements shift right more slowly, and every part of the surroundings passes behind the subject in turn, until whatever was behind it at the start is behind it again at the end.\nThe shot ends on the exact same viewpoint and composition it started from, having circled the subject completely.\nNo zoom, no push-in, no pull-out, no reversal of direction.",
320
+ term: "full orbit, one complete circle around the subject",
320
321
  },
321
322
 
322
323
  // Crane / Jib
@@ -325,14 +326,14 @@ export const CAMERA_MOTIONS: ReadonlyArray<CameraMotion> = [
325
326
  label: "Crane Up",
326
327
  category: "crane",
327
328
  description: "Sweeping crane rise revealing scene",
328
- promptHint: "crane up, camera rises on a jib revealing the wider scene",
329
+ promptHint: "The camera is carried on the end of a long jib arm that swings it UPWARD and OUTWARD through a rising arc, so it climbs steadily higher and at the same time draws back and away from where it started. The scene itself is entirely unchanged; nothing in it moves, falls, appears or is added. Only the viewpoint travels.\nUnlike a straight vertical lift, the aim DOES change: as the camera rises it tips gradually downward, angling more and more steeply so that what began level with it is now looked down upon from above. The rise and the tilt happen together as one continuous sweeping arc.\nThe lens never changes: the focal length is fixed, so nothing is magnified.\nBecause the camera physically travels, there is STRONG parallax: EVERY part of the scene is in motion together, sliding downward and outward through the frame as the viewpoint climbs and pulls back, and the only difference between them is how fast. What is nearest the camera sweeps down and out of the bottom edge quickly, what is further back drifts more gently, and the most distant parts ease slowest of all. It is one smooth continuous gradient of speed across every depth. Nothing anywhere in the frame is frozen or static.\nThe shot ends on a high, wide, elevated vantage looking down over the whole scene, far above and behind where it began.\nNo zoom, no change of focal length, no sideways drift, no orbiting.",
329
330
  },
330
331
  {
331
332
  id: "crane-down",
332
333
  label: "Crane Down",
333
334
  category: "crane",
334
335
  description: "Sweeping crane descent",
335
- promptHint: "crane down, camera descends from above toward the subject",
336
+ promptHint: "The camera is carried on the end of a long jib arm that swings it DOWNWARD and INWARD through a descending arc, so it drops steadily lower and at the same time closes in toward what lay beneath it. The scene itself is entirely unchanged; nothing in it moves, falls, appears or is added. Only the viewpoint travels.\nUnlike a straight vertical descent, the aim DOES change: as the camera drops it tips gradually upward, levelling out more and more, so that what was looked down upon from above is now met at its own level. The fall and the tilt happen together as one continuous sweeping arc.\nThe lens never changes: the focal length is fixed, so nothing is magnified.\nBecause the camera physically travels, there is STRONG parallax: EVERY part of the scene is in motion together, sliding upward and inward through the frame as the viewpoint drops and closes in, and the only difference between them is how fast. What is nearest the camera sweeps up and out of the top edge quickly, what is further back drifts more gently, and the most distant parts ease slowest of all. It is one smooth continuous gradient of speed across every depth. Nothing anywhere in the frame is frozen or static.\nThe shot ends on a low, close vantage, far below and ahead of where it began.\nNo zoom, no change of focal length, no sideways drift, no orbiting.",
336
337
  },
337
338
  {
338
339
  id: "boom-up",
@@ -532,9 +533,8 @@ export const CAMERA_MOTIONS: ReadonlyArray<CameraMotion> = [
532
533
  id: "match-cut-zoom",
533
534
  label: "Match Cut Zoom",
534
535
  category: "zoom",
535
- description: "Beat-timed zoom for cuts",
536
- promptHint: "rapid zoom timed to a beat, suggesting a match cut to the next shot",
537
- term: "rapid beat-timed zoom",
536
+ description: "Fast zoom that hard-cuts to a matching shape",
537
+ promptHint: "A match cut built on a zoom, in two shots joined by one hard cut.\nShot one: the camera is locked to a tripod and never travels; only the lens changes, its focal length rapidly increasing so the frame rushes in and closes tightly on a single round shape at the centre of the picture, until that circular shape fills almost the whole frame.\nAt the moment the round shape fills the frame there is one HARD CUT.\nShot two: a completely different place and time, but a round shape of the same size sits in exactly the same position at the centre of the frame, so the two shots lock together on that shape and the eye reads it as one continuous movement. The camera continues the same inward push for a moment before settling.\nThe two shots share only the shape and its position; the location, the light and everything else are entirely different.\nNo camera travel in either shot, no dolly, no orbiting.",
538
538
  },
539
539
  {
540
540
  id: "screen-tap",
@@ -651,7 +651,9 @@ export const CAMERA_MOTION_IDS: ReadonlyArray<string> = CAMERA_MOTIONS.map((m) =
651
651
  * - End only → "<motion>, ending with <end hints joined>".
652
652
  * - Both → "<motion>, beginning with <start>, ending with <end>".
653
653
  *
654
- * Hints within each side are joined with " and " for grammatical flow.
654
+ * Hints within each side are joined with " and " for grammatical flow. The
655
+ * clauses attach with a comma after a clause-style motion hint and with a
656
+ * space after one that already ends a sentence (see `joinHintFragments`).
655
657
  * If multiple nodes are connected (e.g. Framing + Lighting + Tone), all
656
658
  * three contribute their hint to the clause.
657
659
  *
@@ -676,7 +678,7 @@ export function composeCameraMotionHintFromConnections(
676
678
  const endClause = endHints.filter((h) => h && h.length > 0).join(" and ")
677
679
  if (startClause) parts.push(`beginning with ${startClause}`)
678
680
  if (endClause) parts.push(`ending with ${endClause}`)
679
- return parts.join(", ")
681
+ return joinHintFragments(parts)
680
682
  }
681
683
 
682
684
  /**