@nodaro/prompts 1.7.3 → 1.8.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 (74) hide show
  1. package/dist/index.cjs +5443 -4295
  2. package/dist/index.cjs.map +1 -1
  3. package/dist/index.d.cts +1202 -61
  4. package/dist/index.d.ts +1202 -61
  5. package/dist/index.js +5357 -4297
  6. package/dist/index.js.map +1 -1
  7. package/package.json +2 -2
  8. package/src/__tests__/b7-person-pack-e2e.test.ts +37 -0
  9. package/src/__tests__/catalog-funnel-ratchet.test.ts +97 -0
  10. package/src/__tests__/catalog-packs.test.ts +130 -0
  11. package/src/__tests__/catalog-sidecar-coverage.test.ts +27 -0
  12. package/src/__tests__/catalog-terms.test.ts +162 -0
  13. package/src/__tests__/character-default-role.test.ts +3 -2
  14. package/src/__tests__/content-free-contract.test.ts +45 -0
  15. package/src/__tests__/dod-replace-pack-acceptance.test.ts +41 -0
  16. package/src/__tests__/fixtures/parameter-hint-golden.json +2959 -0
  17. package/src/__tests__/fixtures/person-sector-pack.ts +27 -0
  18. package/src/__tests__/i18n-entry-completeness.test.ts +5 -2
  19. package/src/__tests__/parameter-hint-mode.test.ts +385 -0
  20. package/src/__tests__/parameter-prompt-hint-pack-fallback.test.ts +25 -0
  21. package/src/__tests__/person-packs.test.ts +166 -0
  22. package/src/__tests__/project-all-catalogs.test.ts +26 -0
  23. package/src/__tests__/prompt-builder.test.ts +53 -0
  24. package/src/__tests__/provider-prompt-doctrine.test.ts +18 -0
  25. package/src/__tests__/registered-catalogs-funnel.test.ts +30 -0
  26. package/src/__tests__/registered-catalogs-guard.test.ts +11 -0
  27. package/src/__tests__/term.test.ts +104 -0
  28. package/src/__tests__/transitions.test.ts +8 -5
  29. package/src/__tests__/upstream-immutability.test.ts +23 -0
  30. package/src/action-fx.ts +67 -17
  31. package/src/aesthetic.ts +54 -6
  32. package/src/atmosphere.ts +64 -23
  33. package/src/backdrop.ts +44 -30
  34. package/src/camera-format.ts +33 -11
  35. package/src/camera-motions.ts +89 -0
  36. package/src/catalog-packs.ts +125 -0
  37. package/src/catalog-sidecar-coverage.ts +36 -0
  38. package/src/character-fx.ts +112 -39
  39. package/src/color-look.ts +44 -27
  40. package/src/composition-effects.ts +21 -7
  41. package/src/era.ts +24 -0
  42. package/src/exposure-settings.ts +76 -18
  43. package/src/framing.ts +102 -10
  44. package/src/held-prop.ts +125 -63
  45. package/src/identity-lock.ts +12 -5
  46. package/src/image-reference-doctrine.ts +55 -0
  47. package/src/index.ts +5 -0
  48. package/src/instrumentation.ts +148 -57
  49. package/src/lens.ts +31 -15
  50. package/src/lighting.ts +120 -59
  51. package/src/loop-subject.ts +27 -1
  52. package/src/materials.ts +123 -69
  53. package/src/mood.ts +123 -51
  54. package/src/music-genre.ts +171 -67
  55. package/src/music-mood.ts +85 -17
  56. package/src/parameter-prompt-hint.ts +168 -56
  57. package/src/person-packs.ts +182 -0
  58. package/src/person.ts +506 -408
  59. package/src/photo-genre.ts +37 -22
  60. package/src/photographer.ts +138 -1
  61. package/src/picker-catalogs.ts +86 -40
  62. package/src/pose.ts +105 -40
  63. package/src/post-process-effects.ts +51 -8
  64. package/src/prompt-builder.ts +16 -1
  65. package/src/provider-prompt-doctrine.ts +12 -5
  66. package/src/render-quality.ts +25 -7
  67. package/src/setting.ts +30 -14
  68. package/src/style.ts +33 -15
  69. package/src/styling.ts +155 -94
  70. package/src/temporal.ts +80 -18
  71. package/src/term.ts +155 -0
  72. package/src/transitions.ts +73 -26
  73. package/src/voice-character.ts +190 -90
  74. package/src/voice-delivery.ts +83 -12
package/src/person.ts CHANGED
@@ -30,6 +30,14 @@
30
30
  * backend orchestrator.
31
31
  */
32
32
 
33
+ import {
34
+ getRegisteredPeople,
35
+ getRegisteredPersonDimensionOrder,
36
+ getRegisteredPersonFieldByDimension,
37
+ personPacksVersion,
38
+ } from "./person-packs.js"
39
+ import { resolveTerm, type PickerHintMode } from "./term.js"
40
+
33
41
  export type PersonDimension =
34
42
  | "type"
35
43
  | "age"
@@ -80,6 +88,17 @@ export interface Person {
80
88
  * instead of the redundant "East Asian (any)". Node cards + tooltips
81
89
  * keep the full `label` / `description`. */
82
90
  readonly shortLabel?: string
91
+ /**
92
+ * Optional authored COMPACT term — the short professional phrase a consumer
93
+ * injects instead of the full `promptHint` ("brown hair", "aquiline nose",
94
+ * "of nordic scandinavian descent"). Authored only where the lowercased
95
+ * label is not already what a professional writes: Person fragments are
96
+ * comma-joined into one compound description, so a bare dimension modifier
97
+ * ("Brown", "Strong", "Full") has to carry its category noun to mean
98
+ * anything. See `term.ts`; resolve via `resolveTerm` / `getPersonTerm`,
99
+ * never by reading this field directly.
100
+ */
101
+ readonly term?: string
83
102
  }
84
103
 
