Awesome — here’s a clean drop-in patch that gives you the LOOKA-style “Pick some styles you like” grid, using inline color blocks (so they never render blank), nice glyphs, and an obvious selected state. I’ve also added the tiny state you need and wired it into your existing PDF/ZIP flow (via selectedStyles).

1) Add state (top of BrandKitPage component)
// NEW: user style picks (keep it small: 2–3)
const [selectedStyles, setSelectedStyles] = useState<string[]>([]);

2) Add cards + glyph component (put these above the return)
// ---- Style cards ----
type StyleCard = {
  id: string;
  title: string;
  subtitle?: string;
  hex: string;      // swatch color
  glyph?: string;   // optional overlay icon
};

const STYLE_CARDS: StyleCard[] = [
  { id: "balanced",  title: "Balanced",  subtitle: "Geometric + Wordmark + Badge", hex: "#111827", glyph: "square" },
  { id: "minimal",   title: "Minimal",   subtitle: "Clean lines, lots of space",   hex: "#1f2937", glyph: "pipe" },
  { id: "bold",      title: "Bold",      subtitle: "Heavy weight, strong shapes",  hex: "#3f38c9", glyph: "square-filled" },
  { id: "monogram",  title: "Monogram",  subtitle: "Letter-focused marks",         hex: "#085f4e", glyph: "A" },
  { id: "badge",     title: "Badge",     subtitle: "Emblem styles",                hex: "#075985", glyph: "circle" },
  { id: "playful",   title: "Playful",   subtitle: "Rounded, friendly",            hex: "#be185d", glyph: "dots" },
  { id: "elegant",   title: "Elegant",   subtitle: "Serif, luxury vibes",          hex: "#2b241f", glyph: "italic-E" },
  { id: "techy",     title: "Techy",     subtitle: "Futuristic, angular",          hex: "#0e5161", glyph: "diamond" },
  { id: "organic",   title: "Organic",   subtitle: "Nature, hand-drawn",           hex: "#0f5f2b", glyph: "oval" },
];

function TileGlyph({ type }: { type?: string }) {
  return (
    <svg
      aria-hidden
      className="h-8 w-8 opacity-60"
      viewBox="0 0 24 24"
      fill="none"
      stroke="currentColor"
    >
      {type === "square" && <rect x="6" y="6" width="12" height="12" rx="2" strokeWidth="1.5" />}
      {type === "square-filled" && <rect x="7" y="7" width="10" height="10" rx="2" strokeWidth="0" fill="currentColor" />}
      {type === "pipe" && (
        <>
          <line x1="12" y1="6" x2="12" y2="14" strokeWidth="1.5" />
          <line x1="7" y1="17" x2="17" y2="17" strokeWidth="1.5" />
        </>
      )}
      {type === "circle" && <circle cx="12" cy="12" r="3.5" strokeWidth="1.5" />}
      {type === "dots" && (
        <>
          <circle cx="9" cy="12" r="1.2" />
          <circle cx="12" cy="12" r="1.2" />
          <circle cx="15" cy="12" r="1.2" />
        </>
      )}
      {type === "A" && (
        <text x="12" y="14" textAnchor="middle" fontSize="10" fontWeight="700" fill="currentColor">A</text>
      )}
      {type === "italic-E" && (
        <text x="12" y="14" textAnchor="middle" fontSize="10" fontStyle="italic" fill="currentColor">E</text>
      )}
      {type === "diamond" && <polygon points="12,8 16,12 12,16 8,12" strokeWidth="1.5" />}
      {type === "oval" && <ellipse cx="12" cy="12" rx="3.5" ry="5.5" strokeWidth="1.5" />}
    </svg>
  );
}

const StyleTile: React.FC<{
  card: StyleCard;
  active: boolean;
  onToggle: () => void;
}> = ({ card, active, onToggle }) => (
  <button
    onClick={onToggle}
    aria-pressed={active}
    className={`relative w-full text-left rounded-2xl border transition p-5
      ${active ? "border-indigo-500 shadow-[0_0_0_3px_rgba(99,102,241,0.25)]"
               : "border-neutral-200 hover:border-neutral-300"}`}
  >
    <div
      className="relative h-28 rounded-xl mb-4 flex items-center justify-center text-white/80"
      style={{ backgroundColor: card.hex }}
    >
      <TileGlyph type={card.glyph} />
    </div>
    <div className="font-medium">{card.title}</div>
    {card.subtitle && <div className="text-xs text-neutral-500">{card.subtitle}</div>}
    {active && (
      <div className="absolute top-3 right-3 rounded-full bg-white border border-indigo-500 p-1">
        <svg width="16" height="16" viewBox="0 0 24 24" fill="none">
          <path d="M20 6L9 17l-5-5" stroke="#4f46e5" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round" />
        </svg>
      </div>
    )}
  </button>
);

3) Render the grid in your Step 3 screen

Place this at the very top of the step === 3 section (before fonts), so users pick styles first:

{/* ---- STYLE PICKER ---- */}
<div className="space-y-2">
  <h2 className="text-xl font-semibold">Pick some styles you like</h2>
  <p className="text-sm text-neutral-500">Choose 2–3 cards as inspiration. This guides the AI.</p>
  <div className="grid sm:grid-cols-2 md:grid-cols-3 gap-4">
    {STYLE_CARDS.map((card) => {
      const active = selectedStyles.includes(card.id);
      return (
        <StyleTile
          key={card.id}
          card={card}
          active={active}
          onToggle={() => {
            setSelectedStyles((prev) => {
              if (active) return prev.filter((id) => id !== card.id);
              // cap at 3 selections
              if (prev.length >= 3) return prev;
              return [...prev, card.id];
            });
          }}
        />
      );
    })}
  </div>
  <div className="text-xs text-neutral-500">
    Selected: {selectedStyles.length} / 3
  </div>
</div>


Nothing else in your UI breaks if a user skips this; it’s optional but saved if chosen.

4) Make sure exports include the picks (already supported)

You’re already using selectedStyles in the PDF/ZIP we wired earlier. If it’s not in your brandInfo payload, ensure it’s included (inside downloadBrandKit):

const brandInfo = {
  // ...
  styles: selectedStyles,  // ← include picks
  // ...
};


And in the PDF header page where we show “Style DNA”, keep:

if (selectedStyles.length) {
  pdfDoc.text(`Style DNA: ${selectedStyles.join(", ")}`, 40, 170, { maxWidth: 515 });
}
