diff --git a/components/ImprovedCategoryFilter.jsx b/components/ImprovedCategoryFilter.jsx index 872b40a..c09054b 100644 --- a/components/ImprovedCategoryFilter.jsx +++ b/components/ImprovedCategoryFilter.jsx @@ -1,3 +1,4 @@ +// components/ImprovedCategoryFilter.jsx import React from "react"; import { motion } from "framer-motion"; import { Button } from "@/components/ui/button"; @@ -13,31 +14,31 @@ export default function ImprovedCategoryFilter({ { id: 'all', name: '🔥 All Fonts', - description: 'Complete collection', + description: 'Complete collection of 60 styles', gradient: 'from-pink-500 to-purple-600' }, { id: 'modern', name: '🔤 Modern', - description: 'Clean & professional', + description: 'Clean & professional fonts', gradient: 'from-blue-500 to-indigo-600' }, { id: 'handwriting', name: '✍️ Handwriting', - description: 'Personal & casual', + description: 'Personal, casual and handwritten', gradient: 'from-green-500 to-emerald-600' }, { id: 'statement', name: '🧑‍🎤 Statement', - description: 'Bold & eye-catching', + description: 'Bold & attention-grabbing', gradient: 'from-red-500 to-pink-600' }, { id: 'futuristic', name: '🚀 Futuristic', - description: 'Tech & gaming', + description: 'Tech & gaming inspired', gradient: 'from-purple-500 to-violet-600' }, { @@ -59,7 +60,7 @@ export default function ImprovedCategoryFilter({

Choose Your Style

- Browse fonts by category or view all {fontCounts.all} unique styles + Browse fonts by category or view all {fontCounts?.all ?? 60} unique styles

@@ -97,7 +98,7 @@ export default function ImprovedCategoryFilter({ : 'bg-white/10 text-white/80 border-white/20' }`} > - {fontCounts[category.id] || 0} fonts + {fontCounts?.[category.id] ?? 0} fonts @@ -114,7 +115,7 @@ export default function ImprovedCategoryFilter({ >

- Showing {fontCounts[selectedCategory]} fonts + Showing {fontCounts?.[selectedCategory] ?? 0} fonts in {categories.find(c => c.id === selectedCategory)?.name} category

@@ -122,4 +123,4 @@ export default function ImprovedCategoryFilter({ )} ); -} \ No newline at end of file +} diff --git a/components/PerformanceOptimizedFontCard.jsx b/components/PerformanceOptimizedFontCard.jsx index 24cba0a..5f28061 100644 --- a/components/PerformanceOptimizedFontCard.jsx +++ b/components/PerformanceOptimizedFontCard.jsx @@ -95,26 +95,16 @@ const PerformanceOptimizedFontCard = forwardRef(({ const getFontStyle = useCallback((name) => { const baseStyle = { wordBreak: "break-word", lineHeight: "1.3", willChange: "auto" }; - const fontMap = { - Montserrat: { fontFamily: "Montserrat, sans-serif", fontWeight: "500" }, - 'Bebas Neue': { fontFamily: '"Bebas Neue", cursive', fontWeight: "400", textTransform: "uppercase", letterSpacing: "0.05em" }, - Oswald: { fontFamily: "Oswald, sans-serif", fontWeight: "500", textTransform: "uppercase" }, - Raleway: { fontFamily: "Raleway, sans-serif", fontWeight: "400" }, - Poppins: { fontFamily: "Poppins, sans-serif", fontWeight: "500" }, - Inter: { fontFamily: "Inter, sans-serif", fontWeight: "400" }, - Caveat: { fontFamily: "Caveat, cursive", fontWeight: "400" }, - Pacifico: { fontFamily: "Pacifico, cursive", fontWeight: "400" }, - 'Dancing Script': { fontFamily: '"Dancing Script", cursive', fontWeight: "400" }, - 'Amatic SC': { fontFamily: '"Amatic SC", cursive', fontWeight: "400" }, - Anton: { fontFamily: "Anton, sans-serif", fontWeight: "400", textTransform: "uppercase" }, - 'Luckiest Guy': { fontFamily: '"Luckiest Guy", cursive', fontWeight: "400", textTransform: "uppercase" }, - 'Fredoka One': { fontFamily: '"Fredoka One", cursive', fontWeight: "400" }, - Bangers: { fontFamily: "Bangers, cursive", fontWeight: "400", textTransform: "uppercase" }, - Orbitron: { fontFamily: "Orbitron, sans-serif", fontWeight: "400" }, - 'Press Start 2P': { fontFamily: '"Press Start 2P", cursive', fontWeight: "400", fontSize: "0.85em" }, - 'Playfair Display': { fontFamily: '"Playfair Display", serif', fontWeight: "400" } - }; - return { ...baseStyle, ...(fontMap[name] || {}) }; + const fontEntry = fontTransforms[name]; + if (!fontEntry) return baseStyle; + + const style = { ...baseStyle }; + if (fontEntry.fontFamily) style.fontFamily = fontEntry.fontFamily; + if (fontEntry.fontWeight) style.fontWeight = fontEntry.fontWeight; + if (fontEntry.textTransform) style.textTransform = fontEntry.textTransform; + if (fontEntry.letterSpacing) style.letterSpacing = fontEntry.letterSpacing; + if (fontEntry.fontSize) style.fontSize = fontEntry.fontSize; + return style; }, []); const previewText = sStr(transformedText) || "Hallo Instagram!"; @@ -185,7 +175,7 @@ const PerformanceOptimizedFontCard = forwardRef(({ {copied ? ( <> Copy! ✨ ) : ( - <> Copy! ✨ + <> Start Typing ✨ )} diff --git a/components/fontTransforms.jsx b/components/fontTransforms.jsx index 7689e7e..47f4625 100644 --- a/components/fontTransforms.jsx +++ b/components/fontTransforms.jsx @@ -1,20 +1,18 @@ // components/fontTransforms.jsx -// Unicode-basiertes Font-Transformationsmapping für deine aktuelle Font-Liste -// Nutzt verschiedene Unicode-Blöcke, damit beim Kopieren der "fancy" Stil erhalten bleibt. -// 1) Definition der Unicode-Blöcke (Startpunkte) +// 1) Unicode-Blöcke (Startpunkte) const unicodeBlocks = { - sansSerif: { upperStart: 0x1D5A0, lowerStart: 0x1D5BA }, // Mathematical Sans-Serif - sansSerifBold: { upperStart: 0x1D5D4, lowerStart: 0x1D5EE }, // Bold Sans-Serif - script: { upperStart: 0x1D49C, lowerStart: 0x1D4B6 }, // Mathematical Script - scriptBold: { upperStart: 0x1D4D0, lowerStart: 0x1D4EA }, // Bold Script - fraktur: { upperStart: 0x1D504, lowerStart: 0x1D51E }, // Mathematical Fraktur - frakturBold: { upperStart: 0x1D56C, lowerStart: 0x1D586 }, // Bold Fraktur - monospace: { upperStart: 0x1D670, lowerStart: 0x1D68A }, // Mathematical Monospace - fullwidth: { upperStart: 0xFF21, lowerStart: 0xFF41 } // Fullwidth Latin + sansSerif: { upperStart: 0x1D5A0, lowerStart: 0x1D5BA }, + sansSerifBold: { upperStart: 0x1D5D4, lowerStart: 0x1D5EE }, + script: { upperStart: 0x1D49C, lowerStart: 0x1D4B6 }, + scriptBold: { upperStart: 0x1D4D0, lowerStart: 0x1D4EA }, + fraktur: { upperStart: 0x1D504, lowerStart: 0x1D51E }, + frakturBold: { upperStart: 0x1D56C, lowerStart: 0x1D586 }, + monospace: { upperStart: 0x1D670, lowerStart: 0x1D68A }, + fullwidth: { upperStart: 0xFF21, lowerStart: 0xFF41 } }; -// 2) Helfer zum Mappen von A-Z und a-z in den jeweiligen Unicode-Block +// 2) Unicode-Mapping-Helfer const mapUnicode = (char, block) => { const code = char.charCodeAt(0); if (code >= 65 && code <= 90) return String.fromCodePoint(block.upperStart + (code - 65)); @@ -23,64 +21,105 @@ const mapUnicode = (char, block) => { }; const createTransform = (blockKey) => (text) => - text - .split('') - .map((c) => mapUnicode(c, unicodeBlocks[blockKey])) - .join(''); + text.split('').map((c) => mapUnicode(c, unicodeBlocks[blockKey])).join(''); -// 3) Font-Transformations für deine Liste -export const fontTransforms = { - // 🔤 Modern – Clean & professional - Montserrat: { transform: createTransform('sansSerifBold'), category: 'modern', description: 'Montserrat – Sans-Serif Bold Unicode' }, - Lato: { transform: createTransform('sansSerif'), category: 'modern', description: 'Lato – Humanistischer Sans-Serif Unicode' }, - Raleway: { transform: createTransform('sansSerif'), category: 'modern', description: 'Raleway – Elegant Display Unicode' }, - Poppins: { transform: createTransform('sansSerif'), category: 'modern', description: 'Poppins – Rund & freundlich Unicode' }, - 'Open Sans': { transform: createTransform('sansSerif'), category: 'modern', description: 'Open Sans – Vielseitig Unicode' }, - Roboto: { transform: createTransform('sansSerif'), category: 'modern', description: 'Roboto – Modernes Grotesk Unicode' }, - 'Work Sans': { transform: createTransform('sansSerif'), category: 'modern', description: 'Work Sans – Tech & Clean Unicode' }, +// 3) Font-Transformationen +export const fontTransforms = Object.fromEntries( + Object.entries({ + // 🔤 Modern + Montserrat: ['sansSerifBold', 'modern', 'Montserrat – Sans-Serif Bold Unicode'], + Lato: ['sansSerif', 'modern', 'Lato – Humanistischer Sans-Serif Unicode'], + Raleway: ['sansSerif', 'modern', 'Raleway – Elegant Display Unicode'], + Poppins: ['sansSerif', 'modern', 'Poppins – Rund & freundlich Unicode'], + 'Open Sans': ['sansSerif', 'modern', 'Open Sans – Vielseitig Unicode'], + Roboto: ['sansSerif', 'modern', 'Roboto – Modernes Grotesk Unicode'], + 'Work Sans': ['sansSerif', 'modern', 'Work Sans – Tech & Clean Unicode'], + 'Noto Sans': ['sansSerif', 'modern', 'Noto Sans – International Unicode'], + Jost: ['sansSerif', 'modern', 'Jost – Geometrisch modern Unicode'], + Quicksand: ['sansSerif', 'modern', 'Quicksand – Soft Rounded Unicode'], + 'Averia Libre': ['sansSerif', 'modern', 'Averia Libre – Experimentell Unicode'], + 'Philosopher': ['sansSerif', 'modern', 'Philosopher – Elegant Unicode'], - // ✍️ Handwriting – Personal & casual - Pacifico: { transform: createTransform('scriptBold'), category: 'handwriting', description: 'Pacifico – Lockerer Pinsel Bold Script Unicode' }, - Sacramento: { transform: createTransform('scriptBold'), category: 'handwriting', description: 'Sacramento – Retro-Handlettering Bold Script Unicode' }, - Caveat: { transform: createTransform('scriptBold'), category: 'handwriting', description: 'Caveat – Natural Handwriting Bold Script Unicode' }, - 'Dancing Script': { transform: createTransform('scriptBold'), category: 'handwriting', description: 'Dancing Script – Lebhafte Kursive Bold Script Unicode' }, - 'Indie Flower': { transform: createTransform('scriptBold'), category: 'handwriting', description: 'Indie Flower – Verspieltes Bold Script Unicode' }, - 'Amatic SC': { transform: createTransform('scriptBold'), category: 'handwriting', description: 'Amatic SC – Skizzenartiges Bold Script Unicode' }, - 'Kaushan Script': { transform: createTransform('scriptBold'), category: 'handwriting', description: 'Kaushan Script – Fettere Kursive Bold Script Unicode' }, + // ✍️ Handwriting + Pacifico: ['scriptBold', 'handwriting', 'Pacifico – Lockerer Pinsel Bold Script Unicode'], + Sacramento: ['scriptBold', 'handwriting', 'Sacramento – Retro-Handlettering Bold Script Unicode'], + Caveat: ['scriptBold', 'handwriting', 'Caveat – Natural Handwriting Bold Script Unicode'], + 'Dancing Script': ['scriptBold', 'handwriting', 'Dancing Script – Lebhafte Kursive Bold Script Unicode'], + 'Indie Flower': ['scriptBold', 'handwriting', 'Indie Flower – Verspieltes Bold Script Unicode'], + 'Amatic SC': ['scriptBold', 'handwriting', 'Amatic SC – Skizzenartiges Bold Script Unicode'], + 'Kaushan Script': ['scriptBold', 'handwriting', 'Kaushan Script – Fettere Kursive Bold Script Unicode'], + 'Architects Daughter': ['scriptBold','handwriting', 'Architects Daughter – Skizzenhafte Handschrift Unicode'], + Neucha: ['scriptBold', 'handwriting', 'Neucha – Persönlich und kantig Unicode'], + 'Great Vibes': ['scriptBold', 'handwriting', 'Great Vibes – Elegante Kalligraphie Unicode'], + Satisfy: ['scriptBold', 'handwriting', 'Satisfy – Weiche Script Unicode'], + Yellowtail: ['scriptBold', 'handwriting', 'Yellowtail – Vintage Script Unicode'], + 'Gloria Hallelujah': ['scriptBold', 'handwriting', 'Gloria Hallelujah – Lebendige Handschrift Unicode'], - // 🧑‍🎤 Statement – Bold & eye-catching - Oswald: { transform: createTransform('sansSerifBold'), category: 'statement', description: 'Oswald – Bold Grotesk Unicode' }, - 'Bebas Neue': { transform: createTransform('fullwidth'), category: 'statement', description: 'Bebas Neue – Fullwidth Caps Unicode' }, - Anton: { transform: createTransform('fullwidth'), category: 'statement', description: 'Anton – Plakative Fullwidth Unicode' }, - Ultra: { transform: createTransform('sansSerifBold'), category: 'statement', description: 'Ultra – Kompakte Bold Unicode' }, - 'Stint Ultra Condensed': { transform: createTransform('sansSerifBold'), category: 'statement', description: 'Stint Ultra Condensed – Kompakte Bold Unicode' }, - 'Playfair Display': { transform: createTransform('scriptBold'), category: 'statement', description: 'Playfair Display – Elegante Bold Script Unicode' }, - 'Abril Fatface': { transform: createTransform('scriptBold'), category: 'statement', description: 'Abril Fatface – Fettere Bold Script Unicode' }, + // 🧑‍🎤 Statement + Oswald: ['sansSerifBold', 'statement', 'Oswald – Bold Grotesk Unicode'], + 'Bebas Neue': ['fullwidth', 'statement', 'Bebas Neue – Fullwidth Caps Unicode'], + Anton: ['fullwidth', 'statement', 'Anton – Plakative Fullwidth Unicode'], + Ultra: ['sansSerifBold', 'statement', 'Ultra – Kompakte Bold Unicode'], + 'Stint Ultra Condensed': ['sansSerifBold', 'statement', 'Stint Ultra Condensed – Kompakte Bold Unicode'], + 'Playfair Display': ['scriptBold', 'statement', 'Playfair Display – Elegante Bold Script Unicode'], + 'Abril Fatface': ['scriptBold', 'statement', 'Abril Fatface – Fettere Bold Script Unicode'], + 'Permanent Marker': ['scriptBold', 'statement', 'Permanent Marker – Marker-Style Unicode'], + 'Alfa Slab One': ['fullwidth', 'statement', 'Alfa Slab One – Slab Serif Heavy Unicode'], + 'Black Ops One': ['fullwidth', 'statement', 'Black Ops One – Military Display Unicode'], + 'Germania One': ['frakturBold', 'statement', 'Germania One – Oldstyle Fraktur Unicode'], + 'Holtwood One SC': ['fullwidth', 'statement', 'Holtwood One SC – Klassisch Bold Small Caps Unicode'], + Courgette: ['scriptBold', 'statement', 'Courgette – Verspieltes Script Unicode'], - // 🚀 Futuristic – Tech & gaming - Exo: { transform: createTransform('sansSerif'), category: 'futuristic', description: 'Exo – Tech Grotesk Unicode' }, - Orbitron: { transform: createTransform('monospace'), category: 'futuristic', description: 'Orbitron – Sci-Fi Monospace Unicode' }, - Audiowide: { transform: createTransform('monospace'), category: 'futuristic', description: 'Audiowide – Rundes Monospace Unicode' }, - Rajdhani: { transform: createTransform('monospace'), category: 'futuristic', description: 'Rajdhani – Digital Monospace Unicode' }, - 'Space Mono': { transform: createTransform('monospace'), category: 'futuristic', description: 'Space Mono – Tech Monospace Unicode' }, - Questrial: { transform: createTransform('sansSerif'), category: 'futuristic', description: 'Questrial – Clean Sans-Serif Unicode' }, + // 🚀 Futuristic + Exo: ['sansSerif', 'futuristic', 'Exo – Tech Grotesk Unicode'], + Orbitron: ['monospace', 'futuristic', 'Orbitron – Sci-Fi Monospace Unicode'], + Audiowide: ['monospace', 'futuristic', 'Audiowide – Rundes Monospace Unicode'], + Rajdhani: ['monospace', 'futuristic', 'Rajdhani – Digital Monospace Unicode'], + 'Space Mono': ['monospace', 'futuristic', 'Space Mono – Tech Monospace Unicode'], + Questrial: ['sansSerif', 'futuristic', 'Questrial – Clean Sans-Serif Unicode'], + 'Syncopate': ['monospace', 'futuristic', 'Syncopate – Techno Unicode'], + 'Unica One': ['monospace', 'futuristic', 'Unica One – Monospace Mix Unicode'], + 'Italiana': ['sansSerif', 'futuristic', 'Italiana – Futuristisch Serif Unicode'], + 'Staatliches': ['monospace', 'futuristic', 'Staatliches – Moderne Grotesk Unicode'], - // 🧢 Aesthetic – Retro & Instagram vibes - 'Press Start 2P': { transform: createTransform('monospace'), category: 'aesthetic', description: 'Press Start 2P – Pixel Monospace Unicode' }, - Righteous: { transform: createTransform('frakturBold'), category: 'aesthetic', description: 'Righteous – Stylische Bold Fraktur Unicode' }, - 'Metal Mania': { transform: createTransform('scriptBold'), category: 'aesthetic', description: 'Metal Mania – Fettere Script Unicode' } -}; - -// Hilfsfunktionen -export const getPopularFonts = () => Object.keys(fontTransforms).slice(0, 10); -export const getFontsByCategory = (category) => ( - category === 'all' - ? Object.keys(fontTransforms) - : Object.keys(fontTransforms).filter(f => fontTransforms[f].category === category) + // 🧢 Aesthetic + 'Press Start 2P': ['monospace', 'aesthetic', 'Press Start 2P – Pixel Monospace Unicode'], + Righteous: ['frakturBold', 'aesthetic', 'Righteous – Stylische Bold Fraktur Unicode'], + 'Metal Mania': ['scriptBold', 'aesthetic', 'Metal Mania – Fettere Script Unicode'], + 'Alegreya': ['frakturBold', 'aesthetic', 'Alegreya – Literatur Serif Unicode'], + 'Spectral': ['frakturBold', 'aesthetic', 'Spectral – Editorial Serif Unicode'], + 'Fjalla One': ['sansSerifBold', 'aesthetic', 'Fjalla One – Headline Sans Unicode'], + 'Glass Antiqua': ['scriptBold', 'aesthetic', 'Glass Antiqua – Zarte Antiqua Script Unicode'], + 'Cinzel Decorative': ['scriptBold', 'aesthetic', 'Cinzel Decorative – Klassische Zier-Serif Unicode'], + 'Andika': ['sansSerif', 'aesthetic', 'Andika – Leserlich Unicode'], + 'Almendra': ['scriptBold', 'aesthetic', 'Almendra – Historische Handschrift Unicode'], + }).map(([name, [block, category, description]]) => [ + name, + { + transform: createTransform(block), + category, + description, + className: `font-${name.toLowerCase().replace(/\s+/g, '')}`, + }, + ]) ); +// 🔝 Neue transformText-Funktion – gibt transformierten Text **und** Tailwind-Klasse zurück export const transformText = (text, fontName) => { const font = fontTransforms[fontName]; - if (!font || !text) return text; - return font.transform(text); + if (!font || !text) return { transformed: text, fontClassName: '' }; + return { + transformed: font.transform(text), + fontClassName: font.className, + }; }; + +// Weitere Helfer +export const getPopularFonts = () => Object.keys(fontTransforms).slice(0, 10); + +export const getFontsByCategory = (category) => + category === 'all' + ? Object.keys(fontTransforms) + : Object.keys(fontTransforms).filter( + (f) => fontTransforms[f].category === category + ); diff --git a/components/ui/FontCard.jsx b/components/ui/FontCard.jsx index 2bb4c32..21cf50d 100644 --- a/components/ui/FontCard.jsx +++ b/components/ui/FontCard.jsx @@ -4,8 +4,9 @@ import { Card } from "@/components/ui/card"; import { Button } from "@/components/ui/button"; import { Badge } from "@/components/ui/badge"; import { Copy, Check, Heart, Share2, Info } from "lucide-react"; -import { fontTransforms } from "../fontTransforms"; +import { transformText, fontTransforms } from "../fontTransforms"; import { getFontData } from "@/lib/fonts"; +import fontMap from "@/lib/tailwind-font-map"; export default function FontCard({ fontName, @@ -19,12 +20,20 @@ export default function FontCard({ const fontInfo = fontTransforms[fontName]; const fontData = getFontData(fontName); - const displayText = transformedText || "Hallo Instagram!"; + const fontKey = fontName.toLowerCase().replace(/\s+/g, ""); + const fontVarName = fontMap[fontKey]; + const fontVar = fontVarName ? { fontFamily: `var(${fontVarName})` } : {}; + const fontClass = fontData?.className || ""; + + const rawText = "Hallo Instagram!"; + const transformed = transformText(rawText, fontName); + const finalText = transformed?.transformed || rawText; + const copyText = transformed?.transformed || rawText; const handleCopy = () => { if (navigator.clipboard && window.isSecureContext) { navigator.clipboard - .writeText(displayText) + .writeText(copyText) .then(() => flashCopied()) .catch(() => fallbackCopy()); } else { @@ -39,7 +48,7 @@ export default function FontCard({ const fallbackCopy = () => { const textarea = document.createElement("textarea"); - textarea.value = displayText; + textarea.value = copyText; textarea.setAttribute("readonly", ""); textarea.style.position = "fixed"; textarea.style.top = "0"; @@ -69,7 +78,7 @@ export default function FontCard({ try { await navigator.share({ title: `FancyText – ${fontName}`, - text: displayText, + text: copyText, url: window.location.href, }); } catch (err) { @@ -124,10 +133,10 @@ export default function FontCard({