Yasss, this is a great base. I kept your flow + cards + saved-names, and upgraded it to a 3-step wizard (Name Style → Randomness → Brand Info + Domain Filters) with the subtitle under the H1, and a richer payload for your generator. It still works as a single page (no routing), and preserves your localStorage favorites.

Here’s the full updated component (drop-in replacement):

import React, { useState, useEffect } from 'react';
import { Button } from '@/components/ui/button';
import { Input } from '@/components/ui/input';
import { Label } from '@/components/ui/label';
import { Card, CardContent } from '@/components/ui/card';
import { Slider } from '@/components/ui/slider';
import { Switch } from '@/components/ui/switch';
import { Badge } from '@/components/ui/badge';
import { Tabs, TabsList, TabsTrigger, TabsContent } from '@/components/ui/tabs';
import { Wand2, Check, X, Heart, Loader2, ArrowRight } from 'lucide-react';
import { generateBusinessNames, type GeneratedBusinessName, type BusinessNameStyle } from '@/services/ai/business-names';
import { useLocation } from 'wouter';
import { useAuth } from '@/contexts/AuthContext';

type Randomness = 'low' | 'medium' | 'high';

type Vibe = 'modern' | 'professional' | 'creative' | 'playful' | 'luxury' | 'techy' | 'organic';
type DomainTLD = '.com' | '.co' | '.ai' | '.io' | '.app';

