@nodaro/prompts 1.0.1

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.
Files changed (150) hide show
  1. package/LICENSE +105 -0
  2. package/README.md +27 -0
  3. package/dist/index.cjs +21240 -0
  4. package/dist/index.cjs.map +1 -0
  5. package/dist/index.d.cts +3599 -0
  6. package/dist/index.d.ts +3599 -0
  7. package/dist/index.js +20854 -0
  8. package/dist/index.js.map +1 -0
  9. package/package.json +49 -0
  10. package/src/__tests__/__snapshots__/prompt-builder-segments.test.ts.snap +65 -0
  11. package/src/__tests__/action-fx.test.ts +155 -0
  12. package/src/__tests__/apply-picker-json.test.ts +50 -0
  13. package/src/__tests__/assemble-image-input.test.ts +248 -0
  14. package/src/__tests__/assemble-suno-input.test.ts +283 -0
  15. package/src/__tests__/brand-tokens.test.ts +81 -0
  16. package/src/__tests__/build-image-prompt-element-injection.test.ts +118 -0
  17. package/src/__tests__/build-image-prompt-hybrid-format.test.ts +131 -0
  18. package/src/__tests__/build-image-prompt-mentions.test.ts +809 -0
  19. package/src/__tests__/build-image-prompt-reference-cap.test.ts +57 -0
  20. package/src/__tests__/build-image-prompt-reference-numbering.test.ts +237 -0
  21. package/src/__tests__/build-image-prompt-reference-order.test.ts +313 -0
  22. package/src/__tests__/camera-motions-from-connections.test.ts +71 -0
  23. package/src/__tests__/catalog-gapfill.test.ts +53 -0
  24. package/src/__tests__/character-convergence-image.test.ts +217 -0
  25. package/src/__tests__/character-default-role-image.test.ts +167 -0
  26. package/src/__tests__/character-default-role-video.test.ts +168 -0
  27. package/src/__tests__/character-default-role.test.ts +70 -0
  28. package/src/__tests__/character-fx.test.ts +200 -0
  29. package/src/__tests__/entity-prompts-location.test.ts +97 -0
  30. package/src/__tests__/entity-prompts.test.ts +240 -0
  31. package/src/__tests__/expand-extra-refs-role.test.ts +50 -0
  32. package/src/__tests__/factory-presets.test.ts +1045 -0
  33. package/src/__tests__/factory-snippets.test.ts +68 -0
  34. package/src/__tests__/framing-multi.test.ts +71 -0
  35. package/src/__tests__/framing-vantage.test.ts +39 -0
  36. package/src/__tests__/i18n-entry-completeness.test.ts +269 -0
  37. package/src/__tests__/identity-lock.test.ts +46 -0
  38. package/src/__tests__/instrumentation.test.ts +68 -0
  39. package/src/__tests__/lighting-multi.test.ts +68 -0
  40. package/src/__tests__/location-convergence-image.test.ts +124 -0
  41. package/src/__tests__/mention-lock-flag.test.ts +499 -0
  42. package/src/__tests__/multi-picker-spec.test.ts +71 -0
  43. package/src/__tests__/music-genre.test.ts +103 -0
  44. package/src/__tests__/music-mood.test.ts +87 -0
  45. package/src/__tests__/object-creature-convergence-image.test.ts +105 -0
  46. package/src/__tests__/parameter-prompt-hint.test.ts +270 -0
  47. package/src/__tests__/parameter-registry-sync.test.ts +243 -0
  48. package/src/__tests__/person-age.test.ts +80 -0
  49. package/src/__tests__/person-analyzer-invariants.test.ts +47 -0
  50. package/src/__tests__/person-body-axes.test.ts +67 -0
  51. package/src/__tests__/person-facial-geometry.test.ts +156 -0
  52. package/src/__tests__/person-regional-aesthetic.test.ts +161 -0
  53. package/src/__tests__/person-sections.test.ts +18 -0
  54. package/src/__tests__/picker-analyzer-registry.test.ts +108 -0
  55. package/src/__tests__/picker-catalogs-project.test.ts +85 -0
  56. package/src/__tests__/picker-catalogs.test.ts +53 -0
  57. package/src/__tests__/picker-limits.test.ts +20 -0
  58. package/src/__tests__/prompt-builder-segments.test.ts +183 -0
  59. package/src/__tests__/prompt-builder-structured-fields.test.ts +40 -0
  60. package/src/__tests__/prompt-builder.test.ts +1773 -0
  61. package/src/__tests__/prompt-wizard-categories.test.ts +31 -0
  62. package/src/__tests__/provider-prompt-doctrine.test.ts +49 -0
  63. package/src/__tests__/resolve-prompt-append.test.ts +58 -0
  64. package/src/__tests__/resolve-prompt.test.ts +44 -0
  65. package/src/__tests__/role-picker-shared.test.ts +208 -0
  66. package/src/__tests__/seedance-2-inputs.test.ts +173 -0
  67. package/src/__tests__/seedance-extend.test.ts +44 -0
  68. package/src/__tests__/sound-aggregator.test.ts +350 -0
  69. package/src/__tests__/style-presets.test.ts +34 -0
  70. package/src/__tests__/temporal-multi.test.ts +74 -0
  71. package/src/__tests__/transitions.test.ts +213 -0
  72. package/src/__tests__/video-reference-features.test.ts +41 -0
  73. package/src/__tests__/video-reference-leading-refs.test.ts +90 -0
  74. package/src/__tests__/video-reference-resolver.test.ts +233 -0
  75. package/src/__tests__/video-reference-roles.test.ts +96 -0
  76. package/src/__tests__/voice-character.test.ts +48 -0
  77. package/src/__tests__/voice-delivery.test.ts +41 -0
  78. package/src/__tests__/wardrobe.test.ts +25 -0
  79. package/src/action-fx.ts +255 -0
  80. package/src/aesthetic.ts +435 -0
  81. package/src/assemble-image-input.ts +236 -0
  82. package/src/assemble-suno-input.ts +147 -0
  83. package/src/atmosphere.ts +104 -0
  84. package/src/backdrop.ts +131 -0
  85. package/src/brand-tokens.ts +154 -0
  86. package/src/camera-format.ts +76 -0
  87. package/src/camera-motions.ts +615 -0
  88. package/src/character-fx.ts +274 -0
  89. package/src/color-look.ts +103 -0
  90. package/src/composition-effects.ts +67 -0
  91. package/src/entity-prompts.ts +231 -0
  92. package/src/era.ts +292 -0
  93. package/src/exposure-settings.ts +142 -0
  94. package/src/factory-presets/generate-image.ts +1644 -0
  95. package/src/factory-presets/generate-video.ts +1116 -0
  96. package/src/factory-presets/index.ts +46 -0
  97. package/src/factory-presets/lottie-overlay.ts +166 -0
  98. package/src/factory-presets/motion-graphics.ts +350 -0
  99. package/src/factory-presets/music.ts +734 -0
  100. package/src/factory-presets/sfx.ts +136 -0
  101. package/src/factory-presets/shared-image.ts +207 -0
  102. package/src/factory-presets/switchx.ts +65 -0
  103. package/src/factory-presets/text.ts +292 -0
  104. package/src/factory-presets/types.ts +51 -0
  105. package/src/factory-presets/video-edit.ts +136 -0
  106. package/src/factory-presets/voice.ts +172 -0
  107. package/src/factory-presets.ts +2 -0
  108. package/src/factory-snippets/catalog.ts +105 -0
  109. package/src/factory-snippets/index.ts +16 -0
  110. package/src/factory-snippets/types.ts +33 -0
  111. package/src/framing.ts +634 -0
  112. package/src/held-prop.ts +187 -0
  113. package/src/identity-lock.ts +213 -0
  114. package/src/index.ts +66 -0
  115. package/src/instrumentation.ts +337 -0
  116. package/src/lens.ts +59 -0
  117. package/src/lighting.ts +229 -0
  118. package/src/loop-subject.ts +276 -0
  119. package/src/materials.ts +184 -0
  120. package/src/mood.ts +186 -0
  121. package/src/music-genre.ts +662 -0
  122. package/src/music-mood.ts +137 -0
  123. package/src/object-asset-presets.ts +81 -0
  124. package/src/parameter-prompt-hint.ts +281 -0
  125. package/src/person.ts +1368 -0
  126. package/src/photo-genre.ts +151 -0
  127. package/src/photographer.ts +612 -0
  128. package/src/picker-analyzer-registry.ts +374 -0
  129. package/src/picker-catalogs.ts +858 -0
  130. package/src/pose.ts +246 -0
  131. package/src/post-process-effects.ts +94 -0
  132. package/src/prompt-builder-structured-fields.ts +116 -0
  133. package/src/prompt-builder.ts +2964 -0
  134. package/src/prompt-templates.ts +50 -0
  135. package/src/prompt-wizard-categories.ts +334 -0
  136. package/src/provider-prompt-doctrine.ts +85 -0
  137. package/src/render-quality.ts +89 -0
  138. package/src/resolve-prompt.ts +120 -0
  139. package/src/seedance-2-inputs.ts +100 -0
  140. package/src/setting.ts +130 -0
  141. package/src/sound-aggregator.ts +241 -0
  142. package/src/style-presets.ts +162 -0
  143. package/src/style.ts +99 -0
  144. package/src/styling.ts +585 -0
  145. package/src/temporal.ts +151 -0
  146. package/src/transitions.ts +333 -0
  147. package/src/video-reference-resolver.ts +823 -0
  148. package/src/voice-character.ts +237 -0
  149. package/src/voice-delivery.ts +142 -0
  150. package/src/wardrobe.ts +179 -0
