+
+ New Genlocke
+
+
+ Set up your generational challenge.
+
+
+
+
+ {/* Step 1: Name */}
+ {step === 1 && (
+
+
+ Name Your Genlocke
+
+
+
+ setName(e.target.value)}
+ className="w-full px-3 py-2 rounded-lg border border-gray-300 dark:border-gray-600 bg-white dark:bg-gray-700 text-gray-900 dark:text-gray-100 focus:outline-none focus:ring-2 focus:ring-blue-500 focus:border-transparent"
+ placeholder="My Genlocke"
+ maxLength={100}
+ autoFocus
+ />
+
+
+
+
+
+
+ )}
+
+ {/* Step 2: Game Selection */}
+ {step === 2 && (
+
+
+ Select Games
+
+
+ {/* Preset buttons */}
+
+ {(['true', 'normal', 'custom'] as const).map((type) => {
+ const labels = {
+ true: 'True Genlocke',
+ normal: 'Normal Genlocke',
+ custom: 'Custom',
+ }
+ const descriptions = {
+ true: 'Original releases only',
+ normal: 'Latest version per region',
+ custom: 'Build your own',
+ }
+ const isActive = preset === type
+ return (
+
+ )
+ })}
+
+
+ {regionsLoading && (
+
+ )}
+
+ {/* Legs list */}
+ {legs.length > 0 && (
+
+ {legs.map((leg, index) => (
+ handleGameChange(index, game)}
+ onRemove={() => handleRemoveLeg(index)}
+ onMove={(dir) => handleMoveLeg(index, dir)}
+ />
+ ))}
+
+ )}
+
+ {/* Add leg button */}
+ {preset === 'custom' && availableRegions.length > 0 && (
+
+ )}
+
+ {/* Also allow adding extra regions for presets */}
+ {preset && preset !== 'custom' && availableRegions.length > 0 && legs.length > 0 && (
+
+ )}
+
+
+
+
+
+
+ )}
+
+ {/* Step 3: Rules */}
+ {step === 3 && (
+
+
+
+ {/* Genlocke-specific rules */}
+
+
+
+ Genlocke Rules
+
+
+ Rules specific to the generational challenge
+
+
+
+
+
+
+
+
+
+
+
+
+ )}
+
+ {/* Step 4: Confirm */}
+ {step === 4 && (
+
+
+ Confirm & Start
+
+
+
+
+
+
+
+ Legs ({legs.length})
+
+
+ {legs.map((leg, i) => (
+ -
+
+ {i + 1}.
+
+
+
+
+ {leg.game.name}
+
+
+ {leg.region.charAt(0).toUpperCase() + leg.region.slice(1)}
+
+
+
+ ))}
+
+
+
+
+
+ Rules
+
+
+
+
- Nuzlocke Rules
+ -
+ {enabledRuleCount} of {totalRuleCount} enabled
+
+
+
+
- Hall of Fame
+ -
+ {genlockeRules.retireHoF ? 'Retire' : 'Keep'}
+
+
+
+
+
+
+ {createGenlocke.error && (
+
+ Failed to create genlocke. Please try again.
+
+ )}
+
+
+
+
+
+
+ )}
+
+ )
+}
+
+// --- Sub-components ---
+
+function LegRow({
+ leg,
+ index,
+ total,
+ regions,
+ onGameChange,
+ onRemove,
+ onMove,
+}: {
+ leg: LegEntry
+ index: number
+ total: number
+ regions: Region[]
+ onGameChange: (game: Game) => void
+ onRemove: () => void
+ onMove: (dir: 'up' | 'down') => void
+}) {
+ const region = regions.find((r) => r.name === leg.region)
+ const games = region?.games ?? []
+
+ return (
+
+
+ Select a region to add
+
+
+ {regions.map((region) => (
+
+ ))}
+
+
+
+ )
+}
+
+function GameThumb({ game }: { game: Game }) {
+ const [imgIdx, setImgIdx] = useState(0)
+ const backgroundColor = game.color ?? DEFAULT_COLOR
+ const boxArtSrcs = [`/boxart/${game.slug}.png`, `/boxart/${game.slug}.jpg`]
+
+ if (imgIdx >= boxArtSrcs.length) {
+ return (
+