export default function BusinessName() {
  const [industry, setIndustry] = useState('');
  const [keywords, setKeywords] = useState('');
  const [description, setDescription] = useState('');
  const [selectedStyle, setSelectedStyle] = useState<BusinessNameStyle>('Modern');

  const [randomness, setRandomness] = useState<Randomness>('medium');

  const [vibes, setVibes] = useState<Vibe[]>(['modern']);
  const [lengthRange, setLengthRange] = useState<[number, number]>([6, 10]);
  const [startsWith, setStartsWith] = useState('');
  const [mustInclude, setMustInclude] = useState('');
  const [mustExclude, setMustExclude] = useState('');
  const [tlds, setTlds] = useState<DomainTLD[]>(['.com', '.ai']);
  const [requireAvailable, setRequireAvailable] = useState(true);

  const [isGenerating, setIsGenerating] = useState(false);
  const [generatedNames, setGeneratedNames] = useState<GeneratedBusinessName[]>([]);
  const [savedNames, setSavedNames] = useState<GeneratedBusinessName[]>([]);
  const [, setLocation] = useLocation();
  const { currentUser } = useAuth();

  // Keep your original 5 styles for continuity
  const styles: BusinessNameStyle[] = ['Modern', 'Classic', 'Creative', 'Professional', 'Playful'];

  // Local storage key for saved names
  const SAVED_NAMES_KEY = 'ibrandbiz-saved-names';

  // Load saved names from localStorage on component mount
  useEffect(() => {
    try {
      const saved = localStorage.getItem(SAVED_NAMES_KEY);
      if (saved) setSavedNames(JSON.parse(saved));
    } catch (error) {
      console.error('Error loading saved names:', error);
    }
  }, []);

  // Save to localStorage whenever savedNames changes
  useEffect(() => {
    try {
      localStorage.setItem(SAVED_NAMES_KEY, JSON.stringify(savedNames));
    } catch (error) {
      console.error('Error saving names to localStorage:', error);
    }
  }, [savedNames]);

  const toggleSave = (nameData: GeneratedBusinessName) => {
    setSavedNames(prev => {
      const isAlreadySaved = prev.some(saved => saved.name === nameData.name);
      return isAlreadySaved ? prev.filter(s => s.name !== nameData.name) : [...prev, nameData];
    });
  };

  const isNameSaved = (name: string) => savedNames.some(s => s.name === name);

  const sendToBrandKit = (businessName: string) => {
    setLocation(`/brand-kit?name=${encodeURIComponent(businessName)}`);
  };

  const goToDomains = (businessName: string) => {
    setLocation(`/domains?search=${encodeURIComponent(businessName.toLowerCase())}`);
  };

  const toggleArrayValue = <T,>(arr: T[], value: T): T[] =>
    arr.includes(value) ? arr.filter(v => v !== value) : [...arr, value];

  const handleGenerateNames = async () => {
    if (!industry.trim() || !keywords.trim()) {
      alert('Please enter both industry and keywords to generate names.');
      return;
    }

    setIsGenerating(true);
    setGeneratedNames([]);

    try {
      const payload = {
        industry: industry.trim(),
        keywords: keywords.trim(),
        style: selectedStyle,            // your legacy style
        count: 12,                       // give more to feel “wizard-y”
        // New enrichments (your service can safely ignore unknown keys)
        randomness,
        description: description.trim() || undefined,
        vibe: vibes,
        length_range: lengthRange,
        starts_with: startsWith.trim() || undefined,
        must_include: mustInclude.trim(),
        must_exclude: mustExclude.trim(),
        tlds,
        require_available: requireAvailable,
      };

      const names = await generateBusinessNames(payload as any);
      setGeneratedNames(names);
    } catch (error) {
      console.error('Failed to generate names:', error);
      alert('Failed to generate business names. Please try again.');
    } finally {
      setIsGenerating(false);
    }
  };

  return (
    <div className="space-y-6">
      {/* Header */}
      <div className="flex items-center justify-between">
        <div>
          <h2 className="text-3xl font-bold text-dark">Business Name Wizard</h2>
          <p className="text-muted-foreground mt-2">
            Find the perfect name for your business with AI-powered suggestions
          </p>
        </div>
      </div>

      {/* Generator */}
      <Card>
        <div className="p-6 border-b border-border">
          <h3 className="text-xl font-semibold text-dark">Generate Business Names</h3>
          <p className="text-base font-semibold text-ibrand-dark-blue mt-2">
            Create a short, brandable business name using artificial intelligence
          </p>
        </div>

        <CardContent className="p-6 space-y-6">
          {/* Wizard Tabs */}
          <Tabs defaultValue="style" className="w-full">
            <TabsList className="grid grid-cols-3 w-full md:w-auto">
              <TabsTrigger value="style">Name Style</TabsTrigger>
              <TabsTrigger value="randomness">Randomness</TabsTrigger>
              <TabsTrigger value="brand">Brand Info & Domains</TabsTrigger>
            </TabsList>

            {/* STYLE */}
            <TabsContent value="style" className="space-y-6">
              <div className="grid grid-cols-1 md:grid-cols-2 gap-6">
                <div>
                  <Label htmlFor="industry-category" className="block text-sm font-medium text-foreground mb-2">
                    Industry/Category
                  </Label>
                  <Input
                    id="industry-category"
                    type="text"
                    placeholder="e.g., Coffee Shop, Tech Startup, Consulting"
                    value={industry}
                    onChange={(e) => setIndustry(e.target.value)}
                    data-testid="input-industry"
                  />
                </div>
                <div>
                  <Label htmlFor="keywords" className="block text-sm font-medium text-foreground mb-2">
                    Keywords
                  </Label>
                  <Input
                    id="keywords"
                    type="text"
                    placeholder="e.g., fast, reliable, premium"
                    value={keywords}
                    onChange={(e) => setKeywords(e.target.value)}
                    data-testid="input-keywords"
                  />
                </div>
              </div>

              <div>
                <Label className="block text-sm font-medium text-foreground mb-2">Style Preference</Label>
                <div className="grid grid-cols-2 md:grid-cols-5 gap-3">
                  {styles.map((style) => (
                    <button
                      key={style}
                      onClick={() => setSelectedStyle(style)}
                      className={`p-3 border rounded-lg text-center transition-colors ${
                        selectedStyle === style
                          ? 'border-primary bg-primary/5'
                          : 'border-border hover:border-primary hover:bg-primary/5'
                      }`}
                      data-testid={`button-style-${style.toLowerCase()}`}
                      disabled={isGenerating}
                    >
                      <span className="text-sm">{style}</span>
                    </button>
                  ))}
                </div>
              </div>
            </TabsContent>

            {/* RANDOMNESS */}
            <TabsContent value="randomness" className="space-y-4">
              <Label className="block text-sm font-medium text-foreground">Select generation randomness</Label>
              <div className="grid grid-cols-1 md:grid-cols-3 gap-3">
                {(['low', 'medium', 'high'] as Randomness[]).map(r => (
                  <button
                    key={r}
                    onClick={() => setRandomness(r)}
                    className={`p-3 border rounded-lg text-left transition-colors ${
                      randomness === r ? 'border-primary bg-primary/5' : 'border-border hover:border-primary/50'
                    }`}
                    disabled={isGenerating}
                  >
                    <div className="font-medium capitalize">{r}</div>
                    <div className="text-xs text-muted-foreground">
                      {r === 'low' && 'Less random. The most direct name ideas.'}
                      {r === 'medium' && 'Balanced. More creative results.'}
                      {r === 'high' && 'Wildcard. More varied results.'}
                    </div>
                  </button>
                ))}
              </div>
            </TabsContent>

            {/* BRAND INFO & DOMAINS */}
            <TabsContent value="brand" className="space-y-6">
              <div className="grid grid-cols-1 md:grid-cols-2 gap-6">
                <div>
                  <Label className="block text-sm font-medium text-foreground mb-2">Business description (optional)</Label>
                  <Input
                    type="text"
                    placeholder="One sentence about what you do or for whom"
                    value={description}
                    onChange={(e) => setDescription(e.target.value)}
                  />
                </div>

                <div>
                  <Label className="block text-sm font-medium text-foreground mb-2">Starts with (optional)</Label>
                  <Input
                    type="text"
                    placeholder="e.g., A, Neo, Omni"
                    value={startsWith}
                    onChange={(e) => setStartsWith(e.target.value)}
                  />
                </div>
              </div>

              <div className="grid grid-cols-1 md:grid-cols-2 gap-6">
                <div>
                  <Label className="block text-sm font-medium text-foreground mb-2">Must include (comma separated)</Label>
                  <Input
                    type="text"
                    placeholder="e.g., lab, cloud"
                    value={mustInclude}
                    onChange={(e) => setMustInclude(e.target.value)}
                  />
                </div>
                <div>
                  <Label className="block text-sm font-medium text-foreground mb-2">Must NOT include (comma separated)</Label>
                  <Input
                    type="text"
                    placeholder="e.g., tech, corp"
                    value={mustExclude}
                    onChange={(e) => setMustExclude(e.target.value)}
                  />
                </div>
              </div>

              <div className="grid grid-cols-1 md:grid-cols-2 gap-6">
                <div>
                  <Label className="block text-sm font-medium text-foreground mb-2">Vibe</Label>
                  <div className="flex flex-wrap gap-2">
                    {(['modern','professional','creative','playful','luxury','techy','organic'] as Vibe[]).map(v => (
                      <Badge
                        key={v}
                        variant={vibes.includes(v) ? 'default' : 'secondary'}
                        className="cursor-pointer capitalize"
                        onClick={() => setVibes(prev => toggleArrayValue(prev, v))}
                      >
                        {v}
                      </Badge>
                    ))}
                  </div>
                </div>

                <div>
                  <Label className="block text-sm font-medium text-foreground mb-2">Name length (characters)</Label>
                  <div className="px-1">
                    <Slider
                      min={4}
                      max={14}
                      step={1}
                      value={lengthRange}
                      onValueChange={(v) => setLengthRange([v[0], v[1]] as [number, number])}
                    />
                    <div className="text-xs text-muted-foreground mt-2">
                      {lengthRange[0]} – {lengthRange[1]} chars
                    </div>
                  </div>
                </div>
              </div>

              <div className="grid grid-cols-1 md:grid-cols-2 gap-6">
                <div>
                  <Label className="block text-sm font-medium text-foreground mb-2">Preferred TLDs</Label>
                  <div className="flex flex-wrap gap-2">
                    {(['.com','.co','.ai','.io','.app'] as DomainTLD[]).map(ext => (
                      <Badge
                        key={ext}
                        variant={tlds.includes(ext) ? 'default' : 'secondary'}
                        className="cursor-pointer"
                        onClick={() => setTlds(prev => toggleArrayValue(prev, ext))}
                      >
                        {ext}
                      </Badge>
                    ))}
                  </div>
                </div>

                <div className="flex items-center gap-3">
                  <Switch checked={requireAvailable} onCheckedChange={setRequireAvailable} />
                  <div>
                    <div className="text-sm font-medium">Require available domain</div>
                    <div className="text-xs text-muted-foreground">
                      Filter out names without an available domain in selected TLDs
                    </div>
                  </div>
                </div>
              </div>
            </TabsContent>
          </Tabs>

          <Button
            onClick={handleGenerateNames}
            className="bg-primary hover:bg-primary/90 text-white font-bold"
            data-testid="button-generate-names"
            disabled={isGenerating}
          >
            {isGenerating ? <Loader2 className="mr-2 h-4 w-4 animate-spin" /> : <Wand2 className="mr-2 h-4 w-4" />}
            {isGenerating ? 'Generating...' : 'Generate Names'}
          </Button>
        </CardContent>
      </Card>

      {/* Generated Names */}
      <Card>
        <div className="p-6 border-b border-border">
          <h3 className="text-xl font-semibold text-dark">Generated Names</h3>
          <p className="text-muted-foreground mt-1">Click on any name to create a brand kit</p>
        </div>
        <CardContent className="p-6">
          {generatedNames.length === 0 && !isGenerating ? (
            <div className="text-center py-8">
              <p className="text-muted-foreground">
                Generate business names using the form above to see suggestions here.
              </p>
            </div>
          ) : isGenerating ? (
            <div className="text-center py-8">
              <Loader2 className="h-8 w-8 animate-spin mx-auto mb-4" />
              <p className="text-muted-foreground">Generating creative business names...</p>
            </div>
          ) : (
            <div className="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-4">
              {generatedNames.map((nameData, index) => (
                <div
                  key={`${nameData.name}-${index}`}
                  className="border border-border rounded-lg p-4 hover:border-primary hover:bg-primary/5 transition-colors cursor-pointer"
                  data-testid={`card-name-${index}`}
                  onClick={() => sendToBrandKit(nameData.name)}
                >
                  <div className="flex items-center justify-between">
                    <h4 className="font-semibold text-foreground">{nameData.name}</h4>
                    <button
                      className="p-1 rounded transition-colors hover:bg-gray-100"
                      onClick={(e) => {
                        e.stopPropagation();
                        toggleSave(nameData);
                      }}
                      data-testid={`button-save-${index}`}
                      data-saved={isNameSaved(nameData.name)}
                      aria-label={isNameSaved(nameData.name) ? 'Remove from saved' : 'Save this name'}
                    >
                      <Heart
                        className={`h-4 w-4 transition-colors ${
                          isNameSaved(nameData.name) ? 'text-red-500 fill-red-500' : 'text-muted-foreground hover:text-red-500'
                        }`}
                      />
                    </button>
                  </div>

                  {nameData.description && (
                    <p className="text-xs text-muted-foreground mt-1">{nameData.description}</p>
                  )}

                  {/* Domain badges: show .com plus any extra TLDs if your API returns them */}
                  <div className="flex items-center mt-2 gap-2 flex-wrap">
                    <span
                      className={`inline-flex items-center px-2 py-1 rounded-full text-xs ${
                        nameData.available ? 'bg-accent/10 text-accent' : 'bg-red-100 text-red-600'
                      }`}
                    >
                      {nameData.available ? <Check className="mr-1 h-3 w-3" /> : <X className="mr-1 h-3 w-3" />}
                      .com {nameData.available ? 'Available' : 'Taken'}
                    </span>

                    {/* If your backend adds tldAvailability: Record<'.ai'|'.io'|... , boolean> */}
                    {Array.isArray((nameData as any).tldBadges) &&
                      (nameData as any).tldBadges.map(
                        (b: { tld: string; available: boolean }, i: number) => (
                          <span
                            key={`${b.tld}-${i}`}
                            className={`inline-flex items-center px-2 py-1 rounded-full text-xs ${
                              b.available ? 'bg-accent/10 text-accent' : 'bg-red-100 text-red-600'
                            }`}
                          >
                            {b.available ? <Check className="mr-1 h-3 w-3" /> : <X className="mr-1 h-3 w-3" />}
                            {b.tld} {b.available ? 'Available' : 'Taken'}
                          </span>
                        )
                      )}
                  </div>
                </div>
              ))}
            </div>
          )}
        </CardContent>
      </Card>

      {/* Saved Names */}
      <Card>
        <div className="p-6 border-b border-border">
          <h3 className="text-xl font-semibold text-dark">Saved Names ({savedNames.length})</h3>
          <p className="text-muted-foreground mt-1">Your favorite business name ideas</p>
        </div>
        <CardContent className="p-6">
          {savedNames.length === 0 ? (
            <div className="text-center py-8">
              <p className="text-muted-foreground">
                No saved names yet. Save your favorites by clicking the heart icon on any generated name!
              </p>
            </div>
          ) : (
            <div className="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-4">
              {savedNames.map((nameData, index) => (
                <div
                  key={`${nameData.name}-saved-${index}`}
                  className="border border-border rounded-lg p-4 hover:border-primary hover:bg-primary/5 transition-colors"
                  data-testid={`saved-name-${index}`}
                >
                  <div className="flex items-center justify-between">
                    <h4 className="font-semibold text-foreground">{nameData.name}</h4>
                    <button
                      className="p-1 rounded transition-colors hover:bg-gray-100"
                      onClick={() => toggleSave(nameData)}
                      data-testid={`button-unsave-${index}`}
                      aria-label="Remove from saved"
                    >
                      <Heart className="h-4 w-4 text-red-500 fill-red-500" />
                    </button>
                  </div>

                  {nameData.description && (
                    <p className="text-xs text-muted-foreground mt-1">{nameData.description}</p>
                  )}

                  <div className="flex items-center justify-between mt-3">
                    <span
                      className={`inline-flex items-center px-2 py-1 rounded-full text-xs ${
                        nameData.available ? 'bg-accent/10 text-accent' : 'bg-red-100 text-red-600'
                      }`}
                    >
                      {nameData.available ? <Check className="mr-1 h-3 w-3" /> : <X className="mr-1 h-3 w-3" />}
                      .com {nameData.available ? 'Available' : 'Taken'}
                    </span>

                    <div className="flex gap-2">
                      <Button
                        size="sm"
                        variant="outline"
                        onClick={() => sendToBrandKit(nameData.name)}
                        className="text-xs py-1 px-2 h-auto"
                        data-testid={`button-send-to-brand-kit-saved-${index}`}
                      >
                        <ArrowRight className="mr-1 h-3 w-3" />
                        Send to Brand Kit
                      </Button>
                      <Button
                        size="sm"
                        variant="ghost"
                        onClick={() => goToDomains(nameData.name)}
                        className="text-xs py-1 px-2 h-auto"
                      >
                        Check Domains
                      </Button>
                    </div>
                  </div>
                </div>
              ))}
            </div>
          )}
        </CardContent>
      </Card>
    </div>
  );
}

What changed (quick)

Added Tabs for Name Style / Randomness / Brand Info & Domains.

Subtitle line under “Generate Business Names.”

New filters: vibe chips, length slider, starts with, must include/exclude, TLDs, require available.

Payload passes these fields (safe even if backend ignores extras).

Results support optional extra TLD badges if your backend starts returning them later.

Kept your Saved Names system intact.