@@ -0,0 +1,612 @@
1
+ /**
2
+ * Canonical catalog of Photographer / Artist Style choices.
3
+ *
4
+ * Single-pick parameter node — user picks ONE photographer or illustrator
5
+ * whose visual signature should drive the look. Each promptHint pairs the
6
+ * artist's name with a couple of distinguishing visual cues, because
7
+ * generative models recognise both the name token and the descriptive
8
+ * vocabulary that surrounds it. Names alone tend to be too vague.
9
+ *
10
+ * Categories:
11
+ * - editorial: fashion / editorial photographers (dreamy painterly look)
12
+ * - documentary: documentary, street, photojournalism
13
+ * - cinematographer: working DPs whose work translates well to stills
14
+ * - concept: digital painters, concept artists, fantasy illustrators
15
+ * - illustrator: illustrators, animators, art-nouveau / classical artists
16
+ *
17
+ * Shared between the picker UI, the standalone Photographer parameter node,
18
+ * and the prompt-hint injection on both the frontend DAG executor and the
19
+ * backend orchestrator.
20
+ */
21
+
22
+ export type PhotographerCategory =
23
+ | "editorial"
24
+ | "documentary"
25
+ | "cinematographer"
26
+ | "concept"
27
+ | "illustrator"
28
+
29
+ export interface Photographer {
30
+ readonly id: string
31
+ readonly label: string
32
+ readonly category: PhotographerCategory
33
+ readonly description: string
34
+ readonly promptHint: string
35
+ }
36
+
37
+ export const PHOTOGRAPHERS: ReadonlyArray<Photographer> = [
38
+ // -------------------- Editorial / Fashion --------------------
39
+ {
40
+ id: "tim-walker",
41
+ label: "Tim Walker",
42
+ category: "editorial",
43
+ description: "Painterly fairytale fashion",
44
+ promptHint:
45
+ "in the style of Tim Walker, painterly fairytale fashion staging with elaborate hand-built sets and a soft pastel palette",
46
+ },
47
+ {
48
+ id: "paolo-roversi",
49
+ label: "Paolo Roversi",
50
+ category: "editorial",
51
+ description: "Soft, ethereal Polaroid glow",
52
+ promptHint:
53
+ "in the style of Paolo Roversi, soft ethereal Polaroid glow with diffused window light and a warm milky bath",
54
+ },
55
+ {
56
+ id: "marta-bevacqua",
57
+ label: "Marta Bevacqua",
58
+ category: "editorial",
59
+ description: "Dreamy painterly portraiture",
60
+ promptHint:
61
+ "in the style of Marta Bevacqua, dreamy painterly portraiture with hushed natural light and faintly desaturated skin tones",
62
+ },
63
+ {
64
+ id: "patrick-demarchelier",
65
+ label: "Patrick Demarchelier",
66
+ category: "editorial",
67
+ description: "Refined classic fashion portrait",
68
+ promptHint:
69
+ "in the style of Patrick Demarchelier, refined classic fashion portraiture with crisp catchlights and timeless restraint",
70
+ },
71
+ {
72
+ id: "nick-knight",
73
+ label: "Nick Knight",
74
+ category: "editorial",
75
+ description: "High-gloss avant-garde fashion",
76
+ promptHint:
77
+ "in the style of Nick Knight, high-gloss avant-garde fashion with saturated color, precision sharpness and surreal staging",
78
+ },
79
+ {
80
+ id: "mario-testino",
81
+ label: "Mario Testino",
82
+ category: "editorial",
83
+ description: "Glamorous, sun-soaked fashion",
84
+ promptHint:
85
+ "in the style of Mario Testino, glamorous sun-soaked fashion energy with confident posing and bright editorial color",
86
+ },
87
+ {
88
+ id: "steven-meisel",
89
+ label: "Steven Meisel",
90
+ category: "editorial",
91
+ description: "Polished mid-century editorial",
92
+ promptHint:
93
+ "in the style of Steven Meisel, polished mid-century editorial portraiture with controlled studio light and meticulous styling",
94
+ },
95
+ {
96
+ id: "helmut-newton",
97
+ label: "Helmut Newton",
98
+ category: "editorial",
99
+ description: "Bold black-and-white provocation",
100
+ promptHint:
101
+ "in the style of Helmut Newton, bold black-and-white provocation with hard flash, deep shadows and architectural composition",
102
+ },
103
+ {
104
+ id: "mario-sorrenti",
105
+ label: "Mario Sorrenti",
106
+ category: "editorial",
107
+ description: "Intimate, grainy fashion",
108
+ promptHint:
109
+ "in the style of Mario Sorrenti, intimate grainy fashion photography with raw natural light and confessional closeness",
110
+ },
111
+ {
112
+ id: "annie-leibovitz",
113
+ label: "Annie Leibovitz",
114
+ category: "editorial",
115
+ description: "Cinematic celebrity portrait",
116
+ promptHint:
117
+ "in the style of Annie Leibovitz, cinematic celebrity portraiture with theatrical staging and warm dimensional lighting",
118
+ },
119
+ {
120
+ id: "felicia-simion",
121
+ label: "Felicia Simion",
122
+ category: "editorial",
123
+ description: "Surreal pastoral fine art",
124
+ promptHint:
125
+ "in the style of Felicia Simion, surreal pastoral fine-art photography with quiet symbolism and a muted earthy palette",
126
+ },
127
+ {
128
+ id: "oleg-oprisco",
129
+ label: "Oleg Oprisco",
130
+ category: "editorial",
131
+ description: "Cinematic film-grain storytelling",
132
+ promptHint:
133
+ "in the style of Oleg Oprisco, cinematic film-grain storytelling with painterly costuming and analogue color casts",
134
+ },
135
+ {
136
+ id: "bella-kotak",
137
+ label: "Bella Kotak",
138
+ category: "editorial",
139
+ description: "Magical, fantasy-folkloric portraiture",
140
+ promptHint:
141
+ "in the style of Bella Kotak, magical fantasy-folkloric portraiture with golden light, florals and rich painterly grading",
142
+ },
143
+ {
144
+ id: "yigal-ozeri",
145
+ label: "Yigal Ozeri",
146
+ category: "editorial",
147
+ description: "Hyperreal painted portrait",
148
+ promptHint:
149
+ "in the style of Yigal Ozeri, hyperreal painted portraiture with luminous skin and dappled forest light",
150
+ },
151
+ {
152
+ id: "jimmy-marble",
153
+ label: "Jimmy Marble",
154
+ category: "editorial",
155
+ description: "Pastel, candy-bright editorial",
156
+ promptHint:
157
+ "in the style of Jimmy Marble, pastel candy-bright editorial photography with playful color blocking and clean studio shapes",
158
+ },
159
+ {
160
+ id: "rinko-kawauchi",
161
+ label: "Rinko Kawauchi",
162
+ category: "editorial",
163
+ description: "Quiet, light-suffused everyday",
164
+ promptHint:
165
+ "in the style of Rinko Kawauchi, quiet light-suffused everyday photography with a dreamy pastel haze and gentle overexposure",
166
+ },
167
+ {
168
+ id: "ellen-von-unwerth",
169
+ label: "Ellen von Unwerth",
170
+ category: "editorial",
171
+ description: "Playful retro pin-up energy",
172
+ promptHint:
173
+ "in the style of Ellen von Unwerth, playful retro pin-up energy with monochrome flash and mischievous body language",
174
+ },
175
+ {
176
+ id: "mapplethorpe",
177
+ label: "Robert Mapplethorpe",
178
+ category: "editorial",
179
+ description: "Formalist B&W studio nudes and flowers",
180
+ promptHint:
181
+ "in the style of Robert Mapplethorpe, strict formalist black-and-white studio portraiture with dramatic chiaroscuro lighting, sculpted classical nudes and tightly controlled lily and orchid still lifes",
182
+ },
183
+ {
184
+ id: "sherman",
185
+ label: "Cindy Sherman",
186
+ category: "editorial",
187
+ description: "Conceptual self-portrait character study",
188
+ promptHint:
189
+ "in the style of Cindy Sherman, staged conceptual self-portraiture with costumed character studies, film-still references and a dispassionate often unsettling gaze",
190
+ },
191
+ {
192
+ id: "crewdson",
193
+ label: "Gregory Crewdson",
194
+ category: "editorial",
195
+ description: "Cinematic suburban dread tableau",
196
+ promptHint:
197
+ "in the style of Gregory Crewdson, large-format staged tableau of suburban dread with hyper-cinematic twilight blue-hour lighting and every detail meticulously composed",
198
+ },
199
+ {
200
+ id: "lachapelle",
201
+ label: "David LaChapelle",
202
+ category: "editorial",
203
+ description: "Surreal hyper-saturated celebrity camp",
204
+ promptHint:
205
+ "in the style of David LaChapelle, hyper-saturated surrealist celebrity tableau with religious iconography, candy-gloss color and theatrical excess",
206
+ },
207
+ {
208
+ id: "klein",
209
+ label: "Steven Klein",
210
+ category: "editorial",
211
+ description: "Hard-edged glamour and controlled aggression",
212
+ promptHint:
213
+ "in the style of Steven Klein, hard-edged high-fashion glamour with leather and latex wardrobe, dramatic shadowed lighting and a charge of controlled aggression",
214
+ },
215
+ {
216
+ id: "lindbergh",
217
+ label: "Peter Lindbergh",
218
+ category: "editorial",
219
+ description: "Minimalist B&W natural-light fashion",
220
+ promptHint:
221
+ "in the style of Peter Lindbergh, minimalist black-and-white fashion in natural light with bare makeup, supermodel-era documentary feel, windswept beach settings and untouched skin",
222
+ },
223
+ {
224
+ id: "tillmans",
225
+ label: "Wolfgang Tillmans",
226
+ category: "editorial",
227
+ description: "Candid queer intimacy and casual flash",
228
+ promptHint:
229
+ "in the style of Wolfgang Tillmans, democratic mix of intimate snapshot portraiture and abstract still life with casual on-camera flash and party, club and nightlife candor",
230
+ },
231
+ {
232
+ id: "teller",
233
+ label: "Juergen Teller",
234
+ category: "editorial",
235
+ description: "Anti-glamour direct-flash snapshot",
236
+ promptHint:
237
+ "in the style of Juergen Teller, direct on-camera flash snapshot fashion with deadpan unfiltered models, anti-airbrush rawness and an awkward off-kilter staging",
238
+ },
239
+ {
240
+ id: "penn",
241
+ label: "Irving Penn",
242
+ category: "editorial",
243
+ description: "Austere mid-century studio portrait",
244
+ promptHint:
245
+ "in the style of Irving Penn, austere mid-century studio portraiture against a commanding gray seamless backdrop with controlled grace, sculptural fashion staging and refined still-life precision",
246
+ },
247
+ {
248
+ id: "mcginley",
249
+ label: "Ryan McGinley",
250
+ category: "editorial",
251
+ description: "Naturalistic youth + nudity in landscape, sun-flared candid",
252
+ promptHint:
253
+ "shot in the language of Ryan McGinley, naturalistic youth and nudity roaming through open landscape, sun-flared candid 35mm with euphoric movement and unposed freedom",
254
+ },
255
+ {
256
+ id: "mitchell",
257
+ label: "Tyler Mitchell",
258
+ category: "editorial",
259
+ description: "Contemporary Black portraiture, soft natural light, fashion-meets-documentary",
260
+ promptHint:
261
+ "shot in the language of Tyler Mitchell, contemporary Black portraiture in soft natural light with a fashion-meets-documentary tenderness, pastel wardrobe and sun-warmed skin",
262
+ },
263
+ {
264
+ id: "collins",
265
+ label: "Petra Collins",
266
+ category: "editorial",
267
+ description: "Pink-saturated dreamy female-gaze fashion, hazy 35mm",
268
+ promptHint:
269
+ "shot in the language of Petra Collins, dreamy pink-saturated female-gaze fashion, hazy 35mm grain, soft window light",
270
+ },
271
+ {
272
+ id: "weston",
273
+ label: "Edward Weston",
274
+ category: "editorial",
275
+ description: "Modernist B&W still life, sculptural nudes, sharp formalism",
276
+ promptHint:
277
+ "in the style of Edward Weston, modernist black-and-white still life and sculptural nudes with sharp formalism, large-format clarity and sensuous tonal gradation",
278
+ },
279
+ {
280
+ id: "beaton",
281
+ label: "Cecil Beaton",
282
+ category: "editorial",
283
+ description: "Classical Hollywood-era portraiture, theatrical staging, opulent backdrops",
284
+ promptHint:
285
+ "in the style of Cecil Beaton, classical Hollywood-era portraiture with theatrical staging, opulent painted backdrops and elegant silver-screen glamour",
286
+ },
287
+
288
+ // -------------------- Documentary / Street --------------------
289
+ {
290
+ id: "henri-cartier-bresson",
291
+ label: "Henri Cartier-Bresson",
292
+ category: "documentary",
293
+ description: "Decisive-moment street photography",
294
+ promptHint:
295
+ "in the style of Henri Cartier-Bresson, decisive-moment black-and-white street photography with geometric framing and natural light",
296
+ },
297
+ {
298
+ id: "vivian-maier",
299
+ label: "Vivian Maier",
300
+ category: "documentary",
301
+ description: "Mid-century American street",
302
+ promptHint:
303
+ "in the style of Vivian Maier, mid-century American street photography with square format, observed candor and silver-rich blacks",
304
+ },
305
+ {
306
+ id: "saul-leiter",
307
+ label: "Saul Leiter",
308
+ category: "documentary",
309
+ description: "Painterly color street through glass",
310
+ promptHint:
311
+ "in the style of Saul Leiter, painterly color street photography seen through fogged glass and rain, with abstract layered framing",
312
+ },
313
+ {
314
+ id: "daido-moriyama",
315
+ label: "Daido Moriyama",
316
+ category: "documentary",
317
+ description: "Grainy, high-contrast Tokyo street",
318
+ promptHint:
319
+ "in the style of Daido Moriyama, grainy high-contrast Tokyo street photography with blown highlights and a restless handheld feel",
320
+ },
321
+ {
322
+ id: "robert-capa",
323
+ label: "Robert Capa",
324
+ category: "documentary",
325
+ description: "Visceral combat photojournalism",
326
+ promptHint:
327
+ "in the style of Robert Capa, visceral combat photojournalism with motion blur, gritty grain and an immediate handheld viewpoint",
328
+ },
329
+ {
330
+ id: "sebastiao-salgado",
331
+ label: "Sebastiao Salgado",
332
+ category: "documentary",
333
+ description: "Epic monochrome social documentary",
334
+ promptHint:
335
+ "in the style of Sebastiao Salgado, epic monochrome social documentary with sweeping landscape scale and chiaroscuro tonality",
336
+ },
337
+ {
338
+ id: "diane-arbus",
339
+ label: "Diane Arbus",
340
+ category: "documentary",
341
+ description: "Stark, confrontational portrait",
342
+ promptHint:
343
+ "in the style of Diane Arbus, stark confrontational portraiture with direct gaze, square format and unflinching daylight",
344
+ },
345
+
346
+ // -------------------- Cinematographers --------------------
347
+ {
348
+ id: "roger-deakins",
349
+ label: "Roger Deakins",
350
+ category: "cinematographer",
351
+ description: "Painterly cinematic naturalism",
352
+ promptHint:
353
+ "in the cinematic style of Roger Deakins, painterly natural light with carved silhouettes, deep negative space and restrained color",
354
+ },
355
+ {
356
+ id: "emmanuel-lubezki",
357
+ label: "Emmanuel Lubezki",
358
+ category: "cinematographer",
359
+ description: "Floating natural-light cinematography",
360
+ promptHint:
361
+ "in the cinematic style of Emmanuel Lubezki, floating handheld natural-light cinematography with golden-hour glow and wide-lens immersion",
362
+ },
363
+ {
364
+ id: "greig-fraser",
365
+ label: "Greig Fraser",
366
+ category: "cinematographer",
367
+ description: "Rich tactile genre cinematography",
368
+ promptHint:
369
+ "in the cinematic style of Greig Fraser, rich tactile genre cinematography with anamorphic flares, deep blacks and atmospheric haze",
370
+ },
371
+ {
372
+ id: "christopher-doyle",
373
+ label: "Christopher Doyle",
374
+ category: "cinematographer",
375
+ description: "Saturated handheld neon mood",
376
+ promptHint:
377
+ "in the cinematic style of Christopher Doyle, saturated handheld neon mood with smeared light trails and dreamy slow-shutter blur",
378
+ },
379
+
380
+ // -------------------- Concept / Digital Painters --------------------
381
+ {
382
+ id: "greg-rutkowski",
383
+ label: "Greg Rutkowski",
384
+ category: "concept",
385
+ description: "Epic painterly fantasy concept",
386
+ promptHint:
387
+ "in the style of Greg Rutkowski, epic painterly fantasy concept art with sweeping composition, dramatic god-rays and oil-painting brushwork",
388
+ },
389
+ {
390
+ id: "magali-villeneuve",
391
+ label: "Magali Villeneuve",
392
+ category: "concept",
393
+ description: "Heroic fantasy character art",
394
+ promptHint:
395
+ "in the style of Magali Villeneuve, heroic fantasy character art with detailed armor, painterly skin and warm golden lighting",
396
+ },
397
+ {
398
+ id: "charlie-bowater",
399
+ label: "Charlie Bowater",
400
+ category: "concept",
401
+ description: "Atmospheric digital portraiture",
402
+ promptHint:
403
+ "in the style of Charlie Bowater, atmospheric digital portraiture with painterly textures, moody color and intimate close framing",
404
+ },
405
+ {
406
+ id: "sam-spratt",
407
+ label: "Sam Spratt",
408
+ category: "concept",
409
+ description: "Allegorical hyperreal portrait",
410
+ promptHint:
411
+ "in the style of Sam Spratt, allegorical hyperreal portraiture with sculpted lighting, symbolic detail and old-master tonal depth",
412
+ },
413
+ {
414
+ id: "ruan-jia",
415
+ label: "Ruan Jia",
416
+ category: "concept",
417
+ description: "Lush painterly fantasy portrait",
418
+ promptHint:
419
+ "in the style of Ruan Jia, lush painterly fantasy portraiture with rich fabrics, gilded accents and warm directional light",
420
+ },
421
+ {
422
+ id: "ilya-kuvshinov",
423
+ label: "Ilya Kuvshinov",
424
+ category: "concept",
425
+ description: "Anime-inflected stylized portrait",
426
+ promptHint:
427
+ "in the style of Ilya Kuvshinov, anime-inflected stylized portraiture with soft cell-shading, oversized eyes and pastel rim light",
428
+ },
429
+ {
430
+ id: "wlop",
431
+ label: "WLOP",
432
+ category: "concept",
433
+ description: "Ethereal painterly fantasy",
434
+ promptHint:
435
+ "in the style of WLOP, ethereal painterly fantasy portraiture with flowing hair, glowing rim light and a cool monochromatic palette",
436
+ },
437
+ {
438
+ id: "artgerm",
439
+ label: "Artgerm",
440
+ category: "concept",
441
+ description: "Polished comic-book-inspired pinup",
442
+ promptHint:
443
+ "in the style of Artgerm, polished comic-book-inspired pinup illustration with smooth gradients and crisp graphic edge highlights",
444
+ },
445
+
446
+ // -------------------- Illustrators / Animators --------------------
447
+ {
448
+ id: "makoto-shinkai",
449
+ label: "Makoto Shinkai",
450
+ category: "illustrator",
451
+ description: "Cinematic anime sky and light",
452
+ promptHint:
453
+ "in the style of Makoto Shinkai, cinematic anime sky and light with luminous clouds, lens-flared sun and saturated dusk gradients",
454
+ },
455
+ {
456
+ id: "studio-ghibli",
457
+ label: "Studio Ghibli",
458
+ category: "illustrator",
459
+ description: "Hand-painted Ghibli warmth",
460
+ promptHint:
461
+ "in the style of Studio Ghibli, hand-painted animation warmth with soft pastel skies, lush vegetation and gentle character expressions",
462
+ },
463
+ {
464
+ id: "alphonse-mucha",
465
+ label: "Alphonse Mucha",
466
+ category: "illustrator",
467
+ description: "Art-nouveau decorative panel",
468
+ promptHint:
469
+ "in the style of Alphonse Mucha, art-nouveau decorative panel with ornamental floral borders, flowing hair and warm gilded tones",
470
+ },
471
+ {
472
+ id: "carne-griffiths",
473
+ label: "Carne Griffiths",
474
+ category: "illustrator",
475
+ description: "Ink-bleed botanical portrait",
476
+ promptHint:
477
+ "in the style of Carne Griffiths, ink-bleed botanical portraiture with calligraphic linework, splashed tea washes and tangled florals",
478
+ },
479
+ {
480
+ id: "conrad-roset",
481
+ label: "Conrad Roset",
482
+ category: "illustrator",
483
+ description: "Gentle watercolor figure",
484
+ promptHint:
485
+ "in the style of Conrad Roset, gentle watercolor figure illustration with soft graphite line, blooming pigment and pale skin tones",
486
+ },
487
+ {
488
+ id: "akihito-yoshida",
489
+ label: "Akihito Yoshida",
490
+ category: "illustrator",
491
+ description: "Quiet ink-and-grain monochrome",
492
+ promptHint:
493
+ "in the style of Akihito Yoshida, quiet ink-and-grain monochrome portraiture with sketchy line and contemplative negative space",
494
+ },
495
+ {
496
+ id: "karol-bak",
497
+ label: "Karol Bak",
498
+ category: "illustrator",
499
+ description: "Symbolist painted muse",
500
+ promptHint:
501
+ "in the style of Karol Bak, symbolist painted muse with gilded-leaf accents, art-nouveau ornament and warm earthen pigment",
502
+ },
503
+ {
504
+ id: "ismail-inceoglu",
505
+ label: "Ismail Inceoglu",
506
+ category: "illustrator",
507
+ description: "Mythic painterly landscape",
508
+ promptHint:
509
+ "in the style of Ismail Inceoglu, mythic painterly landscape with monumental scale, layered atmospheric haze and storybook lighting",
510
+ },
511
+ {
512
+ id: "stefan-gesell",
513
+ label: "Stefan Gesell",
514
+ category: "illustrator",
515
+ description: "Dark surreal portraiture",
516
+ promptHint:
517
+ "in the style of Stefan Gesell, dark surreal portraiture with high-contrast monochrome, masked figures and uneasy theatrical lighting",
518
+ },
519
+ {
520
+ id: "andrew-atroshenko",
521
+ label: "Andrew Atroshenko",
522
+ category: "illustrator",
523
+ description: "Romantic impressionist figure",
524
+ promptHint:
525
+ "in the style of Andrew Atroshenko, romantic impressionist figure painting with loose visible brushwork and shimmering candlelight",
526
+ },
527
+ {
528
+ id: "peter-gric",
529
+ label: "Peter Gric",
530
+ category: "illustrator",
531
+ description: "Architectural surrealist landscape",
532
+ promptHint:
533
+ "in the style of Peter Gric, architectural surrealist landscape with crystalline geometric structures and a cool muted palette",
534
+ },
535
+ {
536
+ id: "ingrid-baars",
537
+ label: "Ingrid Baars",
538
+ category: "illustrator",
539
+ description: "Sculptural fashion-art collage",
540
+ promptHint:
541
+ "in the style of Ingrid Baars, sculptural fashion-art collage with elongated forms, smooth painted skin and ornate textile drapery",
542
+ },
543
+ {
544
+ id: "guido-van-helten",
545
+ label: "Guido van Helten",
546
+ category: "illustrator",
547
+ description: "Monumental muralist portrait",
548
+ promptHint:
549
+ "in the style of Guido van Helten, monumental muralist portraiture with weathered concrete texture and quiet grayscale tonality",
550
+ },
551
+ ] as const
552
+
553
+ const photographerById = new Map<string, Photographer>(
554
+ PHOTOGRAPHERS.map((p) => [p.id, p]),
555
+ )
556
+
557
+ export function getPhotographer(id: string | undefined | null): Photographer | undefined {
558
+ if (!id) return undefined
559
+ return photographerById.get(id)
560
+ }
561
+
562
+ export function getPhotographerLabel(id: string | undefined | null, fallback?: string): string {
563
+ const p = getPhotographer(id)
564
+ if (p) return p.label
565
+ if (fallback !== undefined) return fallback
566
+ return (id ?? "").replace(/-/g, " ").replace(/\b\w/g, (c) => c.toUpperCase())
567
+ }
568
+
569
+ export function getPhotographerPromptHint(id: string | undefined | null): string {
570
+ return getPhotographer(id)?.promptHint ?? ""
571
+ }
572
+
573
+ /**
574
+ * Multi-pick variant: 1-2 photographer ids → blended hint. Single → entry's
575
+ * own promptHint. Two → "shot in the blended language of {A} and {B}" — the
576
+ * model interprets this as referencing both creators' visual signatures.
577
+ */
578
+ export function buildPhotographerHints(value: unknown): string {
579
+ const ids: string[] = []
580
+ if (typeof value === "string" && value) ids.push(value)
581
+ else if (Array.isArray(value)) {
582
+ for (const v of value) {
583
+ if (typeof v === "string" && v && !ids.includes(v)) ids.push(v)
584
+ }
585
+ }
586
+ if (ids.length === 0) return ""
587
+ if (ids.length === 1) return getPhotographerPromptHint(ids[0])
588
+ const labels = ids
589
+ .slice(0, 2)
590
+ .map((id) => getPhotographer(id)?.label ?? "")
591
+ .filter((s): s is string => Boolean(s))
592
+ if (labels.length < 2) return getPhotographerPromptHint(ids[0])
593
+ return `shot in the blended visual language of ${labels[0]} and ${labels[1]}`
594
+ }
595
+
596
+ export const PHOTOGRAPHER_IDS: ReadonlyArray<string> = PHOTOGRAPHERS.map((p) => p.id)
597
+
598
+ export const PHOTOGRAPHER_CATEGORY_LABELS: Readonly<Record<PhotographerCategory, string>> = {
599
+ editorial: "Editorial / Fashion",
600
+ documentary: "Documentary / Street",
601
+ cinematographer: "Cinematographer",
602
+ concept: "Concept / Digital",
603
+ illustrator: "Illustrator / Animator",
604
+ }
605
+
606
+ export const PHOTOGRAPHER_CATEGORY_ORDER: ReadonlyArray<PhotographerCategory> = [
607
+ "editorial",
608
+ "documentary",
609
+ "cinematographer",
610
+ "concept",
611
+ "illustrator",
612
+ ]