85
104
  export const PEOPLE: ReadonlyArray<Person> = [
@@ -103,7 +122,7 @@ export const PEOPLE: ReadonlyArray<Person> = [
103
122
  // "Not defined" is the open / unspecified slot — distinct from non-binary.
104
123
  // Use this when gender shouldn't be pinned in the prompt; the model gets
105
124
  // "a person" and ethnicity / build / hair drive the rest.
106
- { id: "not-defined", label: "Not Defined", group: "Realistic", dimension: "type", description: "Gender not specified — left open", promptHint: "a person" },
125
+ { id: "not-defined", label: "Not Defined", group: "Realistic", dimension: "type", description: "Gender not specified — left open", promptHint: "a person", term: "person" },
107
126
 
108
127
  // ----- Realistic — Aesthetic / archetype -----
109
128
  { id: "beautiful-woman", label: "Beautiful Woman", group: "Realistic — Style", dimension: "type", description: "Classically beautiful woman", promptHint: "a beautiful woman" },
@@ -130,10 +149,10 @@ export const PEOPLE: ReadonlyArray<Person> = [
130
149
  { id: "twink", label: "Twink", group: "Realistic — Style", dimension: "type", description: "Slim, smooth, soft gay-male type", promptHint: "a twink — slim, smooth, soft masculine presence with a delicate, gender-fluid vibe" },
131
150
  { id: "soft-butch", label: "Soft Butch", group: "Realistic — Style", dimension: "type", description: "Gentle masculine-of-center woman", promptHint: "a soft-butch woman — gentle masculine-of-center styling and energy" },
132
151
  { id: "tomboy", label: "Tomboy", group: "Realistic — Style", dimension: "type", description: "Boyish styling and energy on a feminine body", promptHint: "a tomboy — boyish styling and energy on a feminine body" },
133
- { id: "thick", label: "Thick", group: "Realistic — Style", dimension: "type", description: "Voluptuous body-positive figure with curves", promptHint: "a thick, voluptuous body-positive figure with full curves" },
134
- { id: "androgynous", label: "Androgynous", group: "Realistic — Style", dimension: "type", description: "Deliberately blended masculine + feminine cues", promptHint: "an androgynous figure with deliberately blended masculine and feminine cues" },
152
+ { id: "thick", label: "Thick", group: "Realistic — Style", dimension: "type", description: "Voluptuous body-positive figure with curves", promptHint: "a thick, voluptuous body-positive figure with full curves", term: "thick voluptuous figure" },
153
+ { id: "androgynous", label: "Androgynous", group: "Realistic — Style", dimension: "type", description: "Deliberately blended masculine + feminine cues", promptHint: "an androgynous figure with deliberately blended masculine and feminine cues", term: "androgynous figure" },
135
154
  { id: "goth", label: "Goth", group: "Realistic — Style", dimension: "type", description: "Goth subculture aesthetic — dark, romantic, dramatic", promptHint: "a goth figure with a dark romantic dramatic subculture aesthetic" },
136
- { id: "bear", label: "Bear", group: "Realistic — Style", dimension: "type", description: "Big, bearded, hairy masculine type", promptHint: "a bear — a big, bearded, hairy man with a warm masculine presence" },
155
+ { id: "bear", label: "Bear", group: "Realistic — Style", dimension: "type", description: "Big, bearded, hairy masculine type", promptHint: "a bear — a big, bearded, hairy man with a warm masculine presence", term: "big bearded hairy man" },
137
156
 
138
157
  // ----- Primitive / Wild -----
139
158
  { id: "caveman", label: "Caveman", group: "Primitive / Wild", dimension: "type", description: "Stone Age primitive man", promptHint: "a caveman — Stone Age primitive in animal furs, with shaggy hair, a heavy brow and a sturdy frame" },
@@ -143,18 +162,18 @@ export const PEOPLE: ReadonlyArray<Person> = [
143
162
  { id: "neanderthal", label: "Neanderthal", group: "Primitive / Wild", dimension: "type", description: "Pre-modern human species", promptHint: "a neanderthal — heavy brow, broad nose, stocky pre-modern human build with weather-toughened skin" },
144
163
 
145
164
  // ----- Fantasy (humanoid) -----
146
- { id: "elf-man", label: "Elf (Male)", group: "Fantasy", dimension: "type", description: "Masculine pointed-ear humanoid", promptHint: "a male elf — slender masculine humanoid with delicately pointed ears, fine sharp features and an ethereal poise" },
147
- { id: "elf-woman", label: "Elf (Female)", group: "Fantasy", dimension: "type", description: "Feminine pointed-ear humanoid", promptHint: "a female elf — slender feminine humanoid with delicately pointed ears, fine elegant features and an ethereal poise" },
165
+ { id: "elf-man", label: "Elf (Male)", group: "Fantasy", dimension: "type", description: "Masculine pointed-ear humanoid", promptHint: "a male elf — slender masculine humanoid with delicately pointed ears, fine sharp features and an ethereal poise", term: "male elf" },
166
+ { id: "elf-woman", label: "Elf (Female)", group: "Fantasy", dimension: "type", description: "Feminine pointed-ear humanoid", promptHint: "a female elf — slender feminine humanoid with delicately pointed ears, fine elegant features and an ethereal poise", term: "female elf" },
148
167
  { id: "elf", label: "Elf", group: "Fantasy", dimension: "type", description: "Slender humanoid with pointed ears", promptHint: "an elf — slender humanoid with delicately pointed ears, fine features and an ethereal poise" },
149
168
  { id: "half-elf", label: "Half-Elf", group: "Fantasy", dimension: "type", description: "Mixed elven-human heritage", promptHint: "a half-elf with subtly pointed ears and a graceful blend of human and elven features" },
150
169
  { id: "dwarf", label: "Dwarf", group: "Fantasy", dimension: "type", description: "Stocky mountain-folk humanoid", promptHint: "a dwarf — stocky, broad-shouldered humanoid with a thick beard and a hardy mountain-folk look" },
151
170
  { id: "orc", label: "Orc", group: "Fantasy", dimension: "type", description: "Heavyset tusked humanoid", promptHint: "an orc — heavyset humanoid with greenish skin, jutting tusks and a brutish, battle-scarred build" },
152
171
  { id: "goblin", label: "Goblin", group: "Fantasy", dimension: "type", description: "Small, wiry humanoid", promptHint: "a goblin — small, wiry humanoid with sharp features, oversized ears and a mischievous look" },
153
172
  { id: "tiefling", label: "Tiefling", group: "Fantasy", dimension: "type", description: "Horned humanoid with infernal heritage", promptHint: "a tiefling — humanoid with curling horns, a tail and faintly otherworldly skin tones" },
154
- { id: "faun", label: "Faun / Satyr", group: "Fantasy", dimension: "type", description: "Goat-legged horned humanoid", promptHint: "a faun — humanoid with goat legs, small curling horns and a woodland presence" },
173
+ { id: "faun", label: "Faun / Satyr", group: "Fantasy", dimension: "type", description: "Goat-legged horned humanoid", promptHint: "a faun — humanoid with goat legs, small curling horns and a woodland presence", term: "faun" },
155
174
  { id: "centaur", label: "Centaur", group: "Fantasy", dimension: "type", description: "Human torso on a horse body", promptHint: "a centaur — human torso fused to the body of a horse" },
156
- { id: "vampire-man", label: "Vampire (Male)", group: "Fantasy", dimension: "type", description: "Masculine fanged immortal", promptHint: "a male vampire — pale, fanged immortal man in formal evening wear with gothic elegance and a quiet predatory poise" },
157
- { id: "vampire-woman", label: "Vampire (Female)", group: "Fantasy", dimension: "type", description: "Feminine fanged immortal", promptHint: "a female vampire — pale, fanged immortal woman in flowing gothic attire with seductive elegance and a quiet predatory poise" },
175
+ { id: "vampire-man", label: "Vampire (Male)", group: "Fantasy", dimension: "type", description: "Masculine fanged immortal", promptHint: "a male vampire — pale, fanged immortal man in formal evening wear with gothic elegance and a quiet predatory poise", term: "male vampire" },
176
+ { id: "vampire-woman", label: "Vampire (Female)", group: "Fantasy", dimension: "type", description: "Feminine fanged immortal", promptHint: "a female vampire — pale, fanged immortal woman in flowing gothic attire with seductive elegance and a quiet predatory poise", term: "female vampire" },
158
177
  { id: "vampire", label: "Vampire", group: "Fantasy", dimension: "type", description: "Pale, fanged immortal", promptHint: "a vampire — pale, fanged immortal with a pristine gothic elegance and a quiet predatory poise" },
159
178
  { id: "werewolf", label: "Werewolf", group: "Fantasy", dimension: "type", description: "Partially transformed lycanthrope", promptHint: "a werewolf — partially transformed humanoid with wolfish snout, fur, claws and a feral musculature" },
160
179
  { id: "mermaid", label: "Mermaid", group: "Fantasy", dimension: "type", description: "Female humanoid with a fish tail", promptHint: "a mermaid — humanoid woman from the waist up with a long iridescent fish tail below" },
@@ -164,11 +183,11 @@ export const PEOPLE: ReadonlyArray<Person> = [
164
183
  { id: "witch", label: "Witch", group: "Fantasy", dimension: "type", description: "Robed female spellcaster", promptHint: "a witch — robed female spellcaster with arcane sigils, a knowing gaze and a quietly powerful air" },
165
184
  { id: "sorcerer", label: "Sorcerer", group: "Fantasy", dimension: "type", description: "Magical man in flowing robes", promptHint: "a sorcerer — magical man in flowing robes wreathed in arcane glow" },
166
185
  { id: "sorceress", label: "Sorceress", group: "Fantasy", dimension: "type", description: "Magical woman in flowing robes", promptHint: "a sorceress — magical woman in flowing robes wreathed in arcane glow" },
167
- { id: "knight-man", label: "Knight (Male)", group: "Fantasy", dimension: "type", description: "Plate-armoured male warrior", promptHint: "a male knight in full plate armour with a heraldic surcoat, broad-shouldered build and a steady warrior's stance" },
168
- { id: "knight-woman", label: "Knight (Female)", group: "Fantasy", dimension: "type", description: "Plate-armoured female warrior", promptHint: "a female knight — warrior maiden in full plate armour with a heraldic surcoat, a poised stance and steady warrior's bearing" },
186
+ { id: "knight-man", label: "Knight (Male)", group: "Fantasy", dimension: "type", description: "Plate-armoured male warrior", promptHint: "a male knight in full plate armour with a heraldic surcoat, broad-shouldered build and a steady warrior's stance", term: "male knight" },
187
+ { id: "knight-woman", label: "Knight (Female)", group: "Fantasy", dimension: "type", description: "Plate-armoured female warrior", promptHint: "a female knight — warrior maiden in full plate armour with a heraldic surcoat, a poised stance and steady warrior's bearing", term: "female knight" },
169
188
  { id: "knight", label: "Knight", group: "Fantasy", dimension: "type", description: "Plate-armoured warrior", promptHint: "a knight in full plate armour with a heraldic surcoat and a steady warrior's stance" },
170
- { id: "barbarian-man", label: "Barbarian (Male)", group: "Fantasy", dimension: "type", description: "Brawny male fur-clad warrior", promptHint: "a male barbarian — brawny masculine warrior in furs and tribal markings, weathered and battle-ready" },
171
- { id: "barbarian-woman", label: "Barbarian (Female)", group: "Fantasy", dimension: "type", description: "Strong female fur-clad warrior", promptHint: "a female barbarian — strong woman warrior in furs and tribal markings, weathered and battle-ready" },
189
+ { id: "barbarian-man", label: "Barbarian (Male)", group: "Fantasy", dimension: "type", description: "Brawny male fur-clad warrior", promptHint: "a male barbarian — brawny masculine warrior in furs and tribal markings, weathered and battle-ready", term: "male barbarian" },
190
+ { id: "barbarian-woman", label: "Barbarian (Female)", group: "Fantasy", dimension: "type", description: "Strong female fur-clad warrior", promptHint: "a female barbarian — strong woman warrior in furs and tribal markings, weathered and battle-ready", term: "female barbarian" },
172
191
  { id: "barbarian", label: "Barbarian", group: "Fantasy", dimension: "type", description: "Brawny fur-clad warrior", promptHint: "a barbarian — brawny warrior in furs and tribal markings, weathered and battle-ready" },
173
192
  { id: "druid", label: "Druid", group: "Fantasy", dimension: "type", description: "Nature-bound robed mystic", promptHint: "a druid — robed nature-binder wreathed in foliage, antler accents and earthy ornaments" },
174
193
  { id: "ranger", label: "Ranger", group: "Fantasy", dimension: "type", description: "Cloaked archer / wilderness scout", promptHint: "a ranger — cloaked archer in muted leather and forest greens, alert wilderness bearing" },
@@ -179,8 +198,8 @@ export const PEOPLE: ReadonlyArray<Person> = [
179
198
  // ----- Warriors / Martial -----
180
199
  { id: "ninja", label: "Ninja", group: "Warriors / Martial", dimension: "type", description: "Stealth-clad shinobi assassin", promptHint: "a ninja — masked shinobi in a black hooded shozoku with face wrap, lean athletic build, twin sword on the back and a stealthy combat-ready stance" },
181
200
  { id: "kunoichi", label: "Kunoichi", group: "Warriors / Martial", dimension: "type", description: "Female ninja", promptHint: "a kunoichi — female ninja in a fitted black hooded shozoku with face wrap, lean athletic build and a stealthy combat-ready stance" },
182
- { id: "samurai-man", label: "Samurai (Male)", group: "Warriors / Martial", dimension: "type", description: "Male Japanese armoured warrior", promptHint: "a male samurai — Japanese warrior in lacquered lamellar yoroi armour with shoulder guards, kabuto helmet, top-knot under the helmet, katana at the hip and a disciplined battle-ready stance" },
183
- { id: "samurai-woman", label: "Samurai (Female)", group: "Warriors / Martial", dimension: "type", description: "Female samurai (onna-musha)", promptHint: "a female samurai — onna-musha warrior in lacquered lamellar yoroi armour with shoulder guards, hair tied up, naginata or katana in hand and a disciplined battle-ready stance" },
201
+ { id: "samurai-man", label: "Samurai (Male)", group: "Warriors / Martial", dimension: "type", description: "Male Japanese armoured warrior", promptHint: "a male samurai — Japanese warrior in lacquered lamellar yoroi armour with shoulder guards, kabuto helmet, top-knot under the helmet, katana at the hip and a disciplined battle-ready stance", term: "male samurai" },
202
+ { id: "samurai-woman", label: "Samurai (Female)", group: "Warriors / Martial", dimension: "type", description: "Female samurai (onna-musha)", promptHint: "a female samurai — onna-musha warrior in lacquered lamellar yoroi armour with shoulder guards, hair tied up, naginata or katana in hand and a disciplined battle-ready stance", term: "female samurai, onna-musha" },
184
203
  { id: "samurai", label: "Samurai", group: "Warriors / Martial", dimension: "type", description: "Japanese armoured warrior", promptHint: "a samurai — Japanese warrior in lacquered lamellar yoroi armour with shoulder guards, kabuto helmet, katana at the hip and a disciplined battle-ready stance" },
185
204
  { id: "karate-fighter", label: "Karate Fighter", group: "Warriors / Martial", dimension: "type", description: "Karate practitioner in gi", promptHint: "a karate practitioner in a crisp white karate gi tied with a black belt, barefoot, in a focused fighting stance" },
186
205
  { id: "kung-fu-master", label: "Kung Fu Master", group: "Warriors / Martial", dimension: "type", description: "Chinese martial-arts adept", promptHint: "a kung fu master in a flowing silk changshan tunic with frog-button closures, slippers and a poised martial stance, decades-of-training discipline" },
@@ -204,11 +223,11 @@ export const PEOPLE: ReadonlyArray<Person> = [
204
223
  { id: "goddess", label: "Goddess", group: "Mythic / Divine", dimension: "type", description: "Female deity", promptHint: "a goddess — female deity with a radiant divine aura, idealised features and an aura of immense power" },
205
224
 
206
225
  // ----- Sci-Fi -----
207
- { id: "android-man", label: "Android (Male)", group: "Sci-Fi", dimension: "type", description: "Masculine humanoid robot", promptHint: "an android — humanoid robot with a masculine sculpt, smooth synthetic skin and visible mechanical seams" },
208
- { id: "android-woman", label: "Android (Female)", group: "Sci-Fi", dimension: "type", description: "Feminine humanoid robot", promptHint: "an android — humanoid robot with a feminine sculpt, smooth synthetic skin and visible mechanical seams" },
226
+ { id: "android-man", label: "Android (Male)", group: "Sci-Fi", dimension: "type", description: "Masculine humanoid robot", promptHint: "an android — humanoid robot with a masculine sculpt, smooth synthetic skin and visible mechanical seams", term: "male android" },
227
+ { id: "android-woman", label: "Android (Female)", group: "Sci-Fi", dimension: "type", description: "Feminine humanoid robot", promptHint: "an android — humanoid robot with a feminine sculpt, smooth synthetic skin and visible mechanical seams", term: "female android" },
209
228
  { id: "android-neutral", label: "Android", group: "Sci-Fi", dimension: "type", description: "Humanoid robot, gender unspecified", promptHint: "an androgynous android — humanoid robot with a neutral sculpt and exposed precision servos" },
210
- { id: "cyborg-man", label: "Cyborg (Male)", group: "Sci-Fi", dimension: "type", description: "Masculine human-machine hybrid", promptHint: "a male cyborg — masculine human body fused with mechanical augmentations, cybernetic limbs and partial exposed circuitry" },
211
- { id: "cyborg-woman", label: "Cyborg (Female)", group: "Sci-Fi", dimension: "type", description: "Feminine human-machine hybrid", promptHint: "a female cyborg — feminine human body fused with mechanical augmentations, cybernetic limbs and partial exposed circuitry" },
229
+ { id: "cyborg-man", label: "Cyborg (Male)", group: "Sci-Fi", dimension: "type", description: "Masculine human-machine hybrid", promptHint: "a male cyborg — masculine human body fused with mechanical augmentations, cybernetic limbs and partial exposed circuitry", term: "male cyborg" },
230
+ { id: "cyborg-woman", label: "Cyborg (Female)", group: "Sci-Fi", dimension: "type", description: "Feminine human-machine hybrid", promptHint: "a female cyborg — feminine human body fused with mechanical augmentations, cybernetic limbs and partial exposed circuitry", term: "female cyborg" },
212
231
  { id: "cyborg", label: "Cyborg", group: "Sci-Fi", dimension: "type", description: "Human-machine hybrid", promptHint: "a cyborg — human body fused with mechanical augmentations, cybernetic limbs and partial exposed circuitry" },
213
232
  { id: "robot", label: "Robot", group: "Sci-Fi", dimension: "type", description: "Fully mechanical humanoid", promptHint: "a robot — fully mechanical humanoid with metal plating, articulated joints and glowing optical sensors" },
214
233
  { id: "alien", label: "Alien", group: "Sci-Fi", dimension: "type", description: "Non-human humanoid", promptHint: "an alien — non-human humanoid with otherworldly facial features, unusual skin tone and unfamiliar proportions" },
@@ -221,8 +240,8 @@ export const PEOPLE: ReadonlyArray<Person> = [
221
240
  { id: "superheroine", label: "Superheroine", group: "Heroes & Villains", dimension: "type", description: "Masked caped female hero", promptHint: "a superheroine — masked, caped, in a fitted spandex suit with a chest emblem and a heroic ready stance" },
222
241
  { id: "masked-vigilante", label: "Masked Vigilante", group: "Heroes & Villains", dimension: "type", description: "Dark-suited masked hero", promptHint: "a masked vigilante — dark tactical bodysuit with a half-mask covering the eyes, urban gritty aesthetic" },
223
242
  { id: "supervillain", label: "Supervillain", group: "Heroes & Villains", dimension: "type", description: "Theatrical evil archetype", promptHint: "a supervillain — theatrical menacing costume with a sinister emblem, dramatic cape and a commanding villain bearing" },
224
- { id: "caped-crusader-man", label: "Caped Crusader (Male)", group: "Heroes & Villains", dimension: "type", description: "Armored cowled male dark hero", promptHint: "a male caped crusader — armoured cowled masculine hero in dark colors with reinforced gauntlets, utility belt and a heavy cape" },
225
- { id: "caped-crusader-woman", label: "Caped Crusader (Female)", group: "Heroes & Villains", dimension: "type", description: "Armored cowled female dark hero", promptHint: "a female caped crusader — armoured cowled feminine hero in dark colors with reinforced gauntlets, utility belt and a heavy cape" },
243
+ { id: "caped-crusader-man", label: "Caped Crusader (Male)", group: "Heroes & Villains", dimension: "type", description: "Armored cowled male dark hero", promptHint: "a male caped crusader — armoured cowled masculine hero in dark colors with reinforced gauntlets, utility belt and a heavy cape", term: "male caped crusader" },
244
+ { id: "caped-crusader-woman", label: "Caped Crusader (Female)", group: "Heroes & Villains", dimension: "type", description: "Armored cowled female dark hero", promptHint: "a female caped crusader — armoured cowled feminine hero in dark colors with reinforced gauntlets, utility belt and a heavy cape", term: "female caped crusader" },
226
245
  { id: "caped-crusader", label: "Caped Crusader", group: "Heroes & Villains", dimension: "type", description: "Armored cowled dark hero", promptHint: "a caped crusader — armoured cowled hero in dark colors with reinforced gauntlets, utility belt and a heavy cape" },
227
246
  { id: "super-soldier", label: "Super-Soldier", group: "Heroes & Villains", dimension: "type", description: "Patriotic exo-armoured warrior", promptHint: "a super-soldier — military-grade exo-armour with patriotic markings, reinforced helm and a star-spangled emblem" },
228
247
  { id: "mutant", label: "Mutant", group: "Heroes & Villains", dimension: "type", description: "Human with one or two visible mutations", promptHint: "a mutant — human-baseline body with one or two visible mutations such as unusual skin pigmentation, glowing eyes, claws or gills" },
@@ -264,7 +283,7 @@ export const PEOPLE: ReadonlyArray<Person> = [
264
283
  // creature without baking in any specific art style.
265
284
  { id: "catgirl", label: "Catgirl", group: "Hybrid / Anthro", dimension: "type", description: "Woman with cat ears and tail", promptHint: "a catgirl — humanoid woman with cat ears on her head and a soft cat tail" },
266
285
  { id: "catboy", label: "Catboy", group: "Hybrid / Anthro", dimension: "type", description: "Man with cat ears and tail", promptHint: "a catboy — humanoid man with cat ears on his head and a soft cat tail" },
267
- { id: "anthro", label: "Anthropomorphic", group: "Hybrid / Anthro", dimension: "type", description: "Bipedal animal-headed humanoid", promptHint: "an anthropomorphic animal humanoid — bipedal body in human stance with an animal head, fur and animal tail" },
286
+ { id: "anthro", label: "Anthropomorphic", group: "Hybrid / Anthro", dimension: "type", description: "Bipedal animal-headed humanoid", promptHint: "an anthropomorphic animal humanoid — bipedal body in human stance with an animal head, fur and animal tail", term: "anthropomorphic animal humanoid" },
268
287
 
269
288
  // ----- Iconic / Public Domain -----
270
289
  // Only public-domain figures — modern trademarked characters (Superman,
@@ -282,12 +301,12 @@ export const PEOPLE: ReadonlyArray<Person> = [
282
301
  { id: "joan-of-arc", label: "Joan of Arc", group: "Iconic / Public Domain", dimension: "type", description: "Medieval warrior-maid in armour", promptHint: "Joan of Arc — medieval warrior-maid in shining plate armour over a white surcoat, holding a banner, short cropped hair and a determined holy expression" },
283
302
  { id: "cleopatra", label: "Cleopatra", group: "Iconic / Public Domain", dimension: "type", description: "Last pharaoh of Egypt", promptHint: "Cleopatra — Egyptian pharaoh-queen in pleated white linen and a broad gold collar, kohl-lined almond eyes, a black bobbed wig and a golden uraeus diadem" },
284
303
  { id: "captain-nemo", label: "Captain Nemo", group: "Iconic / Public Domain", dimension: "type", description: "Verne's submarine captain", promptHint: "Captain Nemo — 19th-century submarine captain in a dark double-breasted naval coat, peaked cap and a stern mariner's bearing" },
285
- { id: "alice-wonderland", label: "Alice (Wonderland)", group: "Iconic / Public Domain", dimension: "type", description: "Carroll's Wonderland girl", promptHint: "Alice from Wonderland — young girl in a blue dress with a white pinafore apron, long blonde hair tied back with a black bow and white knee-high stockings" },
304
+ { id: "alice-wonderland", label: "Alice (Wonderland)", group: "Iconic / Public Domain", dimension: "type", description: "Carroll's Wonderland girl", promptHint: "Alice from Wonderland — young girl in a blue dress with a white pinafore apron, long blonde hair tied back with a black bow and white knee-high stockings", term: "alice from wonderland" },
286
305
  { id: "peter-pan", label: "Peter Pan", group: "Iconic / Public Domain", dimension: "type", description: "Boy who never grew up", promptHint: "Peter Pan — boyish figure in a green tunic and tights with a pointed feathered cap, mischievous grin and a youthful adventurous bearing" },
287
- { id: "dorothy-oz", label: "Dorothy (Oz)", group: "Iconic / Public Domain", dimension: "type", description: "Oz girl in blue gingham", promptHint: "Dorothy from Oz — young girl in a blue and white gingham dress with brown pigtail braids tied with ribbons and ruby slippers" },
288
- { id: "tin-man", label: "Tin Man", group: "Iconic / Public Domain", dimension: "type", description: "Oz tin woodsman", promptHint: "the Tin Man from Oz — humanoid figure made of riveted tin plates with a funnel-shaped hat, an axe in hand and an oil-can at the belt" },
289
- { id: "scarecrow-oz", label: "Scarecrow (Oz)", group: "Iconic / Public Domain", dimension: "type", description: "Oz straw scarecrow", promptHint: "the Scarecrow from Oz — straw-stuffed humanoid in a ragged farmer's outfit and floppy pointed hat with a painted burlap face and patched clothes" },
290
- { id: "cowardly-lion", label: "Cowardly Lion", group: "Iconic / Public Domain", dimension: "type", description: "Oz anthropomorphic lion", promptHint: "the Cowardly Lion from Oz — anthropomorphic bipedal lion with a thick mane, expressive humanlike face and a fretful, timid posture" },
306
+ { id: "dorothy-oz", label: "Dorothy (Oz)", group: "Iconic / Public Domain", dimension: "type", description: "Oz girl in blue gingham", promptHint: "Dorothy from Oz — young girl in a blue and white gingham dress with brown pigtail braids tied with ribbons and ruby slippers", term: "dorothy from oz" },
307
+ { id: "tin-man", label: "Tin Man", group: "Iconic / Public Domain", dimension: "type", description: "Oz tin woodsman", promptHint: "the Tin Man from Oz — humanoid figure made of riveted tin plates with a funnel-shaped hat, an axe in hand and an oil-can at the belt", term: "the tin man from oz" },
308
+ { id: "scarecrow-oz", label: "Scarecrow (Oz)", group: "Iconic / Public Domain", dimension: "type", description: "Oz straw scarecrow", promptHint: "the Scarecrow from Oz — straw-stuffed humanoid in a ragged farmer's outfit and floppy pointed hat with a painted burlap face and patched clothes", term: "the scarecrow from oz" },
309
+ { id: "cowardly-lion", label: "Cowardly Lion", group: "Iconic / Public Domain", dimension: "type", description: "Oz anthropomorphic lion", promptHint: "the Cowardly Lion from Oz — anthropomorphic bipedal lion with a thick mane, expressive humanlike face and a fretful, timid posture", term: "the cowardly lion from oz" },
291
310
  { id: "santa-claus", label: "Santa Claus", group: "Iconic / Public Domain", dimension: "type", description: "Christmas gift-giver", promptHint: "Santa Claus — jolly bearded old man in a red coat trimmed with white fur, a wide black belt, red trousers and tall black boots, carrying a sack of toys" },
292
311
  { id: "grim-reaper", label: "Grim Reaper", group: "Iconic / Public Domain", dimension: "type", description: "Personification of Death", promptHint: "the Grim Reaper — tall hooded skeletal figure in a tattered black robe, bony hands gripping a long wooden scythe, face hidden in shadow" },
293
312
 
@@ -301,82 +320,82 @@ export const PEOPLE: ReadonlyArray<Person> = [
301
320
  { id: "age-young-child", label: "Young Child", dimension: "age", description: "Around 4-6 years old", promptHint: "a young child around 5 years old" },
302
321
  { id: "age-child", label: "Child", dimension: "age", description: "Around 7-9 years old", promptHint: "a child around 8 years old" },
303
322
  { id: "age-pre-teen", label: "Pre-Teen", dimension: "age", description: "Around 10-12 years old", promptHint: "a pre-teen around 11 years old" },
304
- { id: "age-early-teen", label: "Early Teen", dimension: "age", description: "Around 13-15 years old", promptHint: "in their early teens, around 14 years old" },
305
- { id: "age-late-teen", label: "Late Teen", dimension: "age", description: "Around 16-19 years old", promptHint: "in their late teens, around 17 years old" },
306
- { id: "age-teen", label: "Teenager (any)", dimension: "age", description: "Anywhere in 13-19", promptHint: "a teenager, somewhere in their teens" },
307
- { id: "age-early-20s", label: "Early 20s", dimension: "age", description: "Around 20-23 years old", promptHint: "in their early 20s, around 21 years old" },
308
- { id: "age-late-20s", label: "Late 20s", dimension: "age", description: "Around 24-29 years old", promptHint: "in their late 20s, around 27 years old" },
309
- { id: "age-20s", label: "20s (any)", dimension: "age", description: "Anywhere in their twenties", promptHint: "in their 20s" },
310
- { id: "age-30s", label: "30s", dimension: "age", description: "Thirties", promptHint: "in their 30s" },
311
- { id: "age-40s", label: "40s", dimension: "age", description: "Forties", promptHint: "in their 40s" },
312
- { id: "age-50s", label: "50s", dimension: "age", description: "Fifties", promptHint: "in their 50s" },
313
- { id: "age-60s", label: "60s", dimension: "age", description: "Sixties", promptHint: "in their 60s" },
323
+ { id: "age-early-teen", label: "Early Teen", dimension: "age", description: "Around 13-15 years old", promptHint: "in their early teens, around 14 years old", term: "in their early teens" },
324
+ { id: "age-late-teen", label: "Late Teen", dimension: "age", description: "Around 16-19 years old", promptHint: "in their late teens, around 17 years old", term: "in their late teens" },
325
+ { id: "age-teen", label: "Teenager (any)", dimension: "age", description: "Anywhere in 13-19", promptHint: "a teenager, somewhere in their teens", term: "in their teens" },
326
+ { id: "age-early-20s", label: "Early 20s", dimension: "age", description: "Around 20-23 years old", promptHint: "in their early 20s, around 21 years old", term: "in their early 20s" },
327
+ { id: "age-late-20s", label: "Late 20s", dimension: "age", description: "Around 24-29 years old", promptHint: "in their late 20s, around 27 years old", term: "in their late 20s" },
328
+ { id: "age-20s", label: "20s (any)", dimension: "age", description: "Anywhere in their twenties", promptHint: "in their 20s", term: "in their 20s" },
329
+ { id: "age-30s", label: "30s", dimension: "age", description: "Thirties", promptHint: "in their 30s", term: "in their 30s" },
330
+ { id: "age-40s", label: "40s", dimension: "age", description: "Forties", promptHint: "in their 40s", term: "in their 40s" },
331
+ { id: "age-50s", label: "50s", dimension: "age", description: "Fifties", promptHint: "in their 50s", term: "in their 50s" },
332
+ { id: "age-60s", label: "60s", dimension: "age", description: "Sixties", promptHint: "in their 60s", term: "in their 60s" },
314
333
  { id: "age-elderly", label: "Elderly", dimension: "age", description: "70 and older", promptHint: "elderly, in their 70s or older" },
315
334
  { id: "age-custom", label: "Custom age...", dimension: "age", description: "Specify an exact age in years", promptHint: "" },
316
335
 
317
336
  // -------------------- Ethnicity --------------------
318
337
  // Asian (generic + East / South / Southeast breakouts + national-level splits)
319
- { id: "asian-any", label: "Asian (any)", shortLabel: "any", group: "Asian", dimension: "ethnicity", description: "Any Asian — unspecified region", promptHint: "of Asian descent" },
320
- { id: "east-asian", label: "East Asian (any)", shortLabel: "East (any)", group: "Asian", dimension: "ethnicity", description: "East Asian features (broad)", promptHint: "East Asian" },
321
- { id: "chinese", label: "Chinese", group: "Asian", dimension: "ethnicity", description: "Han Chinese features", promptHint: "of Chinese descent" },
322
- { id: "japanese", label: "Japanese", group: "Asian", dimension: "ethnicity", description: "Japanese features", promptHint: "of Japanese descent" },
323
- { id: "korean", label: "Korean", group: "Asian", dimension: "ethnicity", description: "Korean features", promptHint: "of Korean descent" },
324
- { id: "mongolian-tibetan", label: "Mongolian / Tibetan", shortLabel: "Mongol / Tibetan", group: "Asian", dimension: "ethnicity", description: "Mongolian / Tibetan features", promptHint: "of Mongolian or Tibetan descent" },
325
- { id: "south-asian", label: "South Asian / Indian", shortLabel: "South / Indian", group: "Asian", dimension: "ethnicity", description: "Indian / Pakistani / Bangladeshi / Sri Lankan", promptHint: "South Asian" },
326
- { id: "southeast-asian", label: "Southeast Asian (any)", shortLabel: "Southeast (any)", group: "Asian", dimension: "ethnicity", description: "Southeast Asian (broad)", promptHint: "Southeast Asian" },
327
- { id: "thai", label: "Thai", group: "Asian", dimension: "ethnicity", description: "Thai features", promptHint: "of Thai descent" },
328
- { id: "vietnamese", label: "Vietnamese", group: "Asian", dimension: "ethnicity", description: "Vietnamese features", promptHint: "of Vietnamese descent" },
329
- { id: "indonesian-malay", label: "Indonesian / Malay", shortLabel: "Indo / Malay", group: "Asian", dimension: "ethnicity", description: "Indonesian / Malay features", promptHint: "of Indonesian or Malay descent" },
330
- { id: "khmer", label: "Khmer / Cambodian", shortLabel: "Khmer", group: "Asian", dimension: "ethnicity", description: "Khmer / Cambodian features", promptHint: "of Khmer Cambodian descent" },
338
+ { id: "asian-any", label: "Asian (any)", shortLabel: "any", group: "Asian", dimension: "ethnicity", description: "Any Asian — unspecified region", promptHint: "of Asian descent", term: "of asian descent" },
339
+ { id: "east-asian", label: "East Asian (any)", shortLabel: "East (any)", group: "Asian", dimension: "ethnicity", description: "East Asian features (broad)", promptHint: "East Asian", term: "of east asian descent" },
340
+ { id: "chinese", label: "Chinese", group: "Asian", dimension: "ethnicity", description: "Han Chinese features", promptHint: "of Chinese descent", term: "of chinese descent" },
341
+ { id: "japanese", label: "Japanese", group: "Asian", dimension: "ethnicity", description: "Japanese features", promptHint: "of Japanese descent", term: "of japanese descent" },
342
+ { id: "korean", label: "Korean", group: "Asian", dimension: "ethnicity", description: "Korean features", promptHint: "of Korean descent", term: "of korean descent" },
343
+ { id: "mongolian-tibetan", label: "Mongolian / Tibetan", shortLabel: "Mongol / Tibetan", group: "Asian", dimension: "ethnicity", description: "Mongolian / Tibetan features", promptHint: "of Mongolian or Tibetan descent", term: "of mongolian or tibetan descent" },
344
+ { id: "south-asian", label: "South Asian / Indian", shortLabel: "South / Indian", group: "Asian", dimension: "ethnicity", description: "Indian / Pakistani / Bangladeshi / Sri Lankan", promptHint: "South Asian", term: "of south asian or indian descent" },
345
+ { id: "southeast-asian", label: "Southeast Asian (any)", shortLabel: "Southeast (any)", group: "Asian", dimension: "ethnicity", description: "Southeast Asian (broad)", promptHint: "Southeast Asian", term: "of southeast asian descent" },
346
+ { id: "thai", label: "Thai", group: "Asian", dimension: "ethnicity", description: "Thai features", promptHint: "of Thai descent", term: "of thai descent" },
347
+ { id: "vietnamese", label: "Vietnamese", group: "Asian", dimension: "ethnicity", description: "Vietnamese features", promptHint: "of Vietnamese descent", term: "of vietnamese descent" },
348
+ { id: "indonesian-malay", label: "Indonesian / Malay", shortLabel: "Indo / Malay", group: "Asian", dimension: "ethnicity", description: "Indonesian / Malay features", promptHint: "of Indonesian or Malay descent", term: "of indonesian or malay descent" },
349
+ { id: "khmer", label: "Khmer / Cambodian", shortLabel: "Khmer", group: "Asian", dimension: "ethnicity", description: "Khmer / Cambodian features", promptHint: "of Khmer Cambodian descent", term: "of khmer cambodian descent" },
331
350
  { id: "filipino", label: "Filipino", group: "Asian", dimension: "ethnicity", description: "Filipino features (Asian + Spanish heritage)", promptHint: "Filipino" },
332
351
  // Middle East & North Africa
333
- { id: "mena-any", label: "Middle Eastern / N. African (any)", shortLabel: "any", group: "Middle East & N. Africa", dimension: "ethnicity", description: "Any MENA — unspecified", promptHint: "of Middle Eastern or North African descent" },
334
- { id: "middle-eastern", label: "Middle Eastern (Arab)", shortLabel: "Arab", group: "Middle East & N. Africa", dimension: "ethnicity", description: "Arab / Levantine / Gulf features", promptHint: "Middle Eastern" },
335
- { id: "turkish", label: "Turkish", group: "Middle East & N. Africa", dimension: "ethnicity", description: "Anatolian Turkish features", promptHint: "of Turkish descent" },
336
- { id: "persian", label: "Persian / Iranian", shortLabel: "Persian", group: "Middle East & N. Africa", dimension: "ethnicity", description: "Indo-Iranian features", promptHint: "of Persian Iranian descent" },
337
- { id: "israeli", label: "Israeli", group: "Middle East & N. Africa", dimension: "ethnicity", description: "Israeli features (Mediterranean Levantine, broad)", promptHint: "of Israeli descent" },
352
+ { id: "mena-any", label: "Middle Eastern / N. African (any)", shortLabel: "any", group: "Middle East & N. Africa", dimension: "ethnicity", description: "Any MENA — unspecified", promptHint: "of Middle Eastern or North African descent", term: "of middle eastern or north african descent" },
353
+ { id: "middle-eastern", label: "Middle Eastern (Arab)", shortLabel: "Arab", group: "Middle East & N. Africa", dimension: "ethnicity", description: "Arab / Levantine / Gulf features", promptHint: "Middle Eastern", term: "of middle eastern arab descent" },
354
+ { id: "turkish", label: "Turkish", group: "Middle East & N. Africa", dimension: "ethnicity", description: "Anatolian Turkish features", promptHint: "of Turkish descent", term: "of turkish descent" },
355
+ { id: "persian", label: "Persian / Iranian", shortLabel: "Persian", group: "Middle East & N. Africa", dimension: "ethnicity", description: "Indo-Iranian features", promptHint: "of Persian Iranian descent", term: "of persian iranian descent" },
356
+ { id: "israeli", label: "Israeli", group: "Middle East & N. Africa", dimension: "ethnicity", description: "Israeli features (Mediterranean Levantine, broad)", promptHint: "of Israeli descent", term: "of israeli descent" },
338
357
  // African
339
- { id: "african", label: "African (any)", shortLabel: "any", group: "African", dimension: "ethnicity", description: "Any Sub-Saharan African — unspecified region", promptHint: "of African descent" },
340
- { id: "west-african", label: "West African", shortLabel: "West", group: "African", dimension: "ethnicity", description: "Yoruba / Igbo / Akan / Wolof", promptHint: "of West African descent" },
341
- { id: "east-african", label: "East African", shortLabel: "East", group: "African", dimension: "ethnicity", description: "Somali / Ethiopian / Swahili", promptHint: "of East African descent" },
342
- { id: "central-african", label: "Central African", shortLabel: "Central", group: "African", dimension: "ethnicity", description: "Bantu / Congolese / Angolan", promptHint: "of Central African descent" },
343
- { id: "southern-african", label: "Southern African", shortLabel: "Southern", group: "African", dimension: "ethnicity", description: "Zulu / Xhosa / Sotho", promptHint: "of Southern African descent" },
344
- { id: "afro-caribbean", label: "Afro-Caribbean", group: "African", dimension: "ethnicity", description: "Anglophone Caribbean (Jamaica / Trinidad / Barbados)", promptHint: "of Afro-Caribbean descent" },
358
+ { id: "african", label: "African (any)", shortLabel: "any", group: "African", dimension: "ethnicity", description: "Any Sub-Saharan African — unspecified region", promptHint: "of African descent", term: "of african descent" },
359
+ { id: "west-african", label: "West African", shortLabel: "West", group: "African", dimension: "ethnicity", description: "Yoruba / Igbo / Akan / Wolof", promptHint: "of West African descent", term: "of west african descent" },
360
+ { id: "east-african", label: "East African", shortLabel: "East", group: "African", dimension: "ethnicity", description: "Somali / Ethiopian / Swahili", promptHint: "of East African descent", term: "of east african descent" },
361
+ { id: "central-african", label: "Central African", shortLabel: "Central", group: "African", dimension: "ethnicity", description: "Bantu / Congolese / Angolan", promptHint: "of Central African descent", term: "of central african descent" },
362
+ { id: "southern-african", label: "Southern African", shortLabel: "Southern", group: "African", dimension: "ethnicity", description: "Zulu / Xhosa / Sotho", promptHint: "of Southern African descent", term: "of southern african descent" },
363
+ { id: "afro-caribbean", label: "Afro-Caribbean", group: "African", dimension: "ethnicity", description: "Anglophone Caribbean (Jamaica / Trinidad / Barbados)", promptHint: "of Afro-Caribbean descent", term: "of afro-caribbean descent" },
345
364
  // European
346
- { id: "european-any", label: "European (any)", shortLabel: "any", group: "European", dimension: "ethnicity", description: "Any European — unspecified region", promptHint: "of European descent" },
347
- { id: "nordic", label: "Nordic (any)", shortLabel: "Nordic", group: "European", dimension: "ethnicity", description: "Any Scandinavian / Northern European — unspecified region", promptHint: "of Nordic Scandinavian descent" },
348
- { id: "swedish", label: "Swedish", group: "European", dimension: "ethnicity", description: "Sweden — tall, often blonde, fine features", promptHint: "of Swedish descent" },
349
- { id: "norwegian", label: "Norwegian", group: "European", dimension: "ethnicity", description: "Norway — fair-skinned, often light-eyed", promptHint: "of Norwegian descent" },
350
- { id: "danish", label: "Danish", group: "European", dimension: "ethnicity", description: "Denmark — soft features, ash-blonde common", promptHint: "of Danish descent" },
351
- { id: "finnish", label: "Finnish", group: "European", dimension: "ethnicity", description: "Finland — Uralic features, high cheekbones", promptHint: "of Finnish descent" },
352
- { id: "icelandic", label: "Icelandic", group: "European", dimension: "ethnicity", description: "Iceland — Norse + Celtic blend, sharp angular features", promptHint: "of Icelandic descent" },
353
- { id: "celtic", label: "Celtic", group: "European", dimension: "ethnicity", description: "British / Irish features", promptHint: "of Celtic British descent" },
354
- { id: "mediterranean", label: "Mediterranean", shortLabel: "Mediter.", group: "European", dimension: "ethnicity", description: "Southern European (broad)", promptHint: "of Mediterranean descent" },
355
- { id: "slavic", label: "Slavic", group: "European", dimension: "ethnicity", description: "Eastern European features", promptHint: "of Slavic Eastern European descent" },
356
- { id: "czech", label: "Czech", group: "European", dimension: "ethnicity", description: "Czech features (West Slavic, Central European)", promptHint: "of Czech descent" },
357
- { id: "russian", label: "Russian", group: "European", dimension: "ethnicity", description: "Russian features (East Slavic)", promptHint: "of Russian descent" },
358
- { id: "ukrainian", label: "Ukrainian", group: "European", dimension: "ethnicity", description: "Ukrainian features (East Slavic)", promptHint: "of Ukrainian descent" },
359
- { id: "italian", label: "Italian", group: "European", dimension: "ethnicity", description: "Italian features", promptHint: "of Italian descent" },
360
- { id: "iberian", label: "Iberian (Spanish / Portuguese)", shortLabel: "Iberian", group: "European", dimension: "ethnicity", description: "Spanish / Portuguese with Celtiberian + Moorish heritage", promptHint: "of Iberian Spanish or Portuguese descent" },
361
- { id: "french", label: "French", group: "European", dimension: "ethnicity", description: "French features (varies north to south)", promptHint: "of French descent" },
362
- { id: "germanic", label: "Germanic", group: "European", dimension: "ethnicity", description: "German / Austrian / Dutch / Swiss-German", promptHint: "of Germanic descent" },
363
- { id: "greek", label: "Greek", group: "European", dimension: "ethnicity", description: "Greek features", promptHint: "of Greek descent" },
364
- { id: "baltic", label: "Baltic", group: "European", dimension: "ethnicity", description: "Lithuanian / Latvian / Estonian", promptHint: "of Baltic descent" },
365
+ { id: "european-any", label: "European (any)", shortLabel: "any", group: "European", dimension: "ethnicity", description: "Any European — unspecified region", promptHint: "of European descent", term: "of european descent" },
366
+ { id: "nordic", label: "Nordic (any)", shortLabel: "Nordic", group: "European", dimension: "ethnicity", description: "Any Scandinavian / Northern European — unspecified region", promptHint: "of Nordic Scandinavian descent", term: "of nordic scandinavian descent" },
367
+ { id: "swedish", label: "Swedish", group: "European", dimension: "ethnicity", description: "Sweden — tall, often blonde, fine features", promptHint: "of Swedish descent", term: "of swedish descent" },
368
+ { id: "norwegian", label: "Norwegian", group: "European", dimension: "ethnicity", description: "Norway — fair-skinned, often light-eyed", promptHint: "of Norwegian descent", term: "of norwegian descent" },
369
+ { id: "danish", label: "Danish", group: "European", dimension: "ethnicity", description: "Denmark — soft features, ash-blonde common", promptHint: "of Danish descent", term: "of danish descent" },
370
+ { id: "finnish", label: "Finnish", group: "European", dimension: "ethnicity", description: "Finland — Uralic features, high cheekbones", promptHint: "of Finnish descent", term: "of finnish descent" },
371
+ { id: "icelandic", label: "Icelandic", group: "European", dimension: "ethnicity", description: "Iceland — Norse + Celtic blend, sharp angular features", promptHint: "of Icelandic descent", term: "of icelandic descent" },
372
+ { id: "celtic", label: "Celtic", group: "European", dimension: "ethnicity", description: "British / Irish features", promptHint: "of Celtic British descent", term: "of celtic british descent" },
373
+ { id: "mediterranean", label: "Mediterranean", shortLabel: "Mediter.", group: "European", dimension: "ethnicity", description: "Southern European (broad)", promptHint: "of Mediterranean descent", term: "of mediterranean descent" },
374
+ { id: "slavic", label: "Slavic", group: "European", dimension: "ethnicity", description: "Eastern European features", promptHint: "of Slavic Eastern European descent", term: "of slavic eastern european descent" },
375
+ { id: "czech", label: "Czech", group: "European", dimension: "ethnicity", description: "Czech features (West Slavic, Central European)", promptHint: "of Czech descent", term: "of czech descent" },
376
+ { id: "russian", label: "Russian", group: "European", dimension: "ethnicity", description: "Russian features (East Slavic)", promptHint: "of Russian descent", term: "of russian descent" },
377
+ { id: "ukrainian", label: "Ukrainian", group: "European", dimension: "ethnicity", description: "Ukrainian features (East Slavic)", promptHint: "of Ukrainian descent", term: "of ukrainian descent" },
378
+ { id: "italian", label: "Italian", group: "European", dimension: "ethnicity", description: "Italian features", promptHint: "of Italian descent", term: "of italian descent" },
379
+ { id: "iberian", label: "Iberian (Spanish / Portuguese)", shortLabel: "Iberian", group: "European", dimension: "ethnicity", description: "Spanish / Portuguese with Celtiberian + Moorish heritage", promptHint: "of Iberian Spanish or Portuguese descent", term: "of iberian spanish or portuguese descent" },
380
+ { id: "french", label: "French", group: "European", dimension: "ethnicity", description: "French features (varies north to south)", promptHint: "of French descent", term: "of french descent" },
381
+ { id: "germanic", label: "Germanic", group: "European", dimension: "ethnicity", description: "German / Austrian / Dutch / Swiss-German", promptHint: "of Germanic descent", term: "of germanic descent" },
382
+ { id: "greek", label: "Greek", group: "European", dimension: "ethnicity", description: "Greek features", promptHint: "of Greek descent", term: "of greek descent" },
383
+ { id: "baltic", label: "Baltic", group: "European", dimension: "ethnicity", description: "Lithuanian / Latvian / Estonian", promptHint: "of Baltic descent", term: "of baltic descent" },
365
384
  // Latin American
366
- { id: "latin-american", label: "Latin American (any)", shortLabel: "any", group: "Latin American", dimension: "ethnicity", description: "Any Latin American — unspecified region", promptHint: "Latin American" },
367
- { id: "mexican-mesoamerican", label: "Mexican / Mesoamerican", shortLabel: "Mexican", group: "Latin American", dimension: "ethnicity", description: "Mexican / Guatemalan / Central American Mestizo", promptHint: "of Mexican or Mesoamerican heritage" },
368
- { id: "caribbean-latino", label: "Caribbean Latin", shortLabel: "Caribbean", group: "Latin American", dimension: "ethnicity", description: "Cuban / Dominican / Puerto Rican", promptHint: "of Caribbean Latin heritage" },
369
- { id: "brazilian", label: "Brazilian", group: "Latin American", dimension: "ethnicity", description: "Brazilian (Portuguese + African + Indigenous)", promptHint: "of Brazilian heritage" },
370
- { id: "andean-indigenous", label: "Andean / Indigenous Latin", shortLabel: "Andean", group: "Latin American", dimension: "ethnicity", description: "Quechua / Aymara / Maya / Nahua", promptHint: "of Andean or Indigenous Latin American heritage" },
371
- { id: "southern-cone", label: "Southern Cone European", shortLabel: "Southern Cone", group: "Latin American", dimension: "ethnicity", description: "Argentinian / Uruguayan / Chilean (largely European descent)", promptHint: "of Southern Cone European descent" },
385
+ { id: "latin-american", label: "Latin American (any)", shortLabel: "any", group: "Latin American", dimension: "ethnicity", description: "Any Latin American — unspecified region", promptHint: "Latin American", term: "of latin american descent" },
386
+ { id: "mexican-mesoamerican", label: "Mexican / Mesoamerican", shortLabel: "Mexican", group: "Latin American", dimension: "ethnicity", description: "Mexican / Guatemalan / Central American Mestizo", promptHint: "of Mexican or Mesoamerican heritage", term: "of mexican or mesoamerican heritage" },
387
+ { id: "caribbean-latino", label: "Caribbean Latin", shortLabel: "Caribbean", group: "Latin American", dimension: "ethnicity", description: "Cuban / Dominican / Puerto Rican", promptHint: "of Caribbean Latin heritage", term: "of caribbean latin heritage" },
388
+ { id: "brazilian", label: "Brazilian", group: "Latin American", dimension: "ethnicity", description: "Brazilian (Portuguese + African + Indigenous)", promptHint: "of Brazilian heritage", term: "of brazilian heritage" },
389
+ { id: "andean-indigenous", label: "Andean / Indigenous Latin", shortLabel: "Andean", group: "Latin American", dimension: "ethnicity", description: "Quechua / Aymara / Maya / Nahua", promptHint: "of Andean or Indigenous Latin American heritage", term: "of andean or indigenous latin heritage" },
390
+ { id: "southern-cone", label: "Southern Cone European", shortLabel: "Southern Cone", group: "Latin American", dimension: "ethnicity", description: "Argentinian / Uruguayan / Chilean (largely European descent)", promptHint: "of Southern Cone European descent", term: "of southern cone european descent" },
372
391
  // Indigenous
373
- { id: "indigenous-any", label: "Indigenous (any)", shortLabel: "any", group: "Indigenous", dimension: "ethnicity", description: "Any Indigenous — unspecified group", promptHint: "of Indigenous descent" },
392
+ { id: "indigenous-any", label: "Indigenous (any)", shortLabel: "any", group: "Indigenous", dimension: "ethnicity", description: "Any Indigenous — unspecified group", promptHint: "of Indigenous descent", term: "of indigenous descent" },
374
393
  { id: "native-american", label: "Native American", shortLabel: "Native American", group: "Indigenous", dimension: "ethnicity", description: "Native American / First Nations", promptHint: "Native American" },
375
394
  { id: "aboriginal-australian", label: "Aboriginal Australian", shortLabel: "Aboriginal", group: "Indigenous", dimension: "ethnicity", description: "Aboriginal Australian / Torres Strait", promptHint: "Aboriginal Australian" },
376
395
  { id: "pacific-islander", label: "Pacific Islander", shortLabel: "Pacific Isl.", group: "Indigenous", dimension: "ethnicity", description: "Polynesian / Maori / Samoan / Hawaiian", promptHint: "Pacific Islander" },
377
- { id: "inuit", label: "Inuit / Arctic", shortLabel: "Inuit", group: "Indigenous", dimension: "ethnicity", description: "Inuit / Yupik / Aleut", promptHint: "of Inuit Arctic descent" },
396
+ { id: "inuit", label: "Inuit / Arctic", shortLabel: "Inuit", group: "Indigenous", dimension: "ethnicity", description: "Inuit / Yupik / Aleut", promptHint: "of Inuit Arctic descent", term: "of inuit arctic descent" },
378
397
  // Other
379
- { id: "mixed", label: "Mixed", group: "Other", dimension: "ethnicity", description: "Mixed heritage", promptHint: "of mixed heritage" },
398
+ { id: "mixed", label: "Mixed", group: "Other", dimension: "ethnicity", description: "Mixed heritage", promptHint: "of mixed heritage", term: "of mixed heritage" },
380
399
 
381
400
  // -------------------- Body — six independent proportion axes --------------------
382
401
  // Frame / Body Mass / Bust / Waist / Hips / Silhouette replace the old single
@@ -390,307 +409,307 @@ export const PEOPLE: ReadonlyArray<Person> = [
390
409
  { id: "frame-petite", label: "Petite", dimension: "frame", description: "Small, short-statured frame", promptHint: "petite" },
391
410
  { id: "frame-slim", label: "Slim", dimension: "frame", description: "Narrow, slender frame", promptHint: "slim" },
392
411
  { id: "frame-average", label: "Average", dimension: "frame", description: "Average frame", promptHint: "" },
393
- { id: "frame-broad", label: "Broad", dimension: "frame", description: "Wide, broad-shouldered frame", promptHint: "broad-framed" },
412
+ { id: "frame-broad", label: "Broad", dimension: "frame", description: "Wide, broad-shouldered frame", promptHint: "broad-framed", term: "broad-framed" },
394
413
 
395
414
  // ----- Body Mass (leanness / weight, independent of Frame) -----
396
- { id: "mass-lean", label: "Lean", dimension: "body-mass", description: "Lean, low body mass", promptHint: "lean build" },
415
+ { id: "mass-lean", label: "Lean", dimension: "body-mass", description: "Lean, low body mass", promptHint: "lean build", term: "lean build" },
397
416
  { id: "mass-average", label: "Average", dimension: "body-mass", description: "Average body mass", promptHint: "" },
398
- { id: "mass-full", label: "Full", dimension: "body-mass", description: "Full-figured", promptHint: "full-figured" },
399
- { id: "mass-heavy", label: "Heavy", dimension: "body-mass", description: "Heavy-set, large build", promptHint: "heavy-set build" },
417
+ { id: "mass-full", label: "Full", dimension: "body-mass", description: "Full-figured", promptHint: "full-figured", term: "full-figured" },
418
+ { id: "mass-heavy", label: "Heavy", dimension: "body-mass", description: "Heavy-set, large build", promptHint: "heavy-set build", term: "heavy-set build" },
400
419
 
401
420
  // ----- Bust (applicable subjects; ungated like Facial Hair, neutral = no-op) -----
402
- { id: "bust-small", label: "Small", dimension: "bust", description: "Small bust", promptHint: "small bust" },
421
+ { id: "bust-small", label: "Small", dimension: "bust", description: "Small bust", promptHint: "small bust", term: "small bust" },
403
422
  { id: "bust-average", label: "Average", dimension: "bust", description: "Average bust", promptHint: "" },
404
- { id: "bust-full", label: "Full", dimension: "bust", description: "Full bust", promptHint: "full bust" },
405
- { id: "bust-very-full", label: "Very Full", dimension: "bust", description: "Very full bust", promptHint: "very full bust" },
423
+ { id: "bust-full", label: "Full", dimension: "bust", description: "Full bust", promptHint: "full bust", term: "full bust" },
424
+ { id: "bust-very-full", label: "Very Full", dimension: "bust", description: "Very full bust", promptHint: "very full bust", term: "very full bust" },
406
425
 
407
426
  // ----- Waist -----
408
- { id: "waist-defined", label: "Defined", dimension: "waist", description: "Defined, cinched waist", promptHint: "defined waist" },
427
+ { id: "waist-defined", label: "Defined", dimension: "waist", description: "Defined, cinched waist", promptHint: "defined waist", term: "defined waist" },
409
428
  { id: "waist-average", label: "Average", dimension: "waist", description: "Average waist", promptHint: "" },
410
- { id: "waist-straight", label: "Straight", dimension: "waist", description: "Straight, undefined waist", promptHint: "straight waistline" },
429
+ { id: "waist-straight", label: "Straight", dimension: "waist", description: "Straight, undefined waist", promptHint: "straight waistline", term: "straight waistline" },
411
430
 
412
431
  // ----- Hips -----
413
- { id: "hips-narrow", label: "Narrow", dimension: "hips", description: "Narrow hips", promptHint: "narrow hips" },
432
+ { id: "hips-narrow", label: "Narrow", dimension: "hips", description: "Narrow hips", promptHint: "narrow hips", term: "narrow hips" },
414
433
  { id: "hips-balanced", label: "Balanced", dimension: "hips", description: "Balanced hips", promptHint: "" },
415
- { id: "hips-wide", label: "Wide", dimension: "hips", description: "Wide hips", promptHint: "wide hips" },
434
+ { id: "hips-wide", label: "Wide", dimension: "hips", description: "Wide hips", promptHint: "wide hips", term: "wide hips" },
416
435
 
417
436
  // ----- Silhouette (overall body shape; optional, no neutral) -----
418
- { id: "silhouette-hourglass", label: "Hourglass", dimension: "silhouette", description: "Balanced bust + hips, defined waist", promptHint: "hourglass silhouette" },
419
- { id: "silhouette-rectangular", label: "Rectangular", dimension: "silhouette", description: "Straight up-and-down silhouette", promptHint: "rectangular silhouette" },
420
- { id: "silhouette-pear", label: "Pear", dimension: "silhouette", description: "Hips wider than shoulders", promptHint: "pear-shaped silhouette" },
421
- { id: "silhouette-inverted", label: "Inverted Triangle", dimension: "silhouette", description: "Broad shoulders, narrow hips", promptHint: "inverted-triangle silhouette" },
422
- { id: "silhouette-athletic", label: "Athletic", dimension: "silhouette", description: "Lean, toned, V-taper", promptHint: "athletic silhouette" },
437
+ { id: "silhouette-hourglass", label: "Hourglass", dimension: "silhouette", description: "Balanced bust + hips, defined waist", promptHint: "hourglass silhouette", term: "hourglass silhouette" },
438
+ { id: "silhouette-rectangular", label: "Rectangular", dimension: "silhouette", description: "Straight up-and-down silhouette", promptHint: "rectangular silhouette", term: "rectangular silhouette" },
439
+ { id: "silhouette-pear", label: "Pear", dimension: "silhouette", description: "Hips wider than shoulders", promptHint: "pear-shaped silhouette", term: "pear-shaped silhouette" },
440
+ { id: "silhouette-inverted", label: "Inverted Triangle", dimension: "silhouette", description: "Broad shoulders, narrow hips", promptHint: "inverted-triangle silhouette", term: "inverted-triangle silhouette" },
441
+ { id: "silhouette-athletic", label: "Athletic", dimension: "silhouette", description: "Lean, toned, V-taper", promptHint: "athletic silhouette", term: "athletic silhouette" },
423
442
 
424
443
  // -------------------- Face Shape --------------------
425
- { id: "face-oval", label: "Oval", dimension: "face-shape", description: "Slightly longer than wide, soft curves", promptHint: "an oval face shape" },
426
- { id: "face-round", label: "Round", dimension: "face-shape", description: "Soft circular face", promptHint: "a round face shape" },
427
- { id: "face-square", label: "Square", dimension: "face-shape", description: "Strong jaw, equal width forehead and jaw", promptHint: "a square face shape with a strong jaw" },
428
- { id: "face-heart", label: "Heart", dimension: "face-shape", description: "Wider forehead, pointed chin", promptHint: "a heart-shaped face with a wide forehead and pointed chin" },
429
- { id: "face-diamond", label: "Diamond", dimension: "face-shape", description: "Narrow forehead and chin, wide cheekbones", promptHint: "a diamond face shape with a narrow forehead and chin and wide cheekbones" },
430
- { id: "face-oblong", label: "Oblong", dimension: "face-shape", description: "Long and narrow", promptHint: "an oblong face shape, long and narrow" },
431
- { id: "face-triangular", label: "Triangular", dimension: "face-shape", description: "Narrow forehead, wide jaw", promptHint: "a triangular face shape with a narrow forehead and wide jaw" },
444
+ { id: "face-oval", label: "Oval", dimension: "face-shape", description: "Slightly longer than wide, soft curves", promptHint: "an oval face shape", term: "oval face" },
445
+ { id: "face-round", label: "Round", dimension: "face-shape", description: "Soft circular face", promptHint: "a round face shape", term: "round face" },
446
+ { id: "face-square", label: "Square", dimension: "face-shape", description: "Strong jaw, equal width forehead and jaw", promptHint: "a square face shape with a strong jaw", term: "square face with a strong jaw" },
447
+ { id: "face-heart", label: "Heart", dimension: "face-shape", description: "Wider forehead, pointed chin", promptHint: "a heart-shaped face with a wide forehead and pointed chin", term: "heart-shaped face" },
448
+ { id: "face-diamond", label: "Diamond", dimension: "face-shape", description: "Narrow forehead and chin, wide cheekbones", promptHint: "a diamond face shape with a narrow forehead and chin and wide cheekbones", term: "diamond face" },
449
+ { id: "face-oblong", label: "Oblong", dimension: "face-shape", description: "Long and narrow", promptHint: "an oblong face shape, long and narrow", term: "oblong face" },
450
+ { id: "face-triangular", label: "Triangular", dimension: "face-shape", description: "Narrow forehead, wide jaw", promptHint: "a triangular face shape with a narrow forehead and wide jaw", term: "triangular face" },
432
451
 
433
452
  // -------------------- Jawline --------------------
434
- { id: "jaw-strong", label: "Strong", dimension: "jawline", description: "Sharp, defined jawline", promptHint: "a strong, sharply defined jawline" },
435
- { id: "jaw-soft", label: "Soft", dimension: "jawline", description: "Soft, rounded jaw", promptHint: "a soft rounded jawline" },
436
- { id: "jaw-pointed", label: "Pointed", dimension: "jawline", description: "Pointed chin, narrow jaw", promptHint: "a pointed chin with a narrow jawline" },
437
- { id: "jaw-wide", label: "Wide", dimension: "jawline", description: "Wide, broad jaw", promptHint: "a wide broad jaw" },
453
+ { id: "jaw-strong", label: "Strong", dimension: "jawline", description: "Sharp, defined jawline", promptHint: "a strong, sharply defined jawline", term: "strong defined jawline" },
454
+ { id: "jaw-soft", label: "Soft", dimension: "jawline", description: "Soft, rounded jaw", promptHint: "a soft rounded jawline", term: "soft rounded jawline" },
455
+ { id: "jaw-pointed", label: "Pointed", dimension: "jawline", description: "Pointed chin, narrow jaw", promptHint: "a pointed chin with a narrow jawline", term: "pointed chin and narrow jawline" },
456
+ { id: "jaw-wide", label: "Wide", dimension: "jawline", description: "Wide, broad jaw", promptHint: "a wide broad jaw", term: "wide broad jaw" },
438
457
  { id: "jaw-double", label: "Double Chin", dimension: "jawline", description: "Visible double chin", promptHint: "a visible double chin" },
439
458
 
440
459
  // -------------------- Cheekbones --------------------
441
460
  // Neutral-first: "Average" carries an empty promptHint so enabling the
442
461
  // dimension injects nothing until a non-neutral value is picked.
443
462
  { id: "cheekbones-average", label: "Average", dimension: "cheekbones", description: "Average cheekbone projection (no emphasis)", promptHint: "" },
444
- { id: "cheekbones-low", label: "Low", dimension: "cheekbones", description: "Low, flat cheekbones", promptHint: "low, flat cheekbones" },
445
- { id: "cheekbones-high-defined", label: "High & Defined", dimension: "cheekbones", description: "High, clearly defined cheekbones", promptHint: "high, defined cheekbones" },
446
- { id: "cheekbones-sculpted", label: "Sculpted-High", dimension: "cheekbones", description: "Sharply sculpted high cheekbones", promptHint: "sharply sculpted high cheekbones with strong cheekbone projection" },
447
- { id: "cheekbones-wide", label: "Wide", dimension: "cheekbones", description: "Wide, prominent cheekbones", promptHint: "wide, prominent cheekbones" },
463
+ { id: "cheekbones-low", label: "Low", dimension: "cheekbones", description: "Low, flat cheekbones", promptHint: "low, flat cheekbones", term: "low flat cheekbones" },
464
+ { id: "cheekbones-high-defined", label: "High & Defined", dimension: "cheekbones", description: "High, clearly defined cheekbones", promptHint: "high, defined cheekbones", term: "high defined cheekbones" },
465
+ { id: "cheekbones-sculpted", label: "Sculpted-High", dimension: "cheekbones", description: "Sharply sculpted high cheekbones", promptHint: "sharply sculpted high cheekbones with strong cheekbone projection", term: "sharply sculpted high cheekbones" },
466
+ { id: "cheekbones-wide", label: "Wide", dimension: "cheekbones", description: "Wide, prominent cheekbones", promptHint: "wide, prominent cheekbones", term: "wide prominent cheekbones" },
448
467
 
449
468
  // -------------------- Facial Fullness (face leanness, independent of body Build) --------------------
450
469
  { id: "facial-fullness-average", label: "Average", dimension: "facial-fullness", description: "Average facial fullness", promptHint: "" },
451
- { id: "facial-fullness-gaunt", label: "Gaunt", dimension: "facial-fullness", description: "Hollow cheeks, very low facial fat", promptHint: "a gaunt face with hollow cheeks and very low facial fat" },
452
- { id: "facial-fullness-lean", label: "Lean", dimension: "facial-fullness", description: "Low facial fat, subtle hollowing under cheekbones", promptHint: "a lean face with low facial fat and subtle hollowing beneath the cheekbones" },
453
- { id: "facial-fullness-full", label: "Full", dimension: "facial-fullness", description: "Soft, well-padded cheeks", promptHint: "a full face with soft, well-padded cheeks" },
454
- { id: "facial-fullness-round", label: "Round", dimension: "facial-fullness", description: "Round face, soft rounded cheeks", promptHint: "a round face with soft, rounded cheeks" },
470
+ { id: "facial-fullness-gaunt", label: "Gaunt", dimension: "facial-fullness", description: "Hollow cheeks, very low facial fat", promptHint: "a gaunt face with hollow cheeks and very low facial fat", term: "gaunt face with hollow cheeks" },
471
+ { id: "facial-fullness-lean", label: "Lean", dimension: "facial-fullness", description: "Low facial fat, subtle hollowing under cheekbones", promptHint: "a lean face with low facial fat and subtle hollowing beneath the cheekbones", term: "lean face with low facial fat" },
472
+ { id: "facial-fullness-full", label: "Full", dimension: "facial-fullness", description: "Soft, well-padded cheeks", promptHint: "a full face with soft, well-padded cheeks", term: "full face with soft padded cheeks" },
473
+ { id: "facial-fullness-round", label: "Round", dimension: "facial-fullness", description: "Round face, soft rounded cheeks", promptHint: "a round face with soft, rounded cheeks", term: "round face with soft rounded cheeks" },
455
474
 
456
475
  // -------------------- Eye Shape (anatomical shape only — lid/tilt/spacing/set split out below) --------------------
457
- { id: "eye-almond", label: "Almond", dimension: "eye-shape", description: "Almond-shaped eyes", promptHint: "almond-shaped eyes" },
458
- { id: "eye-round", label: "Round", dimension: "eye-shape", description: "Wide, round eyes", promptHint: "wide round eyes" },
459
- { id: "eye-monolid", label: "Monolid", dimension: "eye-shape", description: "No visible crease, smooth lid", promptHint: "monolid eyes with no visible crease" },
460
- { id: "eye-double-eyelid", label: "Double Eyelid", dimension: "eye-shape", description: "Defined upper-eyelid crease", promptHint: "double-eyelid eyes with a clearly defined upper crease" },
461
- { id: "eye-wide", label: "Wide", dimension: "eye-shape", description: "Wide, large eyes", promptHint: "wide, large eyes" },
462
- { id: "eye-narrow", label: "Narrow", dimension: "eye-shape", description: "Narrow, elongated eyes", promptHint: "narrow, elongated eyes" },
476
+ { id: "eye-almond", label: "Almond", dimension: "eye-shape", description: "Almond-shaped eyes", promptHint: "almond-shaped eyes", term: "almond-shaped eyes" },
477
+ { id: "eye-round", label: "Round", dimension: "eye-shape", description: "Wide, round eyes", promptHint: "wide round eyes", term: "wide round eyes" },
478
+ { id: "eye-monolid", label: "Monolid", dimension: "eye-shape", description: "No visible crease, smooth lid", promptHint: "monolid eyes with no visible crease", term: "monolid eyes" },
479
+ { id: "eye-double-eyelid", label: "Double Eyelid", dimension: "eye-shape", description: "Defined upper-eyelid crease", promptHint: "double-eyelid eyes with a clearly defined upper crease", term: "double-eyelid eyes" },
480
+ { id: "eye-wide", label: "Wide", dimension: "eye-shape", description: "Wide, large eyes", promptHint: "wide, large eyes", term: "wide large eyes" },
481
+ { id: "eye-narrow", label: "Narrow", dimension: "eye-shape", description: "Narrow, elongated eyes", promptHint: "narrow, elongated eyes", term: "narrow elongated eyes" },
463
482
 
464
483
  // -------------------- Eyelid Type (upper-lid trait) --------------------
465
484
  // `eye-hooded` / `eye-droopy` / `eye-deep-set` keep their original ids
466
485
  // (moved out of eye-shape) so legacy data still resolves the same hint.
467
486
  { id: "eyelid-standard", label: "Standard", dimension: "eyelid-type", description: "Standard upper eyelid", promptHint: "" },
468
- { id: "eye-hooded", label: "Hooded", dimension: "eyelid-type", description: "Upper lid partially covers the crease", promptHint: "hooded eyes with the upper lid partially covering the crease" },
469
- { id: "eye-droopy", label: "Droopy", dimension: "eyelid-type", description: "Upper lids sit low — soft, sleepy gaze", promptHint: "droopy eyes with the upper lids sitting low for a soft, sleepy gaze" },
470
- { id: "eye-deep-set", label: "Deep-set", dimension: "eyelid-type", description: "Set deeper into the socket", promptHint: "deep-set eyes" },
487
+ { id: "eye-hooded", label: "Hooded", dimension: "eyelid-type", description: "Upper lid partially covers the crease", promptHint: "hooded eyes with the upper lid partially covering the crease", term: "hooded eyes" },
488
+ { id: "eye-droopy", label: "Droopy", dimension: "eyelid-type", description: "Upper lids sit low — soft, sleepy gaze", promptHint: "droopy eyes with the upper lids sitting low for a soft, sleepy gaze", term: "droopy eyes" },
489
+ { id: "eye-deep-set", label: "Deep-set", dimension: "eyelid-type", description: "Set deeper into the socket", promptHint: "deep-set eyes", term: "deep-set eyes" },
471
490
 
472
491
  // -------------------- Canthal Tilt (outer-corner angle) --------------------
473
492
  { id: "canthal-neutral", label: "Neutral", dimension: "canthal-tilt", description: "Neutral canthal tilt", promptHint: "" },
474
- { id: "eye-upturned", label: "Upturned", dimension: "canthal-tilt", description: "Outer corners lift up (positive tilt)", promptHint: "upturned eyes with the outer corners lifted, positive canthal tilt" },
475
- { id: "eye-downturned", label: "Downturned", dimension: "canthal-tilt", description: "Outer corners angle down (negative tilt)", promptHint: "downturned eyes with the outer corners angled down, negative canthal tilt" },
493
+ { id: "eye-upturned", label: "Upturned", dimension: "canthal-tilt", description: "Outer corners lift up (positive tilt)", promptHint: "upturned eyes with the outer corners lifted, positive canthal tilt", term: "upturned eyes, positive canthal tilt" },
494
+ { id: "eye-downturned", label: "Downturned", dimension: "canthal-tilt", description: "Outer corners angle down (negative tilt)", promptHint: "downturned eyes with the outer corners angled down, negative canthal tilt", term: "downturned eyes, negative canthal tilt" },
476
495
 
477
496
  // -------------------- Eye Spacing (horizontal distance between eyes) --------------------
478
497
  { id: "eye-spacing-average", label: "Average", dimension: "eye-spacing", description: "Average eye spacing", promptHint: "" },
479
- { id: "eye-close-set", label: "Close-set", dimension: "eye-spacing", description: "Eyes set close together", promptHint: "close-set eyes set close together" },
480
- { id: "eye-wide-set", label: "Wide-set", dimension: "eye-spacing", description: "Eyes spaced widely apart", promptHint: "wide-set eyes spaced widely apart" },
498
+ { id: "eye-close-set", label: "Close-set", dimension: "eye-spacing", description: "Eyes set close together", promptHint: "close-set eyes set close together", term: "close-set eyes" },
499
+ { id: "eye-wide-set", label: "Wide-set", dimension: "eye-spacing", description: "Eyes spaced widely apart", promptHint: "wide-set eyes spaced widely apart", term: "wide-set eyes" },
481
500
 
482
501
  // -------------------- Eye Set / Brow Distance (vertical brow-to-eye gap) --------------------
483
502
  { id: "eyeset-average", label: "Average", dimension: "eye-set-brow", description: "Average brow-to-eye distance", promptHint: "" },
484
- { id: "eyeset-low", label: "Low-set", dimension: "eye-set-brow", description: "Little brow-to-eye distance (hunter eyes)", promptHint: "eyes set close beneath the brow with little brow-to-eye distance, hunter eyes" },
485
- { id: "eyeset-high", label: "High-set", dimension: "eye-set-brow", description: "Generous brow-to-eye distance (doe eyes)", promptHint: "eyes set well below the brow with generous brow-to-eye distance, doe eyes" },
503
+ { id: "eyeset-low", label: "Low-set", dimension: "eye-set-brow", description: "Little brow-to-eye distance (hunter eyes)", promptHint: "eyes set close beneath the brow with little brow-to-eye distance, hunter eyes", term: "low-set eyes with little brow-to-eye distance" },
504
+ { id: "eyeset-high", label: "High-set", dimension: "eye-set-brow", description: "Generous brow-to-eye distance (doe eyes)", promptHint: "eyes set well below the brow with generous brow-to-eye distance, doe eyes", term: "doe eyes, high-set beneath the brow" },
486
505
 
487
506
  // -------------------- Nose (bridge) --------------------
488
- { id: "nose-straight", label: "Straight", dimension: "nose", description: "Straight bridge", promptHint: "a straight nose" },
489
- { id: "nose-aquiline", label: "Aquiline", dimension: "nose", description: "Curved hooked bridge", promptHint: "an aquiline nose with a curved bridge" },
490
- { id: "nose-roman", label: "Roman", dimension: "nose", description: "Prominent bridge with slight bump", promptHint: "a Roman nose with a prominent bridge" },
491
- { id: "nose-snub", label: "Snub", dimension: "nose", description: "Short, slightly upturned", promptHint: "a snub nose, short and slightly upturned" },
492
- { id: "nose-button", label: "Button", dimension: "nose", description: "Small, rounded tip", promptHint: "a small button nose with a rounded tip" },
493
- { id: "nose-broad", label: "Broad", dimension: "nose", description: "Wide nostrils, broad bridge", promptHint: "a broad nose with wide nostrils" },
494
- { id: "nose-narrow", label: "Narrow", dimension: "nose", description: "Thin, narrow", promptHint: "a narrow thin nose" },
495
- { id: "nose-hooked", label: "Hooked", dimension: "nose", description: "Strongly curved hooked tip", promptHint: "a hooked nose with a strongly curved tip" },
507
+ { id: "nose-straight", label: "Straight", dimension: "nose", description: "Straight bridge", promptHint: "a straight nose", term: "straight nose" },
508
+ { id: "nose-aquiline", label: "Aquiline", dimension: "nose", description: "Curved hooked bridge", promptHint: "an aquiline nose with a curved bridge", term: "aquiline nose" },
509
+ { id: "nose-roman", label: "Roman", dimension: "nose", description: "Prominent bridge with slight bump", promptHint: "a Roman nose with a prominent bridge", term: "roman nose" },
510
+ { id: "nose-snub", label: "Snub", dimension: "nose", description: "Short, slightly upturned", promptHint: "a snub nose, short and slightly upturned", term: "snub nose" },
511
+ { id: "nose-button", label: "Button", dimension: "nose", description: "Small, rounded tip", promptHint: "a small button nose with a rounded tip", term: "button nose" },
512
+ { id: "nose-broad", label: "Broad", dimension: "nose", description: "Wide nostrils, broad bridge", promptHint: "a broad nose with wide nostrils", term: "broad nose" },
513
+ { id: "nose-narrow", label: "Narrow", dimension: "nose", description: "Thin, narrow", promptHint: "a narrow thin nose", term: "narrow nose" },
514
+ { id: "nose-hooked", label: "Hooked", dimension: "nose", description: "Strongly curved hooked tip", promptHint: "a hooked nose with a strongly curved tip", term: "hooked nose" },
496
515
 
497
516
  // -------------------- Nose Tip (rotation / shape of the tip) --------------------
498
517
  { id: "nose-tip-natural", label: "Natural", dimension: "nose-tip", description: "Natural nose tip (no emphasis)", promptHint: "" },
499
- { id: "nose-tip-refined", label: "Refined", dimension: "nose-tip", description: "Refined, narrow tip", promptHint: "a refined, narrow nose tip" },
500
- { id: "nose-tip-upturned", label: "Upturned", dimension: "nose-tip", description: "Slightly upturned tip", promptHint: "a slightly upturned nose tip" },
501
- { id: "nose-tip-rounded", label: "Rounded", dimension: "nose-tip", description: "Soft, rounded tip", promptHint: "a soft, rounded nose tip" },
502
- { id: "nose-tip-drooping", label: "Drooping", dimension: "nose-tip", description: "Slightly drooping, downward tip", promptHint: "a slightly drooping, downward-pointing nose tip" },
518
+ { id: "nose-tip-refined", label: "Refined", dimension: "nose-tip", description: "Refined, narrow tip", promptHint: "a refined, narrow nose tip", term: "refined narrow nose tip" },
519
+ { id: "nose-tip-upturned", label: "Upturned", dimension: "nose-tip", description: "Slightly upturned tip", promptHint: "a slightly upturned nose tip", term: "upturned nose tip" },
520
+ { id: "nose-tip-rounded", label: "Rounded", dimension: "nose-tip", description: "Soft, rounded tip", promptHint: "a soft, rounded nose tip", term: "rounded nose tip" },
521
+ { id: "nose-tip-drooping", label: "Drooping", dimension: "nose-tip", description: "Slightly drooping, downward tip", promptHint: "a slightly drooping, downward-pointing nose tip", term: "drooping nose tip" },
503
522
 
504
523
  // -------------------- Lip Fullness --------------------
505
524
  // `lips-thin` / `lips-medium` / `lips-full` keep their original ids (moved
506
525
  // out of the old combined `lips` dimension) so legacy data resolves the same.
507
- { id: "lips-thin", label: "Thin", dimension: "lip-fullness", description: "Thin lips", promptHint: "thin lips" },
508
- { id: "lips-medium", label: "Medium", dimension: "lip-fullness", description: "Average fullness", promptHint: "medium lips of average fullness" },
509
- { id: "lips-full", label: "Full", dimension: "lip-fullness", description: "Full plump lips", promptHint: "full plump lips" },
510
- { id: "lips-full-lower", label: "Full Lower Lip", dimension: "lip-fullness", description: "Full lips with a fuller lower lip", promptHint: "full lips with a noticeably fuller lower lip" },
526
+ { id: "lips-thin", label: "Thin", dimension: "lip-fullness", description: "Thin lips", promptHint: "thin lips", term: "thin lips" },
527
+ { id: "lips-medium", label: "Medium", dimension: "lip-fullness", description: "Average fullness", promptHint: "medium lips of average fullness", term: "medium lips" },
528
+ { id: "lips-full", label: "Full", dimension: "lip-fullness", description: "Full plump lips", promptHint: "full plump lips", term: "full plump lips" },
529
+ { id: "lips-full-lower", label: "Full Lower Lip", dimension: "lip-fullness", description: "Full lips with a fuller lower lip", promptHint: "full lips with a noticeably fuller lower lip", term: "full lips with a fuller lower lip" },
511
530
 
512
531
  // -------------------- Lip Shape --------------------
513
532
  { id: "lips-natural", label: "Natural", dimension: "lip-shape", description: "Natural lip shape", promptHint: "" },
514
- { id: "lips-cupids-bow", label: "Cupid's Bow", dimension: "lip-shape", description: "Pronounced cupid's bow on the upper lip", promptHint: "a pronounced cupid's bow on the upper lip" },
515
- { id: "lips-wide", label: "Wide", dimension: "lip-shape", description: "Wide mouth shape", promptHint: "a wide mouth" },
516
- { id: "lips-heart", label: "Heart", dimension: "lip-shape", description: "Heart-shaped lips with a defined cupid's bow", promptHint: "heart-shaped lips with a defined cupid's bow" },
517
- { id: "lips-small", label: "Small", dimension: "lip-shape", description: "Petite mouth", promptHint: "a small petite mouth" },
533
+ { id: "lips-cupids-bow", label: "Cupid's Bow", dimension: "lip-shape", description: "Pronounced cupid's bow on the upper lip", promptHint: "a pronounced cupid's bow on the upper lip", term: "pronounced cupid's bow lips" },
534
+ { id: "lips-wide", label: "Wide", dimension: "lip-shape", description: "Wide mouth shape", promptHint: "a wide mouth", term: "wide mouth" },
535
+ { id: "lips-heart", label: "Heart", dimension: "lip-shape", description: "Heart-shaped lips with a defined cupid's bow", promptHint: "heart-shaped lips with a defined cupid's bow", term: "heart-shaped lips" },
536
+ { id: "lips-small", label: "Small", dimension: "lip-shape", description: "Petite mouth", promptHint: "a small petite mouth", term: "small petite mouth" },
518
537
 
519
538
  // -------------------- Lip State (what the lips are doing / wearing) --------------------
520
- { id: "lip-state-chapped", label: "Chapped", dimension: "lip-state", description: "Cracked, dry, weather-worn lips", promptHint: "with chapped, cracked, weather-worn dry lips" },
521
- { id: "lip-state-glossy", label: "Glossy", dimension: "lip-state", description: "High-shine, wet-look lips", promptHint: "with high-shine glossy wet-look lips" },
522
- { id: "lip-state-bare", label: "Bare", dimension: "lip-state", description: "Natural, untreated, no makeup", promptHint: "with bare, natural, untreated lips" },
523
- { id: "lip-state-bold-red", label: "Bold Red", dimension: "lip-state", description: "Saturated red lipstick statement", promptHint: "with a bold, saturated red lipstick statement" },
524
- { id: "lip-state-bitten", label: "Bitten", dimension: "lip-state", description: "Slight playful lip-bite, lower lip caught", promptHint: "playfully biting the lower lip" },
525
- { id: "lip-state-parted", label: "Parted", dimension: "lip-state", description: "Lips slightly parted, breath of air", promptHint: "with lips slightly parted, taking a soft breath" },
526
- { id: "lip-state-pursed", label: "Pursed", dimension: "lip-state", description: "Lips pressed and pushed forward", promptHint: "with lips pursed, pressed and pushed forward" },
527
- { id: "lip-state-bold-black", label: "Bold Black", dimension: "lip-state", description: "Saturated black lipstick statement (goth / avant-garde)", promptHint: "with a bold, saturated black lipstick statement, goth / avant-garde" },
528
- { id: "lip-state-burgundy", label: "Burgundy", dimension: "lip-state", description: "Deep wine-red lipstick", promptHint: "with deep wine-red burgundy lipstick" },
529
- { id: "lip-state-plum", label: "Plum", dimension: "lip-state", description: "Dark purple-toned lipstick", promptHint: "with dark purple-toned plum lipstick" },
530
- { id: "lip-state-mauve", label: "Mauve", dimension: "lip-state", description: "Muted mauve / dusty-pink lipstick", promptHint: "with muted mauve, dusty-pink lipstick" },
531
- { id: "lip-state-pouting", label: "Pouting", dimension: "lip-state", description: "Full pout", promptHint: "with a full pouting expression" },
539
+ { id: "lip-state-chapped", label: "Chapped", dimension: "lip-state", description: "Cracked, dry, weather-worn lips", promptHint: "with chapped, cracked, weather-worn dry lips", term: "chapped dry lips" },
540
+ { id: "lip-state-glossy", label: "Glossy", dimension: "lip-state", description: "High-shine, wet-look lips", promptHint: "with high-shine glossy wet-look lips", term: "glossy wet-look lips" },
541
+ { id: "lip-state-bare", label: "Bare", dimension: "lip-state", description: "Natural, untreated, no makeup", promptHint: "with bare, natural, untreated lips", term: "bare natural lips" },
542
+ { id: "lip-state-bold-red", label: "Bold Red", dimension: "lip-state", description: "Saturated red lipstick statement", promptHint: "with a bold, saturated red lipstick statement", term: "bold red lipstick" },
543
+ { id: "lip-state-bitten", label: "Bitten", dimension: "lip-state", description: "Slight playful lip-bite, lower lip caught", promptHint: "playfully biting the lower lip", term: "biting the lower lip" },
544
+ { id: "lip-state-parted", label: "Parted", dimension: "lip-state", description: "Lips slightly parted, breath of air", promptHint: "with lips slightly parted, taking a soft breath", term: "lips slightly parted" },
545
+ { id: "lip-state-pursed", label: "Pursed", dimension: "lip-state", description: "Lips pressed and pushed forward", promptHint: "with lips pursed, pressed and pushed forward", term: "pursed lips" },
546
+ { id: "lip-state-bold-black", label: "Bold Black", dimension: "lip-state", description: "Saturated black lipstick statement (goth / avant-garde)", promptHint: "with a bold, saturated black lipstick statement, goth / avant-garde", term: "bold black lipstick" },
547
+ { id: "lip-state-burgundy", label: "Burgundy", dimension: "lip-state", description: "Deep wine-red lipstick", promptHint: "with deep wine-red burgundy lipstick", term: "burgundy lipstick" },
548
+ { id: "lip-state-plum", label: "Plum", dimension: "lip-state", description: "Dark purple-toned lipstick", promptHint: "with dark purple-toned plum lipstick", term: "plum lipstick" },
549
+ { id: "lip-state-mauve", label: "Mauve", dimension: "lip-state", description: "Muted mauve / dusty-pink lipstick", promptHint: "with muted mauve, dusty-pink lipstick", term: "mauve lipstick" },
550
+ { id: "lip-state-pouting", label: "Pouting", dimension: "lip-state", description: "Full pout", promptHint: "with a full pouting expression", term: "full pouting expression" },
532
551
 
533
552
  // -------------------- Hair Color --------------------
534
553
  // Blonde family (light → warm → cool)
535
- { id: "hair-platinum", label: "Platinum", dimension: "hair-color", description: "Very pale, icy platinum", promptHint: "platinum blonde hair, very pale and icy" },
536
- { id: "hair-creamy", label: "Creamy", dimension: "hair-color", description: "Warm creamy / vanilla blonde", promptHint: "creamy vanilla blonde hair" },
537
- { id: "hair-blonde", label: "Blonde", dimension: "hair-color", description: "Classic blonde hair", promptHint: "blonde hair" },
538
- { id: "hair-honey", label: "Honey", dimension: "hair-color", description: "Warm honey-gold blonde", promptHint: "honey-gold blonde hair with warm golden tones" },
539
- { id: "hair-strawberry", label: "Strawberry Blonde", dimension: "hair-color", description: "Blonde with pinkish-red tone", promptHint: "strawberry blonde hair with a pinkish-red tint" },
540
- { id: "hair-ash-blonde", label: "Ash Blonde", dimension: "hair-color", description: "Cool, ashy blonde", promptHint: "ash blonde hair with cool, muted tones" },
554
+ { id: "hair-platinum", label: "Platinum", dimension: "hair-color", description: "Very pale, icy platinum", promptHint: "platinum blonde hair, very pale and icy", term: "platinum blonde hair" },
555
+ { id: "hair-creamy", label: "Creamy", dimension: "hair-color", description: "Warm creamy / vanilla blonde", promptHint: "creamy vanilla blonde hair", term: "creamy vanilla blonde hair" },
556
+ { id: "hair-blonde", label: "Blonde", dimension: "hair-color", description: "Classic blonde hair", promptHint: "blonde hair", term: "blonde hair" },
557
+ { id: "hair-honey", label: "Honey", dimension: "hair-color", description: "Warm honey-gold blonde", promptHint: "honey-gold blonde hair with warm golden tones", term: "honey-gold blonde hair" },
558
+ { id: "hair-strawberry", label: "Strawberry Blonde", dimension: "hair-color", description: "Blonde with pinkish-red tone", promptHint: "strawberry blonde hair with a pinkish-red tint", term: "strawberry blonde hair" },
559
+ { id: "hair-ash-blonde", label: "Ash Blonde", dimension: "hair-color", description: "Cool, ashy blonde", promptHint: "ash blonde hair with cool, muted tones", term: "ash blonde hair" },
541
560
  // Red / warm family
542
- { id: "hair-ginger", label: "Ginger", dimension: "hair-color", description: "Bright ginger (reddish-orange)", promptHint: "bright ginger hair, reddish-orange" },
543
- { id: "hair-copper", label: "Copper", dimension: "hair-color", description: "Vibrant copper orange-red", promptHint: "vibrant copper hair with orange-red metallic shine" },
544
- { id: "hair-red", label: "Red", dimension: "hair-color", description: "Classic red hair", promptHint: "red hair" },
545
- { id: "hair-auburn", label: "Auburn", dimension: "hair-color", description: "Rich reddish-brown", promptHint: "auburn hair, rich reddish-brown" },
546
- { id: "hair-burgundy", label: "Burgundy", dimension: "hair-color", description: "Dark wine-red", promptHint: "burgundy hair, deep wine-red" },
561
+ { id: "hair-ginger", label: "Ginger", dimension: "hair-color", description: "Bright ginger (reddish-orange)", promptHint: "bright ginger hair, reddish-orange", term: "ginger hair" },
562
+ { id: "hair-copper", label: "Copper", dimension: "hair-color", description: "Vibrant copper orange-red", promptHint: "vibrant copper hair with orange-red metallic shine", term: "copper hair" },
563
+ { id: "hair-red", label: "Red", dimension: "hair-color", description: "Classic red hair", promptHint: "red hair", term: "red hair" },
564
+ { id: "hair-auburn", label: "Auburn", dimension: "hair-color", description: "Rich reddish-brown", promptHint: "auburn hair, rich reddish-brown", term: "auburn hair" },
565
+ { id: "hair-burgundy", label: "Burgundy", dimension: "hair-color", description: "Dark wine-red", promptHint: "burgundy hair, deep wine-red", term: "burgundy hair" },
547
566
  // Brown family (light → dark)
548
- { id: "hair-light-brown", label: "Light Brown", dimension: "hair-color", description: "Light brown hair", promptHint: "light brown hair" },
549
- { id: "hair-caramel", label: "Caramel", dimension: "hair-color", description: "Warm caramel brown", promptHint: "caramel brown hair with warm golden undertones" },
550
- { id: "hair-brown", label: "Brown", dimension: "hair-color", description: "Medium brown hair", promptHint: "brown hair" },
551
- { id: "hair-chestnut", label: "Chestnut", dimension: "hair-color", description: "Warm reddish-brown chestnut", promptHint: "chestnut brown hair with warm reddish undertones" },
552
- { id: "hair-chocolate", label: "Chocolate", dimension: "hair-color", description: "Rich dark chocolate brown", promptHint: "rich chocolate brown hair" },
553
- { id: "hair-dark-brown", label: "Dark Brown", dimension: "hair-color", description: "Dark brown hair", promptHint: "dark brown hair" },
567
+ { id: "hair-light-brown", label: "Light Brown", dimension: "hair-color", description: "Light brown hair", promptHint: "light brown hair", term: "light brown hair" },
568
+ { id: "hair-caramel", label: "Caramel", dimension: "hair-color", description: "Warm caramel brown", promptHint: "caramel brown hair with warm golden undertones", term: "caramel brown hair" },
569
+ { id: "hair-brown", label: "Brown", dimension: "hair-color", description: "Medium brown hair", promptHint: "brown hair", term: "brown hair" },
570
+ { id: "hair-chestnut", label: "Chestnut", dimension: "hair-color", description: "Warm reddish-brown chestnut", promptHint: "chestnut brown hair with warm reddish undertones", term: "chestnut brown hair" },
571
+ { id: "hair-chocolate", label: "Chocolate", dimension: "hair-color", description: "Rich dark chocolate brown", promptHint: "rich chocolate brown hair", term: "chocolate brown hair" },
572
+ { id: "hair-dark-brown", label: "Dark Brown", dimension: "hair-color", description: "Dark brown hair", promptHint: "dark brown hair", term: "dark brown hair" },
554
573
  // Black family
555
- { id: "hair-black", label: "Black", dimension: "hair-color", description: "Classic black hair", promptHint: "black hair" },
556
- { id: "hair-jet-black", label: "Jet Black", dimension: "hair-color", description: "Deep black with blue undertones", promptHint: "jet black hair with deep blue-black undertones and glossy shine" },
574
+ { id: "hair-black", label: "Black", dimension: "hair-color", description: "Classic black hair", promptHint: "black hair", term: "black hair" },
575
+ { id: "hair-jet-black", label: "Jet Black", dimension: "hair-color", description: "Deep black with blue undertones", promptHint: "jet black hair with deep blue-black undertones and glossy shine", term: "jet black hair" },
557
576
  // Gray / neutral
558
- { id: "hair-gray", label: "Gray", dimension: "hair-color", description: "Gray hair", promptHint: "gray hair" },
559
- { id: "hair-salt-pepper", label: "Salt & Pepper", dimension: "hair-color", description: "Mixed black and gray hair", promptHint: "salt-and-pepper hair" },
560
- { id: "hair-white", label: "White", dimension: "hair-color", description: "White hair", promptHint: "white hair" },
577
+ { id: "hair-gray", label: "Gray", dimension: "hair-color", description: "Gray hair", promptHint: "gray hair", term: "gray hair" },
578
+ { id: "hair-salt-pepper", label: "Salt & Pepper", dimension: "hair-color", description: "Mixed black and gray hair", promptHint: "salt-and-pepper hair", term: "salt-and-pepper hair" },
579
+ { id: "hair-white", label: "White", dimension: "hair-color", description: "White hair", promptHint: "white hair", term: "white hair" },
561
580
  // Silver / Metallic
562
- { id: "hair-silver", label: "Silver", dimension: "hair-color", description: "Bright metallic silver", promptHint: "bright metallic silver hair with a clean reflective sheen" },
563
- { id: "hair-rose-gold", label: "Rose Gold", dimension: "hair-color", description: "Soft pink-gold metallic", promptHint: "rose gold hair, soft pink-gold metallic warmth" },
581
+ { id: "hair-silver", label: "Silver", dimension: "hair-color", description: "Bright metallic silver", promptHint: "bright metallic silver hair with a clean reflective sheen", term: "metallic silver hair" },
582
+ { id: "hair-rose-gold", label: "Rose Gold", dimension: "hair-color", description: "Soft pink-gold metallic", promptHint: "rose gold hair, soft pink-gold metallic warmth", term: "rose gold hair" },
564
583
  // Dyed (catch-all + specific fantasy / cosplay colors)
565
- { id: "hair-dyed", label: "Colorful (any)", dimension: "hair-color", description: "Dyed vibrant colors — unspecified", promptHint: "vibrantly dyed colorful hair" },
566
- { id: "hair-blue", label: "Blue", dimension: "hair-color", description: "Bold blue dyed hair", promptHint: "bold blue dyed hair" },
567
- { id: "hair-pastel-blue", label: "Pastel Blue", dimension: "hair-color", description: "Soft pastel sky-blue", promptHint: "soft pastel sky-blue hair" },
568
- { id: "hair-teal", label: "Teal", dimension: "hair-color", description: "Saturated teal blue-green", promptHint: "saturated teal blue-green hair" },
569
- { id: "hair-mint", label: "Mint", dimension: "hair-color", description: "Pale mint green", promptHint: "pale mint-green hair" },
570
- { id: "hair-green", label: "Green", dimension: "hair-color", description: "Bold green dyed hair", promptHint: "bold green dyed hair" },
571
- { id: "hair-lavender", label: "Lavender", dimension: "hair-color", description: "Soft lavender violet", promptHint: "soft lavender violet hair" },
572
- { id: "hair-purple", label: "Purple", dimension: "hair-color", description: "Bold deep purple", promptHint: "bold deep purple dyed hair" },
573
- { id: "hair-magenta", label: "Magenta", dimension: "hair-color", description: "Vivid magenta pink-purple", promptHint: "vivid magenta pink-purple hair" },
574
- { id: "hair-pink", label: "Pink", dimension: "hair-color", description: "Bold pink dyed hair", promptHint: "bold pink dyed hair" },
575
- { id: "hair-pastel-pink", label: "Pastel Pink", dimension: "hair-color", description: "Soft pastel cotton-candy pink", promptHint: "soft pastel cotton-candy pink hair" },
576
- { id: "hair-peach", label: "Peach", dimension: "hair-color", description: "Warm peach blonde-pink", promptHint: "warm peach hair, blonde-pink with soft warmth" },
577
- { id: "hair-mermaid", label: "Mermaid", dimension: "hair-color", description: "Blue-green-purple ocean blend", promptHint: "mermaid hair blending blue, green, and purple in flowing waves" },
578
- { id: "hair-rainbow", label: "Rainbow", dimension: "hair-color", description: "Multi-color rainbow streaks", promptHint: "rainbow hair with streaks of multiple bright dyed colors" },
584
+ { id: "hair-dyed", label: "Colorful (any)", dimension: "hair-color", description: "Dyed vibrant colors — unspecified", promptHint: "vibrantly dyed colorful hair", term: "vibrantly dyed colorful hair" },
585
+ { id: "hair-blue", label: "Blue", dimension: "hair-color", description: "Bold blue dyed hair", promptHint: "bold blue dyed hair", term: "blue dyed hair" },
586
+ { id: "hair-pastel-blue", label: "Pastel Blue", dimension: "hair-color", description: "Soft pastel sky-blue", promptHint: "soft pastel sky-blue hair", term: "pastel sky-blue hair" },
587
+ { id: "hair-teal", label: "Teal", dimension: "hair-color", description: "Saturated teal blue-green", promptHint: "saturated teal blue-green hair", term: "teal hair" },
588
+ { id: "hair-mint", label: "Mint", dimension: "hair-color", description: "Pale mint green", promptHint: "pale mint-green hair", term: "mint green hair" },
589
+ { id: "hair-green", label: "Green", dimension: "hair-color", description: "Bold green dyed hair", promptHint: "bold green dyed hair", term: "green dyed hair" },
590
+ { id: "hair-lavender", label: "Lavender", dimension: "hair-color", description: "Soft lavender violet", promptHint: "soft lavender violet hair", term: "lavender hair" },
591
+ { id: "hair-purple", label: "Purple", dimension: "hair-color", description: "Bold deep purple", promptHint: "bold deep purple dyed hair", term: "purple dyed hair" },
592
+ { id: "hair-magenta", label: "Magenta", dimension: "hair-color", description: "Vivid magenta pink-purple", promptHint: "vivid magenta pink-purple hair", term: "magenta hair" },
593
+ { id: "hair-pink", label: "Pink", dimension: "hair-color", description: "Bold pink dyed hair", promptHint: "bold pink dyed hair", term: "pink dyed hair" },
594
+ { id: "hair-pastel-pink", label: "Pastel Pink", dimension: "hair-color", description: "Soft pastel cotton-candy pink", promptHint: "soft pastel cotton-candy pink hair", term: "pastel pink hair" },
595
+ { id: "hair-peach", label: "Peach", dimension: "hair-color", description: "Warm peach blonde-pink", promptHint: "warm peach hair, blonde-pink with soft warmth", term: "peach hair" },
596
+ { id: "hair-mermaid", label: "Mermaid", dimension: "hair-color", description: "Blue-green-purple ocean blend", promptHint: "mermaid hair blending blue, green, and purple in flowing waves", term: "mermaid hair" },
597
+ { id: "hair-rainbow", label: "Rainbow", dimension: "hair-color", description: "Multi-color rainbow streaks", promptHint: "rainbow hair with streaks of multiple bright dyed colors", term: "rainbow hair" },
579
598
 
580
599
  // -------------------- Hair Style (length + texture) --------------------
581
600
  // -------------------- Hair Base (natural texture + length) --------------------
582
601
  // Cut/styling choices live in Styling.hair-cut (separate dimension); this is
583
602
  // about what hair the character has, not what was done to it today.
584
- { id: "base-bald", label: "Bald / Shaved", dimension: "hair-base", description: "Bald or fully shaved head", promptHint: "a shaved bald head" },
585
- { id: "base-buzz", label: "Buzz", dimension: "hair-base", description: "Very short cropped hair", promptHint: "very short buzzed hair" },
586
- { id: "base-short-straight", label: "Short Straight", dimension: "hair-base", description: "Short, straight texture", promptHint: "short straight hair" },
587
- { id: "base-short-wavy", label: "Short Wavy", dimension: "hair-base", description: "Short, wavy texture", promptHint: "short wavy hair" },
588
- { id: "base-short-curly", label: "Short Curly", dimension: "hair-base", description: "Short, curly texture", promptHint: "short curly hair" },
589
- { id: "base-short-coily", label: "Short Coily", dimension: "hair-base", description: "Short, tightly coiled texture", promptHint: "short tightly coiled hair" },
590
- { id: "base-medium-straight", label: "Medium Straight", dimension: "hair-base", description: "Shoulder-length, straight", promptHint: "medium-length straight hair" },
591
- { id: "base-medium-wavy", label: "Medium Wavy", dimension: "hair-base", description: "Shoulder-length, wavy", promptHint: "medium-length wavy hair" },
592
- { id: "base-medium-curly", label: "Medium Curly", dimension: "hair-base", description: "Shoulder-length, curly", promptHint: "medium-length curly hair" },
593
- { id: "base-medium-coily", label: "Medium Coily", dimension: "hair-base", description: "Shoulder-length, tightly coiled", promptHint: "medium-length tightly coiled hair" },
594
- { id: "base-long-straight", label: "Long Straight", dimension: "hair-base", description: "Mid-back, straight", promptHint: "long straight hair" },
595
- { id: "base-long-wavy", label: "Long Wavy", dimension: "hair-base", description: "Mid-back, wavy", promptHint: "long wavy hair" },
596
- { id: "base-long-curly", label: "Long Curly", dimension: "hair-base", description: "Mid-back, curly", promptHint: "long curly hair" },
597
- { id: "base-long-coily", label: "Long Coily", dimension: "hair-base", description: "Mid-back, tightly coiled", promptHint: "long tightly coiled hair" },
598
- { id: "base-very-long-straight", label: "Very Long Straight", dimension: "hair-base", description: "Waist-length, straight", promptHint: "very long straight hair down to the waist" },
599
- { id: "base-very-long-wavy", label: "Very Long Wavy", dimension: "hair-base", description: "Waist-length, wavy", promptHint: "very long wavy hair down to the waist" },
600
- { id: "base-very-long-curly", label: "Very Long Curly", dimension: "hair-base", description: "Waist-length, curly", promptHint: "very long curly hair down to the waist" },
601
- { id: "base-afro", label: "Afro", dimension: "hair-base", description: "Voluminous rounded afro", promptHint: "voluminous afro hair" },
602
- { id: "base-thinning", label: "Thinning / Receding", dimension: "hair-base", description: "Visibly thinning or receding hairline", promptHint: "thinning hair with a receding hairline" },
603
- { id: "base-wet", label: "Wet", dimension: "hair-base", description: "Wet, slick hair", promptHint: "wet, slick hair" },
603
+ { id: "base-bald", label: "Bald / Shaved", dimension: "hair-base", description: "Bald or fully shaved head", promptHint: "a shaved bald head", term: "shaved bald head" },
604
+ { id: "base-buzz", label: "Buzz", dimension: "hair-base", description: "Very short cropped hair", promptHint: "very short buzzed hair", term: "buzzed hair" },
605
+ { id: "base-short-straight", label: "Short Straight", dimension: "hair-base", description: "Short, straight texture", promptHint: "short straight hair", term: "short straight hair" },
606
+ { id: "base-short-wavy", label: "Short Wavy", dimension: "hair-base", description: "Short, wavy texture", promptHint: "short wavy hair", term: "short wavy hair" },
607
+ { id: "base-short-curly", label: "Short Curly", dimension: "hair-base", description: "Short, curly texture", promptHint: "short curly hair", term: "short curly hair" },
608
+ { id: "base-short-coily", label: "Short Coily", dimension: "hair-base", description: "Short, tightly coiled texture", promptHint: "short tightly coiled hair", term: "short coily hair" },
609
+ { id: "base-medium-straight", label: "Medium Straight", dimension: "hair-base", description: "Shoulder-length, straight", promptHint: "medium-length straight hair", term: "medium-length straight hair" },
610
+ { id: "base-medium-wavy", label: "Medium Wavy", dimension: "hair-base", description: "Shoulder-length, wavy", promptHint: "medium-length wavy hair", term: "medium-length wavy hair" },
611
+ { id: "base-medium-curly", label: "Medium Curly", dimension: "hair-base", description: "Shoulder-length, curly", promptHint: "medium-length curly hair", term: "medium-length curly hair" },
612
+ { id: "base-medium-coily", label: "Medium Coily", dimension: "hair-base", description: "Shoulder-length, tightly coiled", promptHint: "medium-length tightly coiled hair", term: "medium-length coily hair" },
613
+ { id: "base-long-straight", label: "Long Straight", dimension: "hair-base", description: "Mid-back, straight", promptHint: "long straight hair", term: "long straight hair" },
614
+ { id: "base-long-wavy", label: "Long Wavy", dimension: "hair-base", description: "Mid-back, wavy", promptHint: "long wavy hair", term: "long wavy hair" },
615
+ { id: "base-long-curly", label: "Long Curly", dimension: "hair-base", description: "Mid-back, curly", promptHint: "long curly hair", term: "long curly hair" },
616
+ { id: "base-long-coily", label: "Long Coily", dimension: "hair-base", description: "Mid-back, tightly coiled", promptHint: "long tightly coiled hair", term: "long coily hair" },
617
+ { id: "base-very-long-straight", label: "Very Long Straight", dimension: "hair-base", description: "Waist-length, straight", promptHint: "very long straight hair down to the waist", term: "very long straight hair" },
618
+ { id: "base-very-long-wavy", label: "Very Long Wavy", dimension: "hair-base", description: "Waist-length, wavy", promptHint: "very long wavy hair down to the waist", term: "very long wavy hair" },
619
+ { id: "base-very-long-curly", label: "Very Long Curly", dimension: "hair-base", description: "Waist-length, curly", promptHint: "very long curly hair down to the waist", term: "very long curly hair" },
620
+ { id: "base-afro", label: "Afro", dimension: "hair-base", description: "Voluminous rounded afro", promptHint: "voluminous afro hair", term: "voluminous afro hair" },
621
+ { id: "base-thinning", label: "Thinning / Receding", dimension: "hair-base", description: "Visibly thinning or receding hairline", promptHint: "thinning hair with a receding hairline", term: "thinning hair with a receding hairline" },
622
+ { id: "base-wet", label: "Wet", dimension: "hair-base", description: "Wet, slick hair", promptHint: "wet, slick hair", term: "wet slick hair" },
604
623
 
605
624
  // -------------------- Eyebrows --------------------
606
- { id: "brows-natural", label: "Natural", dimension: "eyebrows", description: "Natural, untouched brows", promptHint: "natural eyebrows" },
607
- { id: "brows-thick", label: "Thick / Bushy", dimension: "eyebrows", description: "Thick, bushy brows", promptHint: "thick bushy eyebrows" },
608
- { id: "brows-thin", label: "Thin / Pencil", dimension: "eyebrows", description: "Thin, pencil-shaped brows", promptHint: "thin pencil-shaped eyebrows" },
609
- { id: "brows-arched", label: "Arched", dimension: "eyebrows", description: "Strongly arched, dramatic curve", promptHint: "strongly arched eyebrows with a dramatic curve" },
610
- { id: "brows-straight", label: "Straight", dimension: "eyebrows", description: "Flat, horizontal brows", promptHint: "flat straight eyebrows" },
611
- { id: "brows-bold", label: "Bold", dimension: "eyebrows", description: "Defined, dark, full brows", promptHint: "bold defined dark full eyebrows" },
612
- { id: "brows-soft", label: "Soft / Faded", dimension: "eyebrows", description: "Soft, light, faded brows", promptHint: "soft, light, faded eyebrows" },
613
- { id: "brows-microbladed", label: "Microbladed", dimension: "eyebrows", description: "Drawn / microbladed crisp shape", promptHint: "microbladed crisply drawn eyebrows" },
614
- { id: "brows-tinted", label: "Tinted", dimension: "eyebrows", description: "Tinted a different color than hair", promptHint: "eyebrows tinted a different color from the hair" },
615
- { id: "brows-unibrow", label: "Unibrow", dimension: "eyebrows", description: "Connected unibrow", promptHint: "a connected unibrow" },
625
+ { id: "brows-natural", label: "Natural", dimension: "eyebrows", description: "Natural, untouched brows", promptHint: "natural eyebrows", term: "natural eyebrows" },
626
+ { id: "brows-thick", label: "Thick / Bushy", dimension: "eyebrows", description: "Thick, bushy brows", promptHint: "thick bushy eyebrows", term: "thick bushy eyebrows" },
627
+ { id: "brows-thin", label: "Thin / Pencil", dimension: "eyebrows", description: "Thin, pencil-shaped brows", promptHint: "thin pencil-shaped eyebrows", term: "thin pencil eyebrows" },
628
+ { id: "brows-arched", label: "Arched", dimension: "eyebrows", description: "Strongly arched, dramatic curve", promptHint: "strongly arched eyebrows with a dramatic curve", term: "strongly arched eyebrows" },
629
+ { id: "brows-straight", label: "Straight", dimension: "eyebrows", description: "Flat, horizontal brows", promptHint: "flat straight eyebrows", term: "flat straight eyebrows" },
630
+ { id: "brows-bold", label: "Bold", dimension: "eyebrows", description: "Defined, dark, full brows", promptHint: "bold defined dark full eyebrows", term: "bold dark full eyebrows" },
631
+ { id: "brows-soft", label: "Soft / Faded", dimension: "eyebrows", description: "Soft, light, faded brows", promptHint: "soft, light, faded eyebrows", term: "soft faded eyebrows" },
632
+ { id: "brows-microbladed", label: "Microbladed", dimension: "eyebrows", description: "Drawn / microbladed crisp shape", promptHint: "microbladed crisply drawn eyebrows", term: "microbladed eyebrows" },
633
+ { id: "brows-tinted", label: "Tinted", dimension: "eyebrows", description: "Tinted a different color than hair", promptHint: "eyebrows tinted a different color from the hair", term: "tinted eyebrows" },
634
+ { id: "brows-unibrow", label: "Unibrow", dimension: "eyebrows", description: "Connected unibrow", promptHint: "a connected unibrow", term: "connected unibrow" },
616
635
 
617
636
  // -------------------- Skin Tone --------------------
618
- { id: "skin-very-fair", label: "Very Fair", dimension: "skin-tone", description: "Very fair / pale skin", promptHint: "very fair pale skin" },
619
- { id: "skin-fair", label: "Fair", dimension: "skin-tone", description: "Fair skin", promptHint: "fair skin" },
620
- { id: "skin-medium", label: "Medium", dimension: "skin-tone", description: "Medium skin tone", promptHint: "medium skin tone" },
621
- { id: "skin-olive", label: "Olive", dimension: "skin-tone", description: "Olive skin", promptHint: "olive skin" },
622
- { id: "skin-tan", label: "Tan", dimension: "skin-tone", description: "Tan skin", promptHint: "tan skin" },
623
- { id: "skin-brown", label: "Brown", dimension: "skin-tone", description: "Brown skin", promptHint: "brown skin" },
624
- { id: "skin-dark", label: "Dark", dimension: "skin-tone", description: "Dark skin", promptHint: "dark skin" },
625
- { id: "skin-very-dark", label: "Very Dark / Ebony", dimension: "skin-tone", description: "Very dark, ebony skin tone (deepest end of the scale)", promptHint: "very dark ebony skin, the deepest skin tone" },
637
+ { id: "skin-very-fair", label: "Very Fair", dimension: "skin-tone", description: "Very fair / pale skin", promptHint: "very fair pale skin", term: "very fair pale skin" },
638
+ { id: "skin-fair", label: "Fair", dimension: "skin-tone", description: "Fair skin", promptHint: "fair skin", term: "fair skin" },
639
+ { id: "skin-medium", label: "Medium", dimension: "skin-tone", description: "Medium skin tone", promptHint: "medium skin tone", term: "medium skin tone" },
640
+ { id: "skin-olive", label: "Olive", dimension: "skin-tone", description: "Olive skin", promptHint: "olive skin", term: "olive skin" },
641
+ { id: "skin-tan", label: "Tan", dimension: "skin-tone", description: "Tan skin", promptHint: "tan skin", term: "tan skin" },
642
+ { id: "skin-brown", label: "Brown", dimension: "skin-tone", description: "Brown skin", promptHint: "brown skin", term: "brown skin" },
643
+ { id: "skin-dark", label: "Dark", dimension: "skin-tone", description: "Dark skin", promptHint: "dark skin", term: "dark skin" },
644
+ { id: "skin-very-dark", label: "Very Dark / Ebony", dimension: "skin-tone", description: "Very dark, ebony skin tone (deepest end of the scale)", promptHint: "very dark ebony skin, the deepest skin tone", term: "very dark ebony skin" },
626
645
 
627
646
  // -------------------- Eye Color --------------------
628
- { id: "eyes-brown", label: "Brown", dimension: "eye-color", description: "Brown eyes", promptHint: "brown eyes" },
629
- { id: "eyes-blue", label: "Blue", dimension: "eye-color", description: "Blue eyes", promptHint: "blue eyes" },
630
- { id: "eyes-green", label: "Green", dimension: "eye-color", description: "Green eyes", promptHint: "green eyes" },
631
- { id: "eyes-hazel", label: "Hazel", dimension: "eye-color", description: "Hazel eyes", promptHint: "hazel eyes" },
632
- { id: "eyes-gray", label: "Gray", dimension: "eye-color", description: "Gray eyes", promptHint: "gray eyes" },
633
- { id: "eyes-amber", label: "Amber", dimension: "eye-color", description: "Amber eyes", promptHint: "amber eyes" },
634
- { id: "eyes-violet", label: "Violet", dimension: "eye-color", description: "Rare violet eyes (Liz Taylor)", promptHint: "rare violet eyes with a deep purple iris" },
635
- { id: "eyes-gold", label: "Gold", dimension: "eye-color", description: "Bright gold iris", promptHint: "bright gold eyes with luminous metallic warmth" },
636
- { id: "eyes-silver", label: "Silver", dimension: "eye-color", description: "Pale silver-gray iris", promptHint: "pale silver eyes with a luminous reflective sheen" },
637
- { id: "eyes-red", label: "Red", dimension: "eye-color", description: "Red iris (albinism / fantasy)", promptHint: "red eyes, albinism or fantasy red iris" },
638
- { id: "eyes-pink", label: "Pink", dimension: "eye-color", description: "Soft pink iris (albino / fantasy)", promptHint: "soft pink eyes, albino or fantasy pink iris" },
639
- { id: "eyes-turquoise", label: "Turquoise", dimension: "eye-color", description: "Vivid turquoise blue-green iris", promptHint: "vivid turquoise blue-green eyes" },
640
- { id: "eyes-black", label: "Black", dimension: "eye-color", description: "Truly black iris (deeper than brown)", promptHint: "jet-black eyes with a truly black iris, deeper than brown" },
647
+ { id: "eyes-brown", label: "Brown", dimension: "eye-color", description: "Brown eyes", promptHint: "brown eyes", term: "brown eyes" },
648
+ { id: "eyes-blue", label: "Blue", dimension: "eye-color", description: "Blue eyes", promptHint: "blue eyes", term: "blue eyes" },
649
+ { id: "eyes-green", label: "Green", dimension: "eye-color", description: "Green eyes", promptHint: "green eyes", term: "green eyes" },
650
+ { id: "eyes-hazel", label: "Hazel", dimension: "eye-color", description: "Hazel eyes", promptHint: "hazel eyes", term: "hazel eyes" },
651
+ { id: "eyes-gray", label: "Gray", dimension: "eye-color", description: "Gray eyes", promptHint: "gray eyes", term: "gray eyes" },
652
+ { id: "eyes-amber", label: "Amber", dimension: "eye-color", description: "Amber eyes", promptHint: "amber eyes", term: "amber eyes" },
653
+ { id: "eyes-violet", label: "Violet", dimension: "eye-color", description: "Rare violet eyes (Liz Taylor)", promptHint: "rare violet eyes with a deep purple iris", term: "violet eyes" },
654
+ { id: "eyes-gold", label: "Gold", dimension: "eye-color", description: "Bright gold iris", promptHint: "bright gold eyes with luminous metallic warmth", term: "gold eyes" },
655
+ { id: "eyes-silver", label: "Silver", dimension: "eye-color", description: "Pale silver-gray iris", promptHint: "pale silver eyes with a luminous reflective sheen", term: "silver eyes" },
656
+ { id: "eyes-red", label: "Red", dimension: "eye-color", description: "Red iris (albinism / fantasy)", promptHint: "red eyes, albinism or fantasy red iris", term: "red eyes" },
657
+ { id: "eyes-pink", label: "Pink", dimension: "eye-color", description: "Soft pink iris (albino / fantasy)", promptHint: "soft pink eyes, albino or fantasy pink iris", term: "pink eyes" },
658
+ { id: "eyes-turquoise", label: "Turquoise", dimension: "eye-color", description: "Vivid turquoise blue-green iris", promptHint: "vivid turquoise blue-green eyes", term: "turquoise eyes" },
659
+ { id: "eyes-black", label: "Black", dimension: "eye-color", description: "Truly black iris (deeper than brown)", promptHint: "jet-black eyes with a truly black iris, deeper than brown", term: "jet-black eyes" },
641
660
 
642
661
  // -------------------- Eye State (what the eyes are doing / where they look) --------------------
643
- { id: "eye-state-closed", label: "Closed", dimension: "eye-state", description: "Eyes fully closed, peaceful", promptHint: "with eyes fully closed in a peaceful expression" },
644
- { id: "eye-state-half-lidded", label: "Half-lidded", dimension: "eye-state", description: "Heavy-lidded sleepy gaze", promptHint: "with heavy half-lidded sleepy eyes" },
662
+ { id: "eye-state-closed", label: "Closed", dimension: "eye-state", description: "Eyes fully closed, peaceful", promptHint: "with eyes fully closed in a peaceful expression", term: "eyes fully closed" },
663
+ { id: "eye-state-half-lidded", label: "Half-lidded", dimension: "eye-state", description: "Heavy-lidded sleepy gaze", promptHint: "with heavy half-lidded sleepy eyes", term: "half-lidded sleepy eyes" },
645
664
  { id: "eye-state-wide-eyed", label: "Wide-eyed", dimension: "eye-state", description: "Eyes wide open, alert / surprised", promptHint: "with eyes wide open, alert and surprised" },
646
665
  { id: "eye-state-staring-camera", label: "Staring at Camera", dimension: "eye-state", description: "Direct unbroken eye contact with the lens", promptHint: "staring directly at the camera with unbroken eye contact" },
647
- { id: "eye-state-gazing-away", label: "Gazing Away", dimension: "eye-state", description: "Looking off-camera, contemplative", promptHint: "gazing off-camera with a contemplative expression" },
666
+ { id: "eye-state-gazing-away", label: "Gazing Away", dimension: "eye-state", description: "Looking off-camera, contemplative", promptHint: "gazing off-camera with a contemplative expression", term: "gazing off-camera" },
648
667
  { id: "eye-state-gazing-up", label: "Gazing Up", dimension: "eye-state", description: "Eyes raised toward something above", promptHint: "with eyes gazing upward toward something above" },
649
668
  { id: "eye-state-gazing-down", label: "Gazing Down", dimension: "eye-state", description: "Eyes downcast", promptHint: "with eyes downcast, gazing softly downward" },
650
- { id: "eye-state-glassy", label: "Glassy", dimension: "eye-state", description: "Eyes wet / tear-glazed", promptHint: "with glassy, tear-glazed wet eyes" },
669
+ { id: "eye-state-glassy", label: "Glassy", dimension: "eye-state", description: "Eyes wet / tear-glazed", promptHint: "with glassy, tear-glazed wet eyes", term: "glassy tear-glazed eyes" },
651
670
 
652
671
  // -------------------- Facial Hair --------------------
653
672
  { id: "face-clean-shaven", label: "Clean-shaven", dimension: "facial-hair", description: "Clean-shaven face", promptHint: "clean-shaven" },
654
- { id: "face-stubble", label: "Stubble", dimension: "facial-hair", description: "Light stubble", promptHint: "light stubble" },
673
+ { id: "face-stubble", label: "Stubble", dimension: "facial-hair", description: "Light stubble", promptHint: "light stubble", term: "light stubble" },
655
674
  { id: "face-mustache", label: "Mustache", dimension: "facial-hair", description: "Mustache", promptHint: "a mustache" },
656
675
  { id: "face-goatee", label: "Goatee", dimension: "facial-hair", description: "Goatee", promptHint: "a goatee" },
657
- { id: "face-short-beard", label: "Short Beard", dimension: "facial-hair", description: "Short trimmed beard", promptHint: "a short trimmed beard" },
676
+ { id: "face-short-beard", label: "Short Beard", dimension: "facial-hair", description: "Short trimmed beard", promptHint: "a short trimmed beard", term: "short trimmed beard" },
658
677
  { id: "face-full-beard", label: "Full Beard", dimension: "facial-hair", description: "Thick full beard", promptHint: "a full beard" },
659
678
  { id: "face-five-oclock-shadow", label: "Five-O'Clock Shadow", dimension: "facial-hair", description: "Heavier daily growth — denser than light stubble", promptHint: "a five-o'clock shadow, daily growth heavier than light stubble" },
660
679
 
661
680
  // -------------------- Skin Texture --------------------
662
- { id: "texture-smooth", label: "Smooth", dimension: "skin-texture", description: "Flawless, silky smooth skin", promptHint: "with flawless, silky smooth skin" },
663
- { id: "texture-wrinkled", label: "Wrinkled", dimension: "skin-texture", description: "Aged, deeply lined skin", promptHint: "with deep wrinkles and aged skin texture" },
681
+ { id: "texture-smooth", label: "Smooth", dimension: "skin-texture", description: "Flawless, silky smooth skin", promptHint: "with flawless, silky smooth skin", term: "flawless smooth skin" },
682
+ { id: "texture-wrinkled", label: "Wrinkled", dimension: "skin-texture", description: "Aged, deeply lined skin", promptHint: "with deep wrinkles and aged skin texture", term: "deeply wrinkled aged skin" },
664
683
  { id: "texture-goosebumps", label: "Goosebumps", dimension: "skin-texture", description: "Raised goosebumps on skin", promptHint: "with goosebumps raised on the skin" },
665
- { id: "texture-dewy", label: "Dewy", dimension: "skin-texture", description: "Glowing, dewy fresh skin", promptHint: "with dewy, glowing skin and a fresh sheen" },
666
- { id: "texture-glistening", label: "Glistening", dimension: "skin-texture", description: "Sweat or oil sheen", promptHint: "with glistening skin, sweat or oil catching the light" },
667
- { id: "texture-weathered", label: "Weathered", dimension: "skin-texture", description: "Sun-aged rough skin", promptHint: "with weathered, sun-worn rough skin" },
668
- { id: "texture-porcelain", label: "Porcelain", dimension: "skin-texture", description: "Flawless near-translucent porcelain", promptHint: "with flawless, near-translucent porcelain skin" },
669
- { id: "texture-sun-kissed", label: "Sun-kissed", dimension: "skin-texture", description: "Warm tan with healthy glow", promptHint: "with sun-kissed skin, warmly tanned with a healthy glow" },
670
- { id: "texture-tanned", label: "Tanned", dimension: "skin-texture", description: "Deeply, evenly tanned skin", promptHint: "with deeply, evenly bronzed tanned skin" },
671
- { id: "texture-tan-lines", label: "Tan Lines", dimension: "skin-texture", description: "Visible tan lines from swimwear", promptHint: "with visible swimwear tan lines on the skin" },
672
- { id: "texture-freckled", label: "Freckled", dimension: "skin-texture", description: "Freckles across cheeks and nose", promptHint: "with visible freckles scattered across cheeks and the bridge of the nose" },
673
- { id: "texture-ruddy", label: "Ruddy", dimension: "skin-texture", description: "Pink-flushed cheeks and nose", promptHint: "with ruddy, warm pink-flushed cheeks and nose" },
674
- { id: "texture-ashen", label: "Ashen / Pale", dimension: "skin-texture", description: "Cool pale, near-bloodless undertone", promptHint: "with ashen, cool pale, near-bloodless skin" },
675
- { id: "texture-oily", label: "Oily / Shiny", dimension: "skin-texture", description: "Slight oil sheen on T-zone", promptHint: "with a slight oily sheen across the T-zone" },
676
- { id: "texture-matte", label: "Matte", dimension: "skin-texture", description: "Poreless matte finish", promptHint: "with a poreless, matte skin finish" },
677
- { id: "texture-blemished", label: "Blemished", dimension: "skin-texture", description: "Visible blemishes, real-skin imperfections", promptHint: "with visible blemishes and natural real-skin imperfections" },
678
- { id: "texture-baby-soft", label: "Baby-soft", dimension: "skin-texture", description: "Smooth, fine-pored youthful skin", promptHint: "with baby-soft, fine-pored, youthful smooth skin" },
679
- { id: "texture-shower-fresh-wet", label: "Shower-Fresh Wet", dimension: "skin-texture", description: "Just-out-of-shower wet skin with water beads", promptHint: "with just-out-of-the-shower wet skin, water beading on the surface and rolling in slow droplets down the curves of the body" },
680
- { id: "texture-acne-scarred", label: "Acne-scarred", dimension: "skin-texture", description: "Visible acne scarring (distinct from blemished — healed scar pattern)", promptHint: "with visible acne scarring, healed pitted-skin texture and uneven surface from past breakouts" },
684
+ { id: "texture-dewy", label: "Dewy", dimension: "skin-texture", description: "Glowing, dewy fresh skin", promptHint: "with dewy, glowing skin and a fresh sheen", term: "dewy glowing skin" },
685
+ { id: "texture-glistening", label: "Glistening", dimension: "skin-texture", description: "Sweat or oil sheen", promptHint: "with glistening skin, sweat or oil catching the light", term: "glistening skin" },
686
+ { id: "texture-weathered", label: "Weathered", dimension: "skin-texture", description: "Sun-aged rough skin", promptHint: "with weathered, sun-worn rough skin", term: "weathered sun-worn skin" },
687
+ { id: "texture-porcelain", label: "Porcelain", dimension: "skin-texture", description: "Flawless near-translucent porcelain", promptHint: "with flawless, near-translucent porcelain skin", term: "porcelain skin" },
688
+ { id: "texture-sun-kissed", label: "Sun-kissed", dimension: "skin-texture", description: "Warm tan with healthy glow", promptHint: "with sun-kissed skin, warmly tanned with a healthy glow", term: "sun-kissed skin" },
689
+ { id: "texture-tanned", label: "Tanned", dimension: "skin-texture", description: "Deeply, evenly tanned skin", promptHint: "with deeply, evenly bronzed tanned skin", term: "deeply tanned skin" },
690
+ { id: "texture-tan-lines", label: "Tan Lines", dimension: "skin-texture", description: "Visible tan lines from swimwear", promptHint: "with visible swimwear tan lines on the skin", term: "visible swimwear tan lines" },
691
+ { id: "texture-freckled", label: "Freckled", dimension: "skin-texture", description: "Freckles across cheeks and nose", promptHint: "with visible freckles scattered across cheeks and the bridge of the nose", term: "freckled skin" },
692
+ { id: "texture-ruddy", label: "Ruddy", dimension: "skin-texture", description: "Pink-flushed cheeks and nose", promptHint: "with ruddy, warm pink-flushed cheeks and nose", term: "ruddy flushed complexion" },
693
+ { id: "texture-ashen", label: "Ashen / Pale", dimension: "skin-texture", description: "Cool pale, near-bloodless undertone", promptHint: "with ashen, cool pale, near-bloodless skin", term: "ashen pale skin" },
694
+ { id: "texture-oily", label: "Oily / Shiny", dimension: "skin-texture", description: "Slight oil sheen on T-zone", promptHint: "with a slight oily sheen across the T-zone", term: "oily shiny skin" },
695
+ { id: "texture-matte", label: "Matte", dimension: "skin-texture", description: "Poreless matte finish", promptHint: "with a poreless, matte skin finish", term: "matte skin finish" },
696
+ { id: "texture-blemished", label: "Blemished", dimension: "skin-texture", description: "Visible blemishes, real-skin imperfections", promptHint: "with visible blemishes and natural real-skin imperfections", term: "blemished skin" },
697
+ { id: "texture-baby-soft", label: "Baby-soft", dimension: "skin-texture", description: "Smooth, fine-pored youthful skin", promptHint: "with baby-soft, fine-pored, youthful smooth skin", term: "baby-soft skin" },
698
+ { id: "texture-shower-fresh-wet", label: "Shower-Fresh Wet", dimension: "skin-texture", description: "Just-out-of-shower wet skin with water beads", promptHint: "with just-out-of-the-shower wet skin, water beading on the surface and rolling in slow droplets down the curves of the body", term: "shower-fresh wet skin" },
699
+ { id: "texture-acne-scarred", label: "Acne-scarred", dimension: "skin-texture", description: "Visible acne scarring (distinct from blemished — healed scar pattern)", promptHint: "with visible acne scarring, healed pitted-skin texture and uneven surface from past breakouts", term: "acne-scarred skin" },
681
700
 
682
701
  // -------------------- Distinctive Features --------------------
683
- { id: "feature-glasses", label: "Glasses", dimension: "distinctive-features", description: "Wears glasses", promptHint: "wearing glasses" },
702
+ { id: "feature-glasses", label: "Glasses", dimension: "distinctive-features", description: "Wears glasses", promptHint: "wearing glasses", term: "wearing glasses" },
684
703
  { id: "feature-freckles", label: "Freckles", dimension: "distinctive-features", description: "Visible freckles", promptHint: "with freckles" },
685
- { id: "feature-tattoos", label: "Tattoos", dimension: "distinctive-features", description: "Visible tattoos", promptHint: "with visible tattoos" },
686
- { id: "feature-scar", label: "Scar", dimension: "distinctive-features", description: "Facial scar", promptHint: "with a facial scar" },
704
+ { id: "feature-tattoos", label: "Tattoos", dimension: "distinctive-features", description: "Visible tattoos", promptHint: "with visible tattoos", term: "visible tattoos" },
705
+ { id: "feature-scar", label: "Scar", dimension: "distinctive-features", description: "Facial scar", promptHint: "with a facial scar", term: "facial scar" },
687
706
  { id: "feature-dimples", label: "Dimples", dimension: "distinctive-features", description: "Dimpled cheeks", promptHint: "with dimples" },
688
- { id: "feature-piercing", label: "Piercing", dimension: "distinctive-features", description: "Visible piercing", promptHint: "with a visible piercing" },
689
- { id: "feature-birthmark", label: "Birthmark", dimension: "distinctive-features", description: "Visible birthmark on face or shoulder", promptHint: "with a visible birthmark on the face or shoulder" },
690
- { id: "feature-mole", label: "Mole / Beauty Mark", dimension: "distinctive-features", description: "One prominent mole, often near upper lip", promptHint: "with a prominent beauty mark mole near the upper lip" },
707
+ { id: "feature-piercing", label: "Piercing", dimension: "distinctive-features", description: "Visible piercing", promptHint: "with a visible piercing", term: "visible piercing" },
708
+ { id: "feature-birthmark", label: "Birthmark", dimension: "distinctive-features", description: "Visible birthmark on face or shoulder", promptHint: "with a visible birthmark on the face or shoulder", term: "visible birthmark" },
709
+ { id: "feature-mole", label: "Mole / Beauty Mark", dimension: "distinctive-features", description: "One prominent mole, often near upper lip", promptHint: "with a prominent beauty mark mole near the upper lip", term: "beauty mark near the upper lip" },
691
710
  { id: "feature-gap-teeth", label: "Gap Teeth", dimension: "distinctive-features", description: "Gap between front teeth", promptHint: "with a gap between the front teeth" },
692
711
  { id: "feature-aegyo-sal", label: "Aegyo Sal", dimension: "distinctive-features", description: "Puffy under-eye fold prized in K-beauty", promptHint: "with aegyo sal, the soft puffy under-eye fold" },
693
- { id: "feature-eye-bags", label: "Eye Bags", dimension: "distinctive-features", description: "Mild dark under-eye circles", promptHint: "with mild dark circles and under-eye bags" },
712
+ { id: "feature-eye-bags", label: "Eye Bags", dimension: "distinctive-features", description: "Mild dark under-eye circles", promptHint: "with mild dark circles and under-eye bags", term: "under-eye bags" },
694
713
  { id: "feature-dimpled-chin", label: "Dimpled Chin", dimension: "distinctive-features", description: "Soft dimple in the chin", promptHint: "with a soft dimple in the chin" },
695
714
  { id: "feature-cleft-chin", label: "Cleft Chin", dimension: "distinctive-features", description: "Defined vertical chin cleft", promptHint: "with a defined vertical cleft chin" },
696
715
  { id: "feature-heterochromia", label: "Heterochromia", dimension: "distinctive-features", description: "Each iris a different color", promptHint: "with heterochromia, each iris a different color" },
@@ -702,17 +721,17 @@ export const PEOPLE: ReadonlyArray<Person> = [
702
721
  { id: "feature-chest-tattoo", label: "Chest Tattoo", dimension: "distinctive-features", description: "Tattoo across chest / décolletage", promptHint: "with a tattoo across the chest and décolletage" },
703
722
  { id: "feature-leg-tattoo", label: "Leg Tattoo", dimension: "distinctive-features", description: "Visible tattoo on leg / calf / thigh", promptHint: "with a visible tattoo on the leg, running across the calf or thigh" },
704
723
  { id: "feature-forearm-tattoo", label: "Forearm Tattoo", dimension: "distinctive-features", description: "Tattoo on inner or outer forearm", promptHint: "with a tattoo on the forearm, visible on the inner or outer side" },
705
- { id: "feature-visible-piercings", label: "Visible Piercings", dimension: "distinctive-features", description: "Multiple visible piercings (septum, nose, lip, multi-ear)", promptHint: "with multiple visible piercings — septum, nose, lip, and multi-ear" },
706
- { id: "feature-ear-piercings", label: "Ear Piercings", dimension: "distinctive-features", description: "Multiple stacked ear piercings (cartilage, helix, conch)", promptHint: "with multiple stacked ear piercings — cartilage, helix, and conch" },
724
+ { id: "feature-visible-piercings", label: "Visible Piercings", dimension: "distinctive-features", description: "Multiple visible piercings (septum, nose, lip, multi-ear)", promptHint: "with multiple visible piercings — septum, nose, lip, and multi-ear", term: "multiple visible piercings" },
725
+ { id: "feature-ear-piercings", label: "Ear Piercings", dimension: "distinctive-features", description: "Multiple stacked ear piercings (cartilage, helix, conch)", promptHint: "with multiple stacked ear piercings — cartilage, helix, and conch", term: "multiple stacked ear piercings" },
707
726
  { id: "feature-lip-piercing", label: "Lip Piercing", dimension: "distinctive-features", description: "Lip ring / labret stud", promptHint: "with a lip piercing, a small ring or labret stud at the lip" },
708
727
  { id: "feature-nostril-piercing", label: "Nostril Piercing", dimension: "distinctive-features", description: "Single nostril stud or ring", promptHint: "with a single nostril piercing, a small stud or ring at the nostril" },
709
728
  { id: "feature-bare-shoulders", label: "Bare Shoulders", dimension: "distinctive-features", description: "Bare shoulders exposed", promptHint: "with bare shoulders exposed, the line of the collarbone and shoulder muscles uncovered" },
710
- { id: "feature-collarbone-visible", label: "Collarbone Visible", dimension: "distinctive-features", description: "Prominent collarbone catching light", promptHint: "with a prominent collarbone clearly defined and catching the light" },
711
- { id: "feature-midriff-visible", label: "Midriff Visible", dimension: "distinctive-features", description: "Exposed midriff between top and bottom", promptHint: "wearing a cropped style with the midriff visible" },
712
- { id: "feature-navel-visible", label: "Navel Visible", dimension: "distinctive-features", description: "Visible navel on bare stomach", promptHint: "with the navel visible" },
713
- { id: "feature-elongated-neck", label: "Elongated Neck", dimension: "distinctive-features", description: "Long swan-like neck", promptHint: "with an elongated, swan-like neck, long and gracefully extended" },
714
- { id: "feature-under-eye-circles", label: "Under-Eye Circles", dimension: "distinctive-features", description: "Subtle dark circles under the eyes (distinct from puffy eye-bags)", promptHint: "with subtle dark circles under the eyes" },
715
- { id: "feature-fangs", label: "Fangs", dimension: "distinctive-features", description: "Visible fangs (vampire / character archetype)", promptHint: "with visible fangs at the canines, character / vampire archetype" },
729
+ { id: "feature-collarbone-visible", label: "Collarbone Visible", dimension: "distinctive-features", description: "Prominent collarbone catching light", promptHint: "with a prominent collarbone clearly defined and catching the light", term: "visible collarbone" },
730
+ { id: "feature-midriff-visible", label: "Midriff Visible", dimension: "distinctive-features", description: "Exposed midriff between top and bottom", promptHint: "wearing a cropped style with the midriff visible", term: "visible midriff" },
731
+ { id: "feature-navel-visible", label: "Navel Visible", dimension: "distinctive-features", description: "Visible navel on bare stomach", promptHint: "with the navel visible", term: "visible navel" },
732
+ { id: "feature-elongated-neck", label: "Elongated Neck", dimension: "distinctive-features", description: "Long swan-like neck", promptHint: "with an elongated, swan-like neck, long and gracefully extended", term: "elongated swan-like neck" },
733
+ { id: "feature-under-eye-circles", label: "Under-Eye Circles", dimension: "distinctive-features", description: "Subtle dark circles under the eyes (distinct from puffy eye-bags)", promptHint: "with subtle dark circles under the eyes", term: "dark under-eye circles" },
734
+ { id: "feature-fangs", label: "Fangs", dimension: "distinctive-features", description: "Visible fangs (vampire / character archetype)", promptHint: "with visible fangs at the canines, character / vampire archetype", term: "visible fangs at the canines" },
716
735
 
717
736
  // -------------------- Regional Aesthetic --------------------
718
737
  // Vibe layer (composes with Ethnicity, Skin Tone, Hair, Styling — never
@@ -729,110 +748,110 @@ export const PEOPLE: ReadonlyArray<Person> = [
729
748
  // differences. Ethiopia is intentionally untagged (never colonized).
730
749
 
731
750
  // ----- USA — Mainstream -----
732
- { id: "cali-beach", label: "California Beach", group: "USA — Mainstream", dimension: "regional-aesthetic", description: "Laid-back beach-town California aesthetic", promptHint: "a California beach aesthetic — laid-back beach-town vibe, golden-hour sun-warmed energy, easy carefree mood" },
733
- { id: "valley-girl", label: "Valley Girl", group: "USA — Mainstream", dimension: "regional-aesthetic", description: "Southern California valley aesthetic (feminine)", promptHint: "a Valley Girl aesthetic — Southern California suburban-chic vibe, polished and sun-kissed" },
734
- { id: "norcal-hippie", label: "NorCal Hippie", group: "USA — Mainstream", dimension: "regional-aesthetic", description: "Northern California Berkeley / Bay-Area hippie aesthetic", promptHint: "a Northern California hippie aesthetic — laid-back Berkeley / Bay-Area mood, gentle counter-culture vibe" },
735
- { id: "boho-la", label: "Boho LA", group: "USA — Mainstream", dimension: "regional-aesthetic", description: "Los Angeles canyon-bohemian aesthetic (feminine)", promptHint: "a Boho LA aesthetic — Los Angeles canyon-bohemian vibe, free-spirited Laurel Canyon mood" },
736
- { id: "texas-cowgirl", label: "Texas Cowgirl", group: "USA — Mainstream", dimension: "regional-aesthetic", description: "Texas Western ranch-country aesthetic (feminine)", promptHint: "a Texas cowgirl aesthetic — Western ranch-country vibe, warm Lone-Star confidence" },
737
- { id: "texas-cowboy", label: "Texas Cowboy", group: "USA — Mainstream", dimension: "regional-aesthetic", description: "Texas Western ranch-country aesthetic (masculine)", promptHint: "a Texas cowboy aesthetic — Western ranch-country vibe, weathered Lone-Star presence" },
738
- { id: "southern-belle", label: "Southern Belle", group: "USA — Mainstream", dimension: "regional-aesthetic", description: "Charleston / Savannah antebellum-gentility aesthetic (feminine)", promptHint: "a Southern Belle aesthetic — Charleston / Savannah gentility, gracious antebellum charm" },
739
- { id: "southern-gentleman", label: "Southern Gentleman", group: "USA — Mainstream", dimension: "regional-aesthetic", description: "Old-South gentility aesthetic (masculine)", promptHint: "a Southern Gentleman aesthetic — old-South gentility, gracious Charleston / Savannah charm" },
740
- { id: "miami-latina", label: "Miami Latina", group: "USA — Mainstream", dimension: "regional-aesthetic", description: "South Beach Caribbean-Latin aesthetic (feminine)", promptHint: "a Miami Latina aesthetic — South Beach Caribbean-Latin energy, sun-and-neon vibrance" },
741
- { id: "miami-latino", label: "Miami Latino", group: "USA — Mainstream", dimension: "regional-aesthetic", description: "South Beach Caribbean-Latin aesthetic (masculine)", promptHint: "a Miami Latino aesthetic — South Beach Caribbean-Latin energy, sun-and-neon confidence" },
742
- { id: "hawaii-island", label: "Hawaii Island", group: "USA — Mainstream", dimension: "regional-aesthetic", description: "Polynesian-Pacific Hawaiian aesthetic", promptHint: "a Hawaiian island aesthetic — Polynesian-Pacific vibe, gentle ocean-warmed presence" },
743
- { id: "nyc-fashion", label: "NYC Fashion", group: "USA — Mainstream", dimension: "regional-aesthetic", description: "Manhattan editorial-fashion aesthetic (feminine)", promptHint: "a New York fashion-girl aesthetic — Manhattan editorial vibe, urban-sharp confident energy" },
744
- { id: "nyc-sharp", label: "NYC Sharp", group: "USA — Mainstream", dimension: "regional-aesthetic", description: "Manhattan power-tailored aesthetic (masculine)", promptHint: "a New York sharp-dressed aesthetic — Manhattan power-and-pace vibe, urban-tailored presence" },
745
- { id: "brooklyn-hipster", label: "Brooklyn Hipster", group: "USA — Mainstream", dimension: "regional-aesthetic", description: "Williamsburg creative-class aesthetic", promptHint: "a Brooklyn hipster aesthetic — Williamsburg creative-class vibe, considered bohemian-urban energy" },
746
- { id: "new-england-prep", label: "New England Prep", group: "USA — Mainstream", dimension: "regional-aesthetic", description: "Cape Cod / Nantucket old-money preppy aesthetic", promptHint: "a New England prep aesthetic — Cape Cod / Nantucket old-money vibe, classic Ivy-coast polish" },
747
- { id: "pnw-granola", label: "PNW Granola", group: "USA — Mainstream", dimension: "regional-aesthetic", description: "Portland / Seattle outdoorsy aesthetic", promptHint: "a Pacific Northwest granola aesthetic — Portland / Seattle outdoorsy vibe, mossy mountain-coffee mood" },
748
- { id: "nashville-country", label: "Nashville Country", group: "USA — Mainstream", dimension: "regional-aesthetic", description: "Music-City modern country-pop aesthetic (feminine)", promptHint: "a Nashville country-pop aesthetic — Music-City warmth, Southern modern-country charm" },
749
- { id: "nashville-cowboy", label: "Nashville Cowboy", group: "USA — Mainstream", dimension: "regional-aesthetic", description: "Music-City modern-cowboy aesthetic (masculine)", promptHint: "a Nashville modern-cowboy aesthetic — Music-City warmth, modern-Western charm" },
750
- { id: "vegas-glam", label: "Vegas Glam", group: "USA — Mainstream", dimension: "regional-aesthetic", description: "Las Vegas Strip-glamour aesthetic (feminine)", promptHint: "a Las Vegas glam aesthetic — Strip-glamour vibe, high-shine showroom presence" },
751
- { id: "vegas-suit", label: "Vegas Suit", group: "USA — Mainstream", dimension: "regional-aesthetic", description: "Las Vegas Strip suited aesthetic (masculine)", promptHint: "a Las Vegas suit-and-shine aesthetic — Strip-glamour vibe, high-roller charisma" },
751
+ { id: "cali-beach", label: "California Beach", group: "USA — Mainstream", dimension: "regional-aesthetic", description: "Laid-back beach-town California aesthetic", promptHint: "a California beach aesthetic — laid-back beach-town vibe, golden-hour sun-warmed energy, easy carefree mood", term: "california beach aesthetic" },
752
+ { id: "valley-girl", label: "Valley Girl", group: "USA — Mainstream", dimension: "regional-aesthetic", description: "Southern California valley aesthetic (feminine)", promptHint: "a Valley Girl aesthetic — Southern California suburban-chic vibe, polished and sun-kissed", term: "valley girl aesthetic" },
753
+ { id: "norcal-hippie", label: "NorCal Hippie", group: "USA — Mainstream", dimension: "regional-aesthetic", description: "Northern California Berkeley / Bay-Area hippie aesthetic", promptHint: "a Northern California hippie aesthetic — laid-back Berkeley / Bay-Area mood, gentle counter-culture vibe", term: "northern california hippie aesthetic" },
754
+ { id: "boho-la", label: "Boho LA", group: "USA — Mainstream", dimension: "regional-aesthetic", description: "Los Angeles canyon-bohemian aesthetic (feminine)", promptHint: "a Boho LA aesthetic — Los Angeles canyon-bohemian vibe, free-spirited Laurel Canyon mood", term: "boho los angeles aesthetic" },
755
+ { id: "texas-cowgirl", label: "Texas Cowgirl", group: "USA — Mainstream", dimension: "regional-aesthetic", description: "Texas Western ranch-country aesthetic (feminine)", promptHint: "a Texas cowgirl aesthetic — Western ranch-country vibe, warm Lone-Star confidence", term: "texas cowgirl aesthetic" },
756
+ { id: "texas-cowboy", label: "Texas Cowboy", group: "USA — Mainstream", dimension: "regional-aesthetic", description: "Texas Western ranch-country aesthetic (masculine)", promptHint: "a Texas cowboy aesthetic — Western ranch-country vibe, weathered Lone-Star presence", term: "texas cowboy aesthetic" },
757
+ { id: "southern-belle", label: "Southern Belle", group: "USA — Mainstream", dimension: "regional-aesthetic", description: "Charleston / Savannah antebellum-gentility aesthetic (feminine)", promptHint: "a Southern Belle aesthetic — Charleston / Savannah gentility, gracious antebellum charm", term: "southern belle aesthetic" },
758
+ { id: "southern-gentleman", label: "Southern Gentleman", group: "USA — Mainstream", dimension: "regional-aesthetic", description: "Old-South gentility aesthetic (masculine)", promptHint: "a Southern Gentleman aesthetic — old-South gentility, gracious Charleston / Savannah charm", term: "southern gentleman aesthetic" },
759
+ { id: "miami-latina", label: "Miami Latina", group: "USA — Mainstream", dimension: "regional-aesthetic", description: "South Beach Caribbean-Latin aesthetic (feminine)", promptHint: "a Miami Latina aesthetic — South Beach Caribbean-Latin energy, sun-and-neon vibrance", term: "miami latina aesthetic" },
760
+ { id: "miami-latino", label: "Miami Latino", group: "USA — Mainstream", dimension: "regional-aesthetic", description: "South Beach Caribbean-Latin aesthetic (masculine)", promptHint: "a Miami Latino aesthetic — South Beach Caribbean-Latin energy, sun-and-neon confidence", term: "miami latino aesthetic" },
761
+ { id: "hawaii-island", label: "Hawaii Island", group: "USA — Mainstream", dimension: "regional-aesthetic", description: "Polynesian-Pacific Hawaiian aesthetic", promptHint: "a Hawaiian island aesthetic — Polynesian-Pacific vibe, gentle ocean-warmed presence", term: "hawaiian island aesthetic" },
762
+ { id: "nyc-fashion", label: "NYC Fashion", group: "USA — Mainstream", dimension: "regional-aesthetic", description: "Manhattan editorial-fashion aesthetic (feminine)", promptHint: "a New York fashion-girl aesthetic — Manhattan editorial vibe, urban-sharp confident energy", term: "new york fashion-girl aesthetic" },
763
+ { id: "nyc-sharp", label: "NYC Sharp", group: "USA — Mainstream", dimension: "regional-aesthetic", description: "Manhattan power-tailored aesthetic (masculine)", promptHint: "a New York sharp-dressed aesthetic — Manhattan power-and-pace vibe, urban-tailored presence", term: "new york sharp-dressed aesthetic" },
764
+ { id: "brooklyn-hipster", label: "Brooklyn Hipster", group: "USA — Mainstream", dimension: "regional-aesthetic", description: "Williamsburg creative-class aesthetic", promptHint: "a Brooklyn hipster aesthetic — Williamsburg creative-class vibe, considered bohemian-urban energy", term: "brooklyn hipster aesthetic" },
765
+ { id: "new-england-prep", label: "New England Prep", group: "USA — Mainstream", dimension: "regional-aesthetic", description: "Cape Cod / Nantucket old-money preppy aesthetic", promptHint: "a New England prep aesthetic — Cape Cod / Nantucket old-money vibe, classic Ivy-coast polish", term: "new england prep aesthetic" },
766
+ { id: "pnw-granola", label: "PNW Granola", group: "USA — Mainstream", dimension: "regional-aesthetic", description: "Portland / Seattle outdoorsy aesthetic", promptHint: "a Pacific Northwest granola aesthetic — Portland / Seattle outdoorsy vibe, mossy mountain-coffee mood", term: "pacific northwest granola aesthetic" },
767
+ { id: "nashville-country", label: "Nashville Country", group: "USA — Mainstream", dimension: "regional-aesthetic", description: "Music-City modern country-pop aesthetic (feminine)", promptHint: "a Nashville country-pop aesthetic — Music-City warmth, Southern modern-country charm", term: "nashville country-pop aesthetic" },
768
+ { id: "nashville-cowboy", label: "Nashville Cowboy", group: "USA — Mainstream", dimension: "regional-aesthetic", description: "Music-City modern-cowboy aesthetic (masculine)", promptHint: "a Nashville modern-cowboy aesthetic — Music-City warmth, modern-Western charm", term: "nashville modern-cowboy aesthetic" },
769
+ { id: "vegas-glam", label: "Vegas Glam", group: "USA — Mainstream", dimension: "regional-aesthetic", description: "Las Vegas Strip-glamour aesthetic (feminine)", promptHint: "a Las Vegas glam aesthetic — Strip-glamour vibe, high-shine showroom presence", term: "las vegas glam aesthetic" },
770
+ { id: "vegas-suit", label: "Vegas Suit", group: "USA — Mainstream", dimension: "regional-aesthetic", description: "Las Vegas Strip suited aesthetic (masculine)", promptHint: "a Las Vegas suit-and-shine aesthetic — Strip-glamour vibe, high-roller charisma", term: "las vegas suit-and-shine aesthetic" },
752
771
 
753
772
  // ----- USA — African-American -----
754
- { id: "harlem-classic", label: "Harlem Classic", group: "USA — African-American", dimension: "regional-aesthetic", description: "Black-New-York heritage aesthetic, jazz-age elegance", promptHint: "a Harlem classic aesthetic — Black-New-York heritage vibe, jazz-age elegance and modern-uptown polish" },
755
- { id: "atl-southern", label: "ATL Southern", group: "USA — African-American", dimension: "regional-aesthetic", description: "Atlanta Black-South hip-hop / R&B aesthetic", promptHint: "an Atlanta Black-South aesthetic — Southern hip-hop / R&B capital vibe, peach-tree confident-and-warm mood" },
756
- { id: "nola-creole", label: "NOLA Creole", group: "USA — African-American", dimension: "regional-aesthetic", description: "New Orleans Louisiana French-Caribbean-African aesthetic", promptHint: "a New Orleans Creole aesthetic — Louisiana French-Caribbean-African vibe, jazz-and-second-line warmth" },
757
- { id: "dmv-go-go", label: "DMV Go-Go", group: "USA — African-American", dimension: "regional-aesthetic", description: "DC / Maryland / Virginia Black-DMV go-go aesthetic", promptHint: "a DC / Maryland / Virginia Black-DMV aesthetic — go-go-music capital vibe, polished East-Coast confidence" },
758
- { id: "west-coast-hip-hop", label: "West Coast", group: "USA — African-American", dimension: "regional-aesthetic", description: "South Central / Compton West Coast hip-hop aesthetic", promptHint: "a West Coast Black-LA aesthetic — South Central / Compton hip-hop vibe, sun-warmed laid-back swagger" },
759
- { id: "chicago-south-side", label: "Chicago South Side", group: "USA — African-American", dimension: "regional-aesthetic", description: "Midwest Black-urban Chicago aesthetic", promptHint: "a Chicago South Side aesthetic — Midwest Black-urban vibe, drill-era street-sharp presence" },
773
+ { id: "harlem-classic", label: "Harlem Classic", group: "USA — African-American", dimension: "regional-aesthetic", description: "Black-New-York heritage aesthetic, jazz-age elegance", promptHint: "a Harlem classic aesthetic — Black-New-York heritage vibe, jazz-age elegance and modern-uptown polish", term: "harlem classic aesthetic" },
774
+ { id: "atl-southern", label: "ATL Southern", group: "USA — African-American", dimension: "regional-aesthetic", description: "Atlanta Black-South hip-hop / R&B aesthetic", promptHint: "an Atlanta Black-South aesthetic — Southern hip-hop / R&B capital vibe, peach-tree confident-and-warm mood", term: "atlanta southern hip-hop aesthetic" },
775
+ { id: "nola-creole", label: "NOLA Creole", group: "USA — African-American", dimension: "regional-aesthetic", description: "New Orleans Louisiana French-Caribbean-African aesthetic", promptHint: "a New Orleans Creole aesthetic — Louisiana French-Caribbean-African vibe, jazz-and-second-line warmth", term: "new orleans creole aesthetic" },
776
+ { id: "dmv-go-go", label: "DMV Go-Go", group: "USA — African-American", dimension: "regional-aesthetic", description: "DC / Maryland / Virginia Black-DMV go-go aesthetic", promptHint: "a DC / Maryland / Virginia Black-DMV aesthetic — go-go-music capital vibe, polished East-Coast confidence", term: "washington dc go-go aesthetic" },
777
+ { id: "west-coast-hip-hop", label: "West Coast", group: "USA — African-American", dimension: "regional-aesthetic", description: "South Central / Compton West Coast hip-hop aesthetic", promptHint: "a West Coast Black-LA aesthetic — South Central / Compton hip-hop vibe, sun-warmed laid-back swagger", term: "west coast los angeles hip-hop aesthetic" },
778
+ { id: "chicago-south-side", label: "Chicago South Side", group: "USA — African-American", dimension: "regional-aesthetic", description: "Midwest Black-urban Chicago aesthetic", promptHint: "a Chicago South Side aesthetic — Midwest Black-urban vibe, drill-era street-sharp presence", term: "chicago south side aesthetic" },
760
779
 
761
780
  // ----- Europe -----
762
- { id: "parisienne", label: "Parisienne", group: "Europe", dimension: "regional-aesthetic", description: "Left-Bank Paris French-chic aesthetic (feminine)", promptHint: "a Parisienne aesthetic — Left-Bank Paris vibe, effortless French-chic mood, je-ne-sais-quoi confidence" },
763
- { id: "parisian-flaneur", label: "Parisian Flâneur", group: "Europe", dimension: "regional-aesthetic", description: "Left-Bank Paris French-chic aesthetic (masculine)", promptHint: "a Parisian flâneur aesthetic — Left-Bank Paris vibe, contemplative French-chic mood, refined city-walker air" },
764
- { id: "milanese-fashion", label: "Milanese Fashion", group: "Europe", dimension: "regional-aesthetic", description: "Italian Milanese high-fashion aesthetic", promptHint: "a Milanese fashion aesthetic — Italian high-fashion polish, Quadrilatero confident sleekness" },
765
- { id: "sicilian-beach", label: "Sicilian Beach", group: "Europe", dimension: "regional-aesthetic", description: "Mediterranean southern-Italian beach aesthetic", promptHint: "a Sicilian beach aesthetic — Mediterranean sun-and-salt vibe, warm southern-Italian ease" },
766
- { id: "madrileña", label: "Madrileña", group: "Europe", dimension: "regional-aesthetic", description: "Madrid Spanish aesthetic (feminine)", promptHint: "a Madrileña aesthetic — Madrid Spanish vibe, sun-and-confidence Iberian energy" },
767
- { id: "madrileño", label: "Madrileño", group: "Europe", dimension: "regional-aesthetic", description: "Madrid Spanish aesthetic (masculine)", promptHint: "a Madrileño aesthetic — Madrid Spanish vibe, sun-and-confidence Iberian presence" },
768
- { id: "catalan-modern", label: "Catalan Modern", group: "Europe", dimension: "regional-aesthetic", description: "Barcelona Mediterranean-design aesthetic", promptHint: "a Catalan modern aesthetic — Barcelona Mediterranean-design vibe, easygoing creative coast" },
769
- { id: "greek-mediterranean", label: "Greek Mediterranean", group: "Europe", dimension: "regional-aesthetic", description: "Aegean island Greek aesthetic", promptHint: "a Greek Mediterranean aesthetic — Aegean island vibe, sun-bleached limestone-and-sea mood" },
770
- { id: "scandi-minimal", label: "Scandi Minimal", group: "Europe", dimension: "regional-aesthetic", description: "Nordic clean-line minimal aesthetic", promptHint: "a Scandinavian minimal aesthetic — Nordic clean-line vibe, hygge-and-quiet-confidence mood" },
771
- { id: "english-rose", label: "English Rose", group: "Europe", dimension: "regional-aesthetic", description: "Countryside English aesthetic (feminine)", promptHint: "an English Rose aesthetic — countryside English vibe, gentle rose-garden refinement" },
772
- { id: "london-prep", label: "London Prep", group: "Europe", dimension: "regional-aesthetic", description: "Mayfair / Chelsea refined British aesthetic (masculine)", promptHint: "a London prep aesthetic — Mayfair / Chelsea vibe, refined British polish" },
773
- { id: "manchester-indie", label: "Manchester Indie", group: "Europe", dimension: "regional-aesthetic", description: "North-England gig-and-rain working-class-cool aesthetic", promptHint: "a Manchester indie aesthetic — North-England gig-and-rain vibe, working-class cool" },
774
- { id: "berlin-alt", label: "Berlin Alt", group: "Europe", dimension: "regional-aesthetic", description: "Kreuzberg techno-and-art counterculture aesthetic", promptHint: "a Berlin alt aesthetic — Kreuzberg techno-and-art vibe, edgy considered counterculture" },
775
- { id: "munich-traditional", label: "Munich Traditional", group: "Europe", dimension: "regional-aesthetic", description: "Bavarian Oktoberfest-traditional aesthetic", promptHint: "a Munich Bavarian-traditional aesthetic — Oktoberfest warmth, alpine-folk pride" },
776
- { id: "eastern-european-glam", label: "Eastern European Glam", group: "Europe", dimension: "regional-aesthetic", description: "Moscow / Kyiv winter-glamour aesthetic (feminine)", promptHint: "an Eastern European glam aesthetic — Moscow / Kyiv vibe, statement-confident winter-glamour" },
777
- { id: "eastern-european-stoic", label: "Eastern European Stoic", group: "Europe", dimension: "regional-aesthetic", description: "Moscow / Kyiv weathered-confidence aesthetic (masculine)", promptHint: "an Eastern European stoic aesthetic — Moscow / Kyiv vibe, weathered confidence, winter-hardened presence" },
781
+ { id: "parisienne", label: "Parisienne", group: "Europe", dimension: "regional-aesthetic", description: "Left-Bank Paris French-chic aesthetic (feminine)", promptHint: "a Parisienne aesthetic — Left-Bank Paris vibe, effortless French-chic mood, je-ne-sais-quoi confidence", term: "parisienne aesthetic" },
782
+ { id: "parisian-flaneur", label: "Parisian Flâneur", group: "Europe", dimension: "regional-aesthetic", description: "Left-Bank Paris French-chic aesthetic (masculine)", promptHint: "a Parisian flâneur aesthetic — Left-Bank Paris vibe, contemplative French-chic mood, refined city-walker air", term: "parisian flaneur aesthetic" },
783
+ { id: "milanese-fashion", label: "Milanese Fashion", group: "Europe", dimension: "regional-aesthetic", description: "Italian Milanese high-fashion aesthetic", promptHint: "a Milanese fashion aesthetic — Italian high-fashion polish, Quadrilatero confident sleekness", term: "milanese fashion aesthetic" },
784
+ { id: "sicilian-beach", label: "Sicilian Beach", group: "Europe", dimension: "regional-aesthetic", description: "Mediterranean southern-Italian beach aesthetic", promptHint: "a Sicilian beach aesthetic — Mediterranean sun-and-salt vibe, warm southern-Italian ease", term: "sicilian beach aesthetic" },
785
+ { id: "madrileña", label: "Madrileña", group: "Europe", dimension: "regional-aesthetic", description: "Madrid Spanish aesthetic (feminine)", promptHint: "a Madrileña aesthetic — Madrid Spanish vibe, sun-and-confidence Iberian energy", term: "madrileña aesthetic" },
786
+ { id: "madrileño", label: "Madrileño", group: "Europe", dimension: "regional-aesthetic", description: "Madrid Spanish aesthetic (masculine)", promptHint: "a Madrileño aesthetic — Madrid Spanish vibe, sun-and-confidence Iberian presence", term: "madrileño aesthetic" },
787
+ { id: "catalan-modern", label: "Catalan Modern", group: "Europe", dimension: "regional-aesthetic", description: "Barcelona Mediterranean-design aesthetic", promptHint: "a Catalan modern aesthetic — Barcelona Mediterranean-design vibe, easygoing creative coast", term: "catalan modern aesthetic" },
788
+ { id: "greek-mediterranean", label: "Greek Mediterranean", group: "Europe", dimension: "regional-aesthetic", description: "Aegean island Greek aesthetic", promptHint: "a Greek Mediterranean aesthetic — Aegean island vibe, sun-bleached limestone-and-sea mood", term: "greek mediterranean aesthetic" },
789
+ { id: "scandi-minimal", label: "Scandi Minimal", group: "Europe", dimension: "regional-aesthetic", description: "Nordic clean-line minimal aesthetic", promptHint: "a Scandinavian minimal aesthetic — Nordic clean-line vibe, hygge-and-quiet-confidence mood", term: "scandinavian minimal aesthetic" },
790
+ { id: "english-rose", label: "English Rose", group: "Europe", dimension: "regional-aesthetic", description: "Countryside English aesthetic (feminine)", promptHint: "an English Rose aesthetic — countryside English vibe, gentle rose-garden refinement", term: "english rose aesthetic" },
791
+ { id: "london-prep", label: "London Prep", group: "Europe", dimension: "regional-aesthetic", description: "Mayfair / Chelsea refined British aesthetic (masculine)", promptHint: "a London prep aesthetic — Mayfair / Chelsea vibe, refined British polish", term: "london prep aesthetic" },
792
+ { id: "manchester-indie", label: "Manchester Indie", group: "Europe", dimension: "regional-aesthetic", description: "North-England gig-and-rain working-class-cool aesthetic", promptHint: "a Manchester indie aesthetic — North-England gig-and-rain vibe, working-class cool", term: "manchester indie aesthetic" },
793
+ { id: "berlin-alt", label: "Berlin Alt", group: "Europe", dimension: "regional-aesthetic", description: "Kreuzberg techno-and-art counterculture aesthetic", promptHint: "a Berlin alt aesthetic — Kreuzberg techno-and-art vibe, edgy considered counterculture", term: "berlin alt aesthetic" },
794
+ { id: "munich-traditional", label: "Munich Traditional", group: "Europe", dimension: "regional-aesthetic", description: "Bavarian Oktoberfest-traditional aesthetic", promptHint: "a Munich Bavarian-traditional aesthetic — Oktoberfest warmth, alpine-folk pride", term: "munich bavarian-traditional aesthetic" },
795
+ { id: "eastern-european-glam", label: "Eastern European Glam", group: "Europe", dimension: "regional-aesthetic", description: "Moscow / Kyiv winter-glamour aesthetic (feminine)", promptHint: "an Eastern European glam aesthetic — Moscow / Kyiv vibe, statement-confident winter-glamour", term: "eastern european glam aesthetic" },
796
+ { id: "eastern-european-stoic", label: "Eastern European Stoic", group: "Europe", dimension: "regional-aesthetic", description: "Moscow / Kyiv weathered-confidence aesthetic (masculine)", promptHint: "an Eastern European stoic aesthetic — Moscow / Kyiv vibe, weathered confidence, winter-hardened presence", term: "eastern european stoic aesthetic" },
778
797
 
779
798
  // ----- Asia -----
780
- { id: "tokyo-harajuku", label: "Tokyo Harajuku", group: "Asia", dimension: "regional-aesthetic", description: "Tokyo playful expressive Japanese street aesthetic", promptHint: "a Tokyo Harajuku aesthetic — playful expressive Japanese street vibe, color-and-character mood" },
781
- { id: "ginza-office", label: "Ginza Office", group: "Asia", dimension: "regional-aesthetic", description: "Tokyo Ginza Japanese corporate-elegant aesthetic", promptHint: "a Ginza Tokyo office aesthetic — buttoned-up Japanese corporate-elegant vibe" },
782
- { id: "shibuya-streetwear", label: "Shibuya Streetwear", group: "Asia", dimension: "regional-aesthetic", description: "Tokyo Shibuya street-fashion aesthetic", promptHint: "a Shibuya streetwear aesthetic — Tokyo street-fashion vibe, layered post-modern mood" },
783
- { id: "osaka-everyday", label: "Osaka Everyday", group: "Asia", dimension: "regional-aesthetic", description: "Osaka warm casual Kansai aesthetic", promptHint: "an Osaka everyday aesthetic — warm casual Kansai vibe, easygoing humor-and-warmth" },
784
- { id: "seoul-k-pop", label: "Seoul K-Pop", group: "Asia", dimension: "regional-aesthetic", description: "Seoul Korean-pop polished aesthetic", promptHint: "a Seoul K-pop aesthetic — Korean-pop polish vibe, idol-grade brightness" },
785
- { id: "gangnam-glam", label: "Gangnam Glam", group: "Asia", dimension: "regional-aesthetic", description: "Seoul Gangnam Korean luxury-district aesthetic", promptHint: "a Gangnam Seoul glam aesthetic — Korean luxury-district vibe, polished beauty-statement" },
786
- { id: "shanghai-modern", label: "Shanghai Modern", group: "Asia", dimension: "regional-aesthetic", description: "Shanghai Chinese metropolitan aesthetic", promptHint: "a Shanghai modern aesthetic — Chinese metropolitan vibe, Bund-skyline cosmopolitan polish" },
787
- { id: "beijing-hutong", label: "Beijing Hutong", group: "Asia", dimension: "regional-aesthetic", description: "Beijing old-courtyard traditional-meets-modern aesthetic", promptHint: "a Beijing hutong aesthetic — old-Beijing courtyard vibe, traditional-meets-modern mood" },
788
- { id: "hong-kong-cinematic", label: "Hong Kong Cinematic", group: "Asia", dimension: "regional-aesthetic", description: "Hong Kong neon-noir Wong-Kar-Wai aesthetic", promptHint: "a Hong Kong cinematic aesthetic — neon-mid-century vibe, Wong-Kar-Wai mood" },
789
- { id: "mumbai-bollywood", label: "Mumbai Bollywood", group: "Asia", dimension: "regional-aesthetic", description: "Mumbai Indian film-industry aesthetic", promptHint: "a Mumbai Bollywood aesthetic — Indian film-industry vibe, vibrant statement-glamour" },
790
- { id: "south-india-traditional", label: "South India Traditional", group: "Asia", dimension: "regional-aesthetic", description: "Tamil / Kerala temple-town classical aesthetic", promptHint: "a South Indian traditional aesthetic — Tamil / Kerala temple-town vibe, classical refinement" },
791
- { id: "bangkok-street", label: "Bangkok Street", group: "Asia", dimension: "regional-aesthetic", description: "Bangkok Thai night-market neon-urban aesthetic", promptHint: "a Bangkok street aesthetic — Thai night-market energy, neon-and-warmth urban vibe" },
799
+ { id: "tokyo-harajuku", label: "Tokyo Harajuku", group: "Asia", dimension: "regional-aesthetic", description: "Tokyo playful expressive Japanese street aesthetic", promptHint: "a Tokyo Harajuku aesthetic — playful expressive Japanese street vibe, color-and-character mood", term: "tokyo harajuku aesthetic" },
800
+ { id: "ginza-office", label: "Ginza Office", group: "Asia", dimension: "regional-aesthetic", description: "Tokyo Ginza Japanese corporate-elegant aesthetic", promptHint: "a Ginza Tokyo office aesthetic — buttoned-up Japanese corporate-elegant vibe", term: "ginza tokyo office aesthetic" },
801
+ { id: "shibuya-streetwear", label: "Shibuya Streetwear", group: "Asia", dimension: "regional-aesthetic", description: "Tokyo Shibuya street-fashion aesthetic", promptHint: "a Shibuya streetwear aesthetic — Tokyo street-fashion vibe, layered post-modern mood", term: "shibuya streetwear aesthetic" },
802
+ { id: "osaka-everyday", label: "Osaka Everyday", group: "Asia", dimension: "regional-aesthetic", description: "Osaka warm casual Kansai aesthetic", promptHint: "an Osaka everyday aesthetic — warm casual Kansai vibe, easygoing humor-and-warmth", term: "osaka everyday aesthetic" },
803
+ { id: "seoul-k-pop", label: "Seoul K-Pop", group: "Asia", dimension: "regional-aesthetic", description: "Seoul Korean-pop polished aesthetic", promptHint: "a Seoul K-pop aesthetic — Korean-pop polish vibe, idol-grade brightness", term: "seoul k-pop aesthetic" },
804
+ { id: "gangnam-glam", label: "Gangnam Glam", group: "Asia", dimension: "regional-aesthetic", description: "Seoul Gangnam Korean luxury-district aesthetic", promptHint: "a Gangnam Seoul glam aesthetic — Korean luxury-district vibe, polished beauty-statement", term: "gangnam seoul glam aesthetic" },
805
+ { id: "shanghai-modern", label: "Shanghai Modern", group: "Asia", dimension: "regional-aesthetic", description: "Shanghai Chinese metropolitan aesthetic", promptHint: "a Shanghai modern aesthetic — Chinese metropolitan vibe, Bund-skyline cosmopolitan polish", term: "shanghai modern aesthetic" },
806
+ { id: "beijing-hutong", label: "Beijing Hutong", group: "Asia", dimension: "regional-aesthetic", description: "Beijing old-courtyard traditional-meets-modern aesthetic", promptHint: "a Beijing hutong aesthetic — old-Beijing courtyard vibe, traditional-meets-modern mood", term: "beijing hutong aesthetic" },
807
+ { id: "hong-kong-cinematic", label: "Hong Kong Cinematic", group: "Asia", dimension: "regional-aesthetic", description: "Hong Kong neon-noir Wong-Kar-Wai aesthetic", promptHint: "a Hong Kong cinematic aesthetic — neon-mid-century vibe, Wong-Kar-Wai mood", term: "hong kong cinematic aesthetic" },
808
+ { id: "mumbai-bollywood", label: "Mumbai Bollywood", group: "Asia", dimension: "regional-aesthetic", description: "Mumbai Indian film-industry aesthetic", promptHint: "a Mumbai Bollywood aesthetic — Indian film-industry vibe, vibrant statement-glamour", term: "mumbai bollywood aesthetic" },
809
+ { id: "south-india-traditional", label: "South India Traditional", group: "Asia", dimension: "regional-aesthetic", description: "Tamil / Kerala temple-town classical aesthetic", promptHint: "a South Indian traditional aesthetic — Tamil / Kerala temple-town vibe, classical refinement", term: "south indian traditional aesthetic" },
810
+ { id: "bangkok-street", label: "Bangkok Street", group: "Asia", dimension: "regional-aesthetic", description: "Bangkok Thai night-market neon-urban aesthetic", promptHint: "a Bangkok street aesthetic — Thai night-market energy, neon-and-warmth urban vibe", term: "bangkok street aesthetic" },
792
811
 
793
812
  // ----- Latin America -----
794
- { id: "carioca-rio", label: "Carioca (Rio)", group: "Latin America", dimension: "regional-aesthetic", description: "Rio de Janeiro beach-and-favela-music Brazilian aesthetic", promptHint: "a Carioca aesthetic — Rio de Janeiro beach-and-favela-music vibe, sun-warmed Brazilian energy" },
795
- { id: "paulista", label: "Paulista (São Paulo)", group: "Latin America", dimension: "regional-aesthetic", description: "São Paulo metropolitan Brazilian creative-class aesthetic", promptHint: "a Paulista aesthetic — São Paulo metropolitan vibe, urban-Brazilian creative-class polish" },
796
- { id: "buenos-aires-tango", label: "Buenos Aires Tango", group: "Latin America", dimension: "regional-aesthetic", description: "Buenos Aires Recoleta / San Telmo tango aesthetic (feminine)", promptHint: "a Buenos Aires tango aesthetic — Recoleta / San Telmo vibe, sultry porteña confidence" },
797
- { id: "porteño", label: "Porteño", group: "Latin America", dimension: "regional-aesthetic", description: "Buenos Aires refined milonguero aesthetic (masculine)", promptHint: "a Porteño aesthetic — Buenos Aires vibe, refined milonguero presence" },
798
- { id: "mexico-city-chic", label: "Mexico City Chic", group: "Latin America", dimension: "regional-aesthetic", description: "CDMX Roma / Polanco modern-Mexican aesthetic", promptHint: "a Mexico City chic aesthetic — CDMX Roma / Polanco vibe, modern-Mexican polish" },
799
- { id: "chilango-traditional", label: "Chilango Traditional", group: "Latin America", dimension: "regional-aesthetic", description: "Mexico City warm folk-and-feast aesthetic", promptHint: "a Chilango traditional aesthetic — Mexico City vibe, warm folk-and-feast mood" },
800
- { id: "bogota-cosmopolitan", label: "Bogotá Cosmopolitan", group: "Latin America", dimension: "regional-aesthetic", description: "Bogotá Colombian capital refined Andean aesthetic", promptHint: "a Bogotá cosmopolitan aesthetic — Colombian capital vibe, refined Andean polish" },
813
+ { id: "carioca-rio", label: "Carioca (Rio)", group: "Latin America", dimension: "regional-aesthetic", description: "Rio de Janeiro beach-and-favela-music Brazilian aesthetic", promptHint: "a Carioca aesthetic — Rio de Janeiro beach-and-favela-music vibe, sun-warmed Brazilian energy", term: "carioca aesthetic" },
814
+ { id: "paulista", label: "Paulista (São Paulo)", group: "Latin America", dimension: "regional-aesthetic", description: "São Paulo metropolitan Brazilian creative-class aesthetic", promptHint: "a Paulista aesthetic — São Paulo metropolitan vibe, urban-Brazilian creative-class polish", term: "paulista aesthetic" },
815
+ { id: "buenos-aires-tango", label: "Buenos Aires Tango", group: "Latin America", dimension: "regional-aesthetic", description: "Buenos Aires Recoleta / San Telmo tango aesthetic (feminine)", promptHint: "a Buenos Aires tango aesthetic — Recoleta / San Telmo vibe, sultry porteña confidence", term: "buenos aires tango aesthetic" },
816
+ { id: "porteño", label: "Porteño", group: "Latin America", dimension: "regional-aesthetic", description: "Buenos Aires refined milonguero aesthetic (masculine)", promptHint: "a Porteño aesthetic — Buenos Aires vibe, refined milonguero presence", term: "porteño aesthetic" },
817
+ { id: "mexico-city-chic", label: "Mexico City Chic", group: "Latin America", dimension: "regional-aesthetic", description: "CDMX Roma / Polanco modern-Mexican aesthetic", promptHint: "a Mexico City chic aesthetic — CDMX Roma / Polanco vibe, modern-Mexican polish", term: "mexico city chic aesthetic" },
818
+ { id: "chilango-traditional", label: "Chilango Traditional", group: "Latin America", dimension: "regional-aesthetic", description: "Mexico City warm folk-and-feast aesthetic", promptHint: "a Chilango traditional aesthetic — Mexico City vibe, warm folk-and-feast mood", term: "chilango traditional aesthetic" },
819
+ { id: "bogota-cosmopolitan", label: "Bogotá Cosmopolitan", group: "Latin America", dimension: "regional-aesthetic", description: "Bogotá Colombian capital refined Andean aesthetic", promptHint: "a Bogotá cosmopolitan aesthetic — Colombian capital vibe, refined Andean polish", term: "bogotá cosmopolitan aesthetic" },
801
820
 
802
821
  // ----- Middle East -----
803
- { id: "beirut-riviera", label: "Beirut Riviera", group: "Middle East", dimension: "regional-aesthetic", description: "Lebanese Mediterranean cosmopolitan aesthetic", promptHint: "a Beirut Riviera aesthetic — Lebanese Mediterranean vibe, cosmopolitan-glamour mood" },
804
- { id: "tel-aviv-beach", label: "Tel Aviv Beach", group: "Middle East", dimension: "regional-aesthetic", description: "Tel Aviv Mediterranean coastal-city startup-energy aesthetic", promptHint: "a Tel Aviv beach aesthetic — Mediterranean coastal-city vibe, easygoing sun-and-sea startup-energy mood" },
805
- { id: "jerusalem-stone", label: "Jerusalem Stone", group: "Middle East", dimension: "regional-aesthetic", description: "Jerusalem old-city limestone-heritage aesthetic", promptHint: "a Jerusalem old-city aesthetic — limestone-warmth heritage vibe, layered ancient-and-modern presence" },
806
- { id: "sabra", label: "Sabra", group: "Middle East", dimension: "regional-aesthetic", description: "Native-Israeli direct-and-warm Sabra aesthetic", promptHint: "a Sabra aesthetic — native-Israeli vibe, sun-warmed direct-and-warm energy, prickly-outside-sweet-inside mood" },
807
- { id: "dubai-modern", label: "Dubai Modern", group: "Middle East", dimension: "regional-aesthetic", description: "Gulf-luxury Dubai cosmopolitan-emirate aesthetic", promptHint: "a Dubai modern aesthetic — Gulf-luxury vibe, polished cosmopolitan-emirate presence" },
808
- { id: "persian-glam", label: "Persian Glam", group: "Middle East", dimension: "regional-aesthetic", description: "Iranian heritage-and-glamour Persian aesthetic", promptHint: "a Persian glam aesthetic — Iranian heritage-and-glamour vibe, refined statement mood" },
809
- { id: "istanbul-bosphorus", label: "Istanbul Bosphorus", group: "Middle East", dimension: "regional-aesthetic", description: "Istanbul east-meets-west Bosphorus Ottoman-and-modern aesthetic", promptHint: "an Istanbul Bosphorus aesthetic — east-meets-west Turkish vibe, layered Ottoman-and-modern strait-city presence" },
822
+ { id: "beirut-riviera", label: "Beirut Riviera", group: "Middle East", dimension: "regional-aesthetic", description: "Lebanese Mediterranean cosmopolitan aesthetic", promptHint: "a Beirut Riviera aesthetic — Lebanese Mediterranean vibe, cosmopolitan-glamour mood", term: "beirut riviera aesthetic" },
823
+ { id: "tel-aviv-beach", label: "Tel Aviv Beach", group: "Middle East", dimension: "regional-aesthetic", description: "Tel Aviv Mediterranean coastal-city startup-energy aesthetic", promptHint: "a Tel Aviv beach aesthetic — Mediterranean coastal-city vibe, easygoing sun-and-sea startup-energy mood", term: "tel aviv beach aesthetic" },
824
+ { id: "jerusalem-stone", label: "Jerusalem Stone", group: "Middle East", dimension: "regional-aesthetic", description: "Jerusalem old-city limestone-heritage aesthetic", promptHint: "a Jerusalem old-city aesthetic — limestone-warmth heritage vibe, layered ancient-and-modern presence", term: "jerusalem old-city aesthetic" },
825
+ { id: "sabra", label: "Sabra", group: "Middle East", dimension: "regional-aesthetic", description: "Native-Israeli direct-and-warm Sabra aesthetic", promptHint: "a Sabra aesthetic — native-Israeli vibe, sun-warmed direct-and-warm energy, prickly-outside-sweet-inside mood", term: "native israeli sabra aesthetic" },
826
+ { id: "dubai-modern", label: "Dubai Modern", group: "Middle East", dimension: "regional-aesthetic", description: "Gulf-luxury Dubai cosmopolitan-emirate aesthetic", promptHint: "a Dubai modern aesthetic — Gulf-luxury vibe, polished cosmopolitan-emirate presence", term: "dubai modern aesthetic" },
827
+ { id: "persian-glam", label: "Persian Glam", group: "Middle East", dimension: "regional-aesthetic", description: "Iranian heritage-and-glamour Persian aesthetic", promptHint: "a Persian glam aesthetic — Iranian heritage-and-glamour vibe, refined statement mood", term: "persian glam aesthetic" },
828
+ { id: "istanbul-bosphorus", label: "Istanbul Bosphorus", group: "Middle East", dimension: "regional-aesthetic", description: "Istanbul east-meets-west Bosphorus Ottoman-and-modern aesthetic", promptHint: "an Istanbul Bosphorus aesthetic — east-meets-west Turkish vibe, layered Ottoman-and-modern strait-city presence", term: "istanbul bosphorus aesthetic" },
810
829
 
811
830
  // ----- North Africa -----
812
- { id: "cairene-cosmopolitan", label: "Cairene Cosmopolitan", group: "North Africa", dimension: "regional-aesthetic", description: "Cairo Egyptian-Arab metropolitan aesthetic", promptHint: "a Cairene cosmopolitan aesthetic — Cairo metropolitan vibe, layered Egyptian-Arab modern-and-historical mood" },
813
- { id: "maghreb-coastal", label: "Maghreb Coastal", group: "North Africa", dimension: "regional-aesthetic", description: "Tunis / Algiers French-Mediterranean-North-African colonial-port aesthetic", promptHint: "a Maghreb coastal aesthetic — Tunis / Algiers French-Mediterranean-North-African vibe, sun-bleached colonial-port mood" },
814
- { id: "marrakech-bohemian", label: "Marrakech Bohemian", group: "North Africa", dimension: "regional-aesthetic", description: "Marrakech Moroccan medina warm-spice aesthetic", promptHint: "a Marrakech bohemian aesthetic — Moroccan medina vibe, warm-spice and -textile mood" },
831
+ { id: "cairene-cosmopolitan", label: "Cairene Cosmopolitan", group: "North Africa", dimension: "regional-aesthetic", description: "Cairo Egyptian-Arab metropolitan aesthetic", promptHint: "a Cairene cosmopolitan aesthetic — Cairo metropolitan vibe, layered Egyptian-Arab modern-and-historical mood", term: "cairene cosmopolitan aesthetic" },
832
+ { id: "maghreb-coastal", label: "Maghreb Coastal", group: "North Africa", dimension: "regional-aesthetic", description: "Tunis / Algiers French-Mediterranean-North-African colonial-port aesthetic", promptHint: "a Maghreb coastal aesthetic — Tunis / Algiers French-Mediterranean-North-African vibe, sun-bleached colonial-port mood", term: "maghreb coastal aesthetic" },
833
+ { id: "marrakech-bohemian", label: "Marrakech Bohemian", group: "North Africa", dimension: "regional-aesthetic", description: "Marrakech Moroccan medina warm-spice aesthetic", promptHint: "a Marrakech bohemian aesthetic — Moroccan medina vibe, warm-spice and -textile mood", term: "marrakech bohemian aesthetic" },
815
834
 
816
835
  // ----- Sub-Saharan Africa -----
817
836
  // 🇬🇧 Anglophone, 🇫🇷 Francophone, 🇵🇹 Lusophone — colonial-cultural overlay
818
837
  // drives sartorial / media-diet differences. Ethiopia untagged (never colonized).
819
- { id: "lagos-afro-glam", label: "Lagos Afro-Glam", group: "Sub-Saharan Africa", dimension: "regional-aesthetic", description: "🇬🇧 Lagos Nigerian Anglophone-West-African metropolitan aesthetic", promptHint: "a Lagos Afro-glam aesthetic — Nigerian Anglophone-West-African metropolitan vibe, vibrant statement-fashion mood" },
820
- { id: "accra-afro-fashion", label: "Accra Afro-Fashion", group: "Sub-Saharan Africa", dimension: "regional-aesthetic", description: "🇬🇧 Accra Ghanaian Anglophone-West-African kente-meets-modern aesthetic", promptHint: "an Accra Afro-fashion aesthetic — Ghanaian Anglophone-West-African vibe, kente-meets-modern statement" },
821
- { id: "dakar-francophone", label: "Dakar Francophone", group: "Sub-Saharan Africa", dimension: "regional-aesthetic", description: "🇫🇷 Dakar Senegalese Francophone-West-African coastal-cosmopolitan aesthetic", promptHint: "a Dakar aesthetic — Senegalese Francophone-West-African coastal-cosmopolitan vibe, refined boubou-and-Paris-pull mood" },
822
- { id: "abidjan-cosmopolitan", label: "Abidjan Cosmopolitan", group: "Sub-Saharan Africa", dimension: "regional-aesthetic", description: "🇫🇷 Abidjan Ivoirian Francophone-West-African urban aesthetic", promptHint: "an Abidjan aesthetic — Ivoirian Francophone-West-African urban vibe, lagoon-city polish" },
823
- { id: "kinshasa-sape", label: "Kinshasa SAPE", group: "Sub-Saharan Africa", dimension: "regional-aesthetic", description: "🇫🇷 Kinshasa Congolese Francophone-Central-African SAPE dandy aesthetic", promptHint: "a Kinshasa SAPE aesthetic — Congolese Francophone-Central-African dandy vibe, Society-of-Ambianceurs hyper-tailored statement" },
824
- { id: "nairobi-cosmopolitan", label: "Nairobi Cosmopolitan", group: "Sub-Saharan Africa", dimension: "regional-aesthetic", description: "🇬🇧 Nairobi Kenyan Anglophone-East-African modern-urban aesthetic", promptHint: "a Nairobi cosmopolitan aesthetic — Kenyan Anglophone-East-African modern-urban vibe, considered creative-class polish" },
825
- { id: "addis-habesha", label: "Addis Habesha", group: "Sub-Saharan Africa", dimension: "regional-aesthetic", description: "Addis Ababa Ethiopian Habesha highland-heritage aesthetic (Ethiopia was never colonized)", promptHint: "an Addis Ababa Habesha aesthetic — Ethiopian highland heritage vibe, refined coffee-ceremony-and-modern-Addis polish" },
826
- { id: "swahili-coast", label: "Swahili Coast", group: "Sub-Saharan Africa", dimension: "regional-aesthetic", description: "🇬🇧 Zanzibar / Mombasa Anglophone-East-African coastal-Swahili aesthetic", promptHint: "a Swahili-Coast aesthetic — Zanzibar / Mombasa Anglophone-East-African coastal vibe, Indian-Ocean-trade-route warmth" },
827
- { id: "johannesburg-urban", label: "Johannesburg Urban", group: "Sub-Saharan Africa", dimension: "regional-aesthetic", description: "🇬🇧 Johannesburg South-African Anglophone-Southern-African Black-metropolitan aesthetic", promptHint: "a Johannesburg urban aesthetic — South-African Anglophone-Southern-African Black-metropolitan vibe, post-Soweto urban-creative confidence" },
828
- { id: "cape-town-cosmopolitan", label: "Cape Town Cosmopolitan", group: "Sub-Saharan Africa", dimension: "regional-aesthetic", description: "🇬🇧 Cape Town South-African Anglophone-Southern-African coastal-city aesthetic", promptHint: "a Cape Town cosmopolitan aesthetic — South-African Anglophone-Southern-African coastal-city vibe, easygoing creative polish" },
829
- { id: "luanda-lusophone", label: "Luanda Lusophone", group: "Sub-Saharan Africa", dimension: "regional-aesthetic", description: "🇵🇹 Luanda Angolan Lusophone-Southern-African kizomba-and-Atlantic-coast aesthetic", promptHint: "a Luanda aesthetic — Angolan Lusophone-Southern-African vibe, kizomba-and-Atlantic-coast statement-presence" },
838
+ { id: "lagos-afro-glam", label: "Lagos Afro-Glam", group: "Sub-Saharan Africa", dimension: "regional-aesthetic", description: "🇬🇧 Lagos Nigerian Anglophone-West-African metropolitan aesthetic", promptHint: "a Lagos Afro-glam aesthetic — Nigerian Anglophone-West-African metropolitan vibe, vibrant statement-fashion mood", term: "lagos afro-glam aesthetic" },
839
+ { id: "accra-afro-fashion", label: "Accra Afro-Fashion", group: "Sub-Saharan Africa", dimension: "regional-aesthetic", description: "🇬🇧 Accra Ghanaian Anglophone-West-African kente-meets-modern aesthetic", promptHint: "an Accra Afro-fashion aesthetic — Ghanaian Anglophone-West-African vibe, kente-meets-modern statement", term: "accra afro-fashion aesthetic" },
840
+ { id: "dakar-francophone", label: "Dakar Francophone", group: "Sub-Saharan Africa", dimension: "regional-aesthetic", description: "🇫🇷 Dakar Senegalese Francophone-West-African coastal-cosmopolitan aesthetic", promptHint: "a Dakar aesthetic — Senegalese Francophone-West-African coastal-cosmopolitan vibe, refined boubou-and-Paris-pull mood", term: "dakar francophone aesthetic" },
841
+ { id: "abidjan-cosmopolitan", label: "Abidjan Cosmopolitan", group: "Sub-Saharan Africa", dimension: "regional-aesthetic", description: "🇫🇷 Abidjan Ivoirian Francophone-West-African urban aesthetic", promptHint: "an Abidjan aesthetic — Ivoirian Francophone-West-African urban vibe, lagoon-city polish", term: "abidjan cosmopolitan aesthetic" },
842
+ { id: "kinshasa-sape", label: "Kinshasa SAPE", group: "Sub-Saharan Africa", dimension: "regional-aesthetic", description: "🇫🇷 Kinshasa Congolese Francophone-Central-African SAPE dandy aesthetic", promptHint: "a Kinshasa SAPE aesthetic — Congolese Francophone-Central-African dandy vibe, Society-of-Ambianceurs hyper-tailored statement", term: "kinshasa sape aesthetic" },
843
+ { id: "nairobi-cosmopolitan", label: "Nairobi Cosmopolitan", group: "Sub-Saharan Africa", dimension: "regional-aesthetic", description: "🇬🇧 Nairobi Kenyan Anglophone-East-African modern-urban aesthetic", promptHint: "a Nairobi cosmopolitan aesthetic — Kenyan Anglophone-East-African modern-urban vibe, considered creative-class polish", term: "nairobi cosmopolitan aesthetic" },
844
+ { id: "addis-habesha", label: "Addis Habesha", group: "Sub-Saharan Africa", dimension: "regional-aesthetic", description: "Addis Ababa Ethiopian Habesha highland-heritage aesthetic (Ethiopia was never colonized)", promptHint: "an Addis Ababa Habesha aesthetic — Ethiopian highland heritage vibe, refined coffee-ceremony-and-modern-Addis polish", term: "addis ababa habesha aesthetic" },
845
+ { id: "swahili-coast", label: "Swahili Coast", group: "Sub-Saharan Africa", dimension: "regional-aesthetic", description: "🇬🇧 Zanzibar / Mombasa Anglophone-East-African coastal-Swahili aesthetic", promptHint: "a Swahili-Coast aesthetic — Zanzibar / Mombasa Anglophone-East-African coastal vibe, Indian-Ocean-trade-route warmth", term: "swahili coast aesthetic" },
846
+ { id: "johannesburg-urban", label: "Johannesburg Urban", group: "Sub-Saharan Africa", dimension: "regional-aesthetic", description: "🇬🇧 Johannesburg South-African Anglophone-Southern-African Black-metropolitan aesthetic", promptHint: "a Johannesburg urban aesthetic — South-African Anglophone-Southern-African Black-metropolitan vibe, post-Soweto urban-creative confidence", term: "johannesburg urban aesthetic" },
847
+ { id: "cape-town-cosmopolitan", label: "Cape Town Cosmopolitan", group: "Sub-Saharan Africa", dimension: "regional-aesthetic", description: "🇬🇧 Cape Town South-African Anglophone-Southern-African coastal-city aesthetic", promptHint: "a Cape Town cosmopolitan aesthetic — South-African Anglophone-Southern-African coastal-city vibe, easygoing creative polish", term: "cape town cosmopolitan aesthetic" },
848
+ { id: "luanda-lusophone", label: "Luanda Lusophone", group: "Sub-Saharan Africa", dimension: "regional-aesthetic", description: "🇵🇹 Luanda Angolan Lusophone-Southern-African kizomba-and-Atlantic-coast aesthetic", promptHint: "a Luanda aesthetic — Angolan Lusophone-Southern-African vibe, kizomba-and-Atlantic-coast statement-presence", term: "luanda lusophone aesthetic" },
830
849
 
831
850
  // ----- Oceania -----
832
- { id: "bondi-beach", label: "Bondi Beach", group: "Oceania", dimension: "regional-aesthetic", description: "Bondi Australian coastal salt-and-sun aesthetic", promptHint: "a Bondi Beach aesthetic — Australian coastal vibe, salt-and-sun easygoing presence" },
833
- { id: "australian-outback", label: "Outback", group: "Oceania", dimension: "regional-aesthetic", description: "Rural Australian Outback aesthetic (feminine)", promptHint: "an Australian Outback aesthetic — rural Australian vibe, weathered sun-burnt confidence" },
834
- { id: "outback-stockman", label: "Outback Stockman", group: "Oceania", dimension: "regional-aesthetic", description: "Rural Australian Outback aesthetic (masculine)", promptHint: "an Outback Stockman aesthetic — rural Australian vibe, weathered station-hand presence" },
835
- { id: "auckland-coastal", label: "Auckland Coastal", group: "Oceania", dimension: "regional-aesthetic", description: "Auckland New Zealand harbor-city Pacific aesthetic", promptHint: "an Auckland coastal aesthetic — New Zealand harbor-city vibe, considered Pacific polish" },
851
+ { id: "bondi-beach", label: "Bondi Beach", group: "Oceania", dimension: "regional-aesthetic", description: "Bondi Australian coastal salt-and-sun aesthetic", promptHint: "a Bondi Beach aesthetic — Australian coastal vibe, salt-and-sun easygoing presence", term: "bondi beach aesthetic" },
852
+ { id: "australian-outback", label: "Outback", group: "Oceania", dimension: "regional-aesthetic", description: "Rural Australian Outback aesthetic (feminine)", promptHint: "an Australian Outback aesthetic — rural Australian vibe, weathered sun-burnt confidence", term: "australian outback aesthetic" },
853
+ { id: "outback-stockman", label: "Outback Stockman", group: "Oceania", dimension: "regional-aesthetic", description: "Rural Australian Outback aesthetic (masculine)", promptHint: "an Outback Stockman aesthetic — rural Australian vibe, weathered station-hand presence", term: "outback stockman aesthetic" },
854
+ { id: "auckland-coastal", label: "Auckland Coastal", group: "Oceania", dimension: "regional-aesthetic", description: "Auckland New Zealand harbor-city Pacific aesthetic", promptHint: "an Auckland coastal aesthetic — New Zealand harbor-city vibe, considered Pacific polish", term: "auckland coastal aesthetic" },
836
855
  ] as const
837
856
 
838
857
  export const PERSON_DIMENSION_ORDER: ReadonlyArray<PersonDimension> = [
@@ -1111,11 +1130,27 @@ export interface PersonValue {
1111
1130
  postText?: string
1112
1131
  }
1113
1132
 
1114
- const personById = new Map<string, Person>(PEOPLE.map((p) => [p.id, p]))
1133
+ // The person id → entry index reads the REGISTERED (pack-composed) person set,
1134
+ // memoized on the person-pack registry version so late registration is seen.
1135
+ // The import is cycle-safe: person-packs.ts imports PEOPLE from this module but
1136
+ // only reads it inside function bodies, and this module only calls the
1137
+ // registered accessors inside functions (never at module-eval time).
1138
+ let _personMemo: { v: number; map: Map<string, Person> } | null = null
1139
+ function personIndex(): Map<string, Person> {
1140
+ const v = personPacksVersion()
1141
+ if (_personMemo && _personMemo.v === v) return _personMemo.map
1142
+ const map = new Map<string, Person>()
1143
+ // Pack entries widen `dimension` to a string outside the closed union; every
1144
+ // field getPerson's callers read (label/description/promptHint/group) is
1145
+ // shared, so the structural cast is safe.
1146
+ for (const p of getRegisteredPeople()) map.set(p.id, p as Person)
1147
+ _personMemo = { v, map }
1148
+ return map
1149
+ }
1115
1150
 
1116
1151
  export function getPerson(id: string | undefined | null): Person | undefined {
1117
1152
  if (!id) return undefined
1118
- return personById.get(id)
1153
+ return personIndex().get(id)
1119
1154
  }
1120
1155
 
1121
1156
  export function getPersonLabel(id: string | undefined | null, fallback?: string): string {
@@ -1129,6 +1164,17 @@ export function getPersonPromptHint(id: string | undefined | null): string {
1129
1164
  return getPerson(id)?.promptHint ?? ""
1130
1165
  }
1131
1166
 
1167
+ /**
1168
+ * The COMPACT counterpart of `getPersonPromptHint`: the short professional
1169
+ * term ("brown hair", "aquiline nose", "of nordic scandinavian descent") a
1170
+ * consumer injects instead of the full mechanism description. Same lookup,
1171
+ * same empty-string-on-miss behavior, so the two can never disagree about
1172
+ * which entry they are describing.
1173
+ */
1174
+ export function getPersonTerm(id: string | undefined | null): string {
1175
+ return resolveTerm(getPerson(id))
1176
+ }
1177
+
1132
1178
  export const PERSON_IDS: ReadonlyArray<string> = PEOPLE.map((p) => p.id)
1133
1179
 
1134
1180
  /**
@@ -1163,15 +1209,23 @@ function normalizePickIds(value: unknown): string[] {
1163
1209
  return out
1164
1210
  }
1165
1211
 
1166
- function buildEthnicityHint(value: unknown): string {
1212
+ /**
1213
+ * How ONE selected id turns into a fragment: `getPersonPromptHint` in verbose
1214
+ * mode, `getPersonTerm` in compact mode. Threaded through every builder below
1215
+ * so the two modes can never disagree about WHICH ids contribute or in what
1216
+ * order — only about how each one is phrased.
1217
+ */
1218
+ type PersonFragmentFor = (id: string | undefined | null) => string
1219
+
1220
+ function buildEthnicityFragment(value: unknown, fragmentFor: PersonFragmentFor): string {
1167
1221
  const ids = normalizePickIds(value)
1168
1222
  if (ids.length === 0) return ""
1169
- if (ids.length === 1) return getPersonPromptHint(ids[0])
1223
+ if (ids.length === 1) return fragmentFor(ids[0])
1170
1224
  const labels = ids
1171
1225
  .slice(0, 2)
1172
1226
  .map((id) => getPerson(id)?.shortLabel ?? getPerson(id)?.label ?? "")
1173
1227
  .filter((s): s is string => Boolean(s))
1174
- if (labels.length < 2) return getPersonPromptHint(ids[0])
1228
+ if (labels.length < 2) return fragmentFor(ids[0])
1175
1229
  return `of mixed ${labels[0]} and ${labels[1]} heritage`
1176
1230
  }
1177
1231
 
@@ -1180,15 +1234,15 @@ function buildEthnicityHint(value: unknown): string {
1180
1234
  * "two-tone X and Y hair" using lowercased entry labels (covers ombre,
1181
1235
  * balayage, highlights, dyed two-tone styles).
1182
1236
  */
1183
- function buildHairColorHint(value: unknown): string {
1237
+ function buildHairColorFragment(value: unknown, fragmentFor: PersonFragmentFor): string {
1184
1238
  const ids = normalizePickIds(value)
1185
1239
  if (ids.length === 0) return ""
1186
- if (ids.length === 1) return getPersonPromptHint(ids[0])
1240
+ if (ids.length === 1) return fragmentFor(ids[0])
1187
1241
  const labels = ids
1188
1242
  .slice(0, 2)
1189
1243
  .map((id) => getPerson(id)?.label?.toLowerCase() ?? "")
1190
1244
  .filter((s): s is string => Boolean(s))
1191
- if (labels.length < 2) return getPersonPromptHint(ids[0])
1245
+ if (labels.length < 2) return fragmentFor(ids[0])
1192
1246
  return `two-tone ${labels[0]} and ${labels[1]} hair`
1193
1247
  }
1194
1248
 
@@ -1202,8 +1256,8 @@ function buildHairColorHint(value: unknown): string {
1202
1256
  * heterochromia look should add the `feature-heterochromia` distinctive
1203
1257
  * feature alongside the two color picks.
1204
1258
  */
1205
- function buildEyeColorHints(value: unknown): string[] {
1206
- return emitIndependentHints(value)
1259
+ function buildEyeColorFragments(value: unknown, fragmentFor: PersonFragmentFor): string[] {
1260
+ return emitIndependentFragments(value, fragmentFor)
1207
1261
  }
1208
1262
 
1209
1263
  /**
@@ -1219,7 +1273,20 @@ export function buildAgeHint(
1219
1273
  ageId: string | undefined | null,
1220
1274
  customAge: number | undefined | null,
1221
1275
  ): string {
1222
- if (ageId !== "age-custom") return getPersonPromptHint(ageId)
1276
+ return buildAgeFragment(ageId, customAge, getPersonPromptHint)
1277
+ }
1278
+
1279
+ /**
1280
+ * `buildAgeHint` parameterized by how a catalog age id is phrased. The
1281
+ * custom-numeric branch is mode-independent — "34 years old" is already the
1282
+ * compact professional phrasing — so only the catalog lookup differs.
1283
+ */
1284
+ function buildAgeFragment(
1285
+ ageId: string | undefined | null,
1286
+ customAge: number | undefined | null,
1287
+ fragmentFor: PersonFragmentFor,
1288
+ ): string {
1289
+ if (ageId !== "age-custom") return fragmentFor(ageId)
1223
1290
  if (typeof customAge !== "number" || !Number.isFinite(customAge)) return ""
1224
1291
  const n = Math.max(0, Math.min(120, Math.round(customAge)))
1225
1292
  if (n === 0) return "a newborn under 1 year old"
@@ -1239,7 +1306,7 @@ export function buildAgeHint(
1239
1306
  * clause, so we emit them all separately and let buildPersonHints'
1240
1307
  * comma-join read naturally.
1241
1308
  */
1242
- function emitIndependentHints(value: unknown): string[] {
1309
+ function emitIndependentFragments(value: unknown, fragmentFor: PersonFragmentFor): string[] {
1243
1310
  const ids = normalizePickIds(value)
1244
1311
  const out: string[] = []
1245
1312
  // Skin-exposure clauses COMPOUND in providers' output-safety classifiers:
@@ -1254,42 +1321,53 @@ function emitIndependentHints(value: unknown): string[] {
1254
1321
  if (id === "feature-midriff-visible") out.push("wearing a cropped style, midriff and navel visible")
1255
1322
  continue
1256
1323
  }
1257
- const hint = getPersonPromptHint(id)
1258
- if (hint) out.push(hint)
1324
+ const fragment = fragmentFor(id)
1325
+ if (fragment) out.push(fragment)
1259
1326
  }
1260
1327
  return out
1261
1328
  }
1262
1329
 
1263
- export function buildPersonHints(
1330
+ /**
1331
+ * The one walk over the per-dimension person fields, parameterized by how a
1332
+ * single selected id turns into a fragment. `buildPersonHints` (verbose) and
1333
+ * `buildPersonTerms` (compact) both delegate here, so the dimension order, the
1334
+ * multi-pick composition rules (mixed heritage, two-tone hair, the
1335
+ * midriff+navel fold), the custom-age numeric branch, the legacy `lips`
1336
+ * fallback and the pre/post free text are shared by construction.
1337
+ */
1338
+ function collectPersonFragments(
1264
1339
  data: Record<string, unknown> & PersonValue,
1340
+ fragmentFor: PersonFragmentFor,
1265
1341
  ): string[] {
1266
1342
  const hints: string[] = []
1267
1343
 
1268
1344
  const pre = typeof data.preText === "string" ? data.preText.trim() : ""
1269
1345
  if (pre) hints.push(pre)
1270
1346
 
1271
- for (const dimension of PERSON_DIMENSION_ORDER) {
1272
- const field = PERSON_FIELD_BY_DIMENSION[dimension]
1347
+ const fieldByDimension = getRegisteredPersonFieldByDimension()
1348
+ for (const dimension of getRegisteredPersonDimensionOrder()) {
1349
+ const field = fieldByDimension[dimension]
1350
+ if (!field) continue
1273
1351
  const raw = data[field]
1274
1352
  if (dimension === "age") {
1275
1353
  const ageId = typeof raw === "string" ? raw : undefined
1276
1354
  const customAge = typeof data.customAge === "number" ? data.customAge : undefined
1277
- const h = buildAgeHint(ageId, customAge)
1355
+ const h = buildAgeFragment(ageId, customAge, fragmentFor)
1278
1356
  if (h) hints.push(h)
1279
1357
  continue
1280
1358
  }
1281
1359
  if (dimension === "ethnicity") {
1282
- const h = buildEthnicityHint(raw)
1360
+ const h = buildEthnicityFragment(raw, fragmentFor)
1283
1361
  if (h) hints.push(h)
1284
1362
  continue
1285
1363
  }
1286
1364
  if (dimension === "hair-color") {
1287
- const h = buildHairColorHint(raw)
1365
+ const h = buildHairColorFragment(raw, fragmentFor)
1288
1366
  if (h) hints.push(h)
1289
1367
  continue
1290
1368
  }
1291
1369
  if (dimension === "eye-color") {
1292
- for (const h of buildEyeColorHints(raw)) hints.push(h)
1370
+ for (const h of buildEyeColorFragments(raw, fragmentFor)) hints.push(h)
1293
1371
  continue
1294
1372
  }
1295
1373
  if (
@@ -1299,11 +1377,11 @@ export function buildPersonHints(
1299
1377
  dimension === "skin-texture" ||
1300
1378
  dimension === "regional-aesthetic"
1301
1379
  ) {
1302
- for (const h of emitIndependentHints(raw)) hints.push(h)
1380
+ for (const h of emitIndependentFragments(raw, fragmentFor)) hints.push(h)
1303
1381
  continue
1304
1382
  }
1305
1383
  if (typeof raw !== "string" || raw.length === 0) continue
1306
- const hint = getPersonPromptHint(raw)
1384
+ const hint = fragmentFor(raw)
1307
1385
  if (hint) hints.push(hint)
1308
1386
  }
1309
1387
 
@@ -1318,7 +1396,7 @@ export function buildPersonHints(
1318
1396
  !data.lipFullness &&
1319
1397
  !data.lipShape
1320
1398
  ) {
1321
- const legacyLips = getPersonPromptHint(data.lips)
1399
+ const legacyLips = fragmentFor(data.lips)
1322
1400
  if (legacyLips) hints.push(legacyLips)
1323
1401
  }
1324
1402
 
@@ -1328,6 +1406,26 @@ export function buildPersonHints(
1328
1406
  return hints
1329
1407
  }
1330
1408
 
1409
+ export function buildPersonHints(
1410
+ data: Record<string, unknown> & PersonValue,
1411
+ mode: PickerHintMode = "full",
1412
+ ): string[] {
1413
+ if (mode === "compact") return buildPersonTerms(data)
1414
+ return collectPersonFragments(data, getPersonPromptHint)
1415
+ }
1416
+
1417
+ /**
1418
+ * The COMPACT counterpart of `buildPersonHints`: the same per-dimension walk
1419
+ * in the same canonical order, emitting each selection's short professional
1420
+ * term ("in their 30s", "of east asian descent", "long wavy hair", "brown
1421
+ * hair", "fair skin", "green eyes") instead of its full mechanism description.
1422
+ */
1423
+ export function buildPersonTerms(
1424
+ data: Record<string, unknown> & PersonValue,
1425
+ ): string[] {
1426
+ return collectPersonFragments(data, getPersonTerm)
1427
+ }
1428
+
1331
1429
  // Legacy → new field relocation tables for `migratePersonValue`. The old
1332
1430
  // single `eye-shape` dimension crammed shape + lid + tilt + spacing into one
1333
1431
  // pick, and `lips` crammed fullness + shape; both were split. Ids were kept