Compare commits

..

7 Commits

Author SHA1 Message Date
87cd5beaac 'anton':
'bebas-neue':
'dancing-script':
'montserrat':
'orbitron':
'pacifico':
'playfair-display
'poppins': [
2025-08-04 23:01:46 -05:00
2587880a1f Anpassungen 2025-08-04 22:53:25 -05:00
7f63454701 removed .next folder 2025-08-04 18:35:39 -05:00
2d2c2db261 Fonts werden teilweise geladen 2025-08-04 22:17:34 +02:00
d9508cc196 Fonts werden teilweise geladen 2025-08-04 20:04:08 +02:00
b701dbe30d Gute version, fonts laden nicht 2025-08-04 16:33:05 +02:00
62ebe48adb Initial commit 2025-08-03 18:48:24 +02:00
77 changed files with 4583 additions and 1614 deletions

View File

@@ -0,0 +1,64 @@
import { useState } from "react";
import { fontTransforms, transformText } from "@/components/fontTransforms";
export default function FancyTextPreview() {
const [inputText, setInputText] = useState("Hello Instagram");
const [copiedIndex, setCopiedIndex] = useState(null);
const allFonts = Object.keys(fontTransforms);
const handleCopy = async (text, index) => {
try {
await navigator.clipboard.writeText(text);
setCopiedIndex(index);
setTimeout(() => setCopiedIndex(null), 1500);
} catch (err) {
console.error("Copy failed:", err);
}
};
return (
<div className="max-w-3xl mx-auto p-4">
<input
type="text"
className="w-full border rounded px-4 py-2 mb-6 text-lg"
value={inputText}
onChange={(e) => setInputText(e.target.value)}
placeholder="Type something..."
/>
<div className="space-y-6">
{allFonts.map((fontName, index) => {
const { transformed, fontClassName } = transformText(inputText, fontName);
return (
<div
key={fontName}
className="border-b pb-4 flex flex-col gap-2"
>
<p className="text-sm font-semibold text-gray-700">{fontName}</p>
<div className="flex flex-col gap-1">
{/* ⬇️ Normale Textvorschau mit Webfont */}
<p className={`text-xl ${fontClassName}`}>
{inputText || "Hello Instagram"}
</p>
{/* ⬇️ Fancy Unicode-Text */}
<p className="text-xl text-gray-600">
{transformed}
</p>
</div>
<button
className="self-start mt-1 text-sm bg-gray-200 hover:bg-gray-300 rounded px-3 py-1"
onClick={() => handleCopy(transformed, index)}
>
{copiedIndex === index ? "Copied!" : "Copy"}
</button>
</div>
);
})}
</div>
</div>
);
}

View File

@@ -1,3 +1,4 @@
// components/ImprovedCategoryFilter.jsx
import React from "react"; import React from "react";
import { motion } from "framer-motion"; import { motion } from "framer-motion";
import { Button } from "@/components/ui/button"; import { Button } from "@/components/ui/button";
@@ -13,31 +14,31 @@ export default function ImprovedCategoryFilter({
{ {
id: 'all', id: 'all',
name: '🔥 All Fonts', name: '🔥 All Fonts',
description: 'Complete collection', description: 'Complete collection of 60 styles',
gradient: 'from-pink-500 to-purple-600' gradient: 'from-pink-500 to-purple-600'
}, },
{ {
id: 'modern', id: 'modern',
name: '🔤 Modern', name: '🔤 Modern',
description: 'Clean & professional', description: 'Clean & professional fonts',
gradient: 'from-blue-500 to-indigo-600' gradient: 'from-blue-500 to-indigo-600'
}, },
{ {
id: 'handwriting', id: 'handwriting',
name: '✍️ Handwriting', name: '✍️ Handwriting',
description: 'Personal & casual', description: 'Personal, casual and handwritten',
gradient: 'from-green-500 to-emerald-600' gradient: 'from-green-500 to-emerald-600'
}, },
{ {
id: 'statement', id: 'statement',
name: '🧑‍🎤 Statement', name: '🧑‍🎤 Statement',
description: 'Bold & eye-catching', description: 'Bold & attention-grabbing',
gradient: 'from-red-500 to-pink-600' gradient: 'from-red-500 to-pink-600'
}, },
{ {
id: 'futuristic', id: 'futuristic',
name: '🚀 Futuristic', name: '🚀 Futuristic',
description: 'Tech & gaming', description: 'Tech & gaming inspired',
gradient: 'from-purple-500 to-violet-600' gradient: 'from-purple-500 to-violet-600'
}, },
{ {
@@ -59,7 +60,7 @@ export default function ImprovedCategoryFilter({
<div className="text-center mb-6"> <div className="text-center mb-6">
<h2 className="text-2xl font-bold text-white mb-2">Choose Your Style</h2> <h2 className="text-2xl font-bold text-white mb-2">Choose Your Style</h2>
<p className="text-white/70 text-sm"> <p className="text-white/70 text-sm">
Browse fonts by category or view all {fontCounts.all} unique styles Browse fonts by category or view all {fontCounts?.all ?? 60} unique styles
</p> </p>
</div> </div>
@@ -97,7 +98,7 @@ export default function ImprovedCategoryFilter({
: 'bg-white/10 text-white/80 border-white/20' : 'bg-white/10 text-white/80 border-white/20'
}`} }`}
> >
{fontCounts[category.id] || 0} fonts {fontCounts?.[category.id] ?? 0} fonts
</Badge> </Badge>
</div> </div>
</Button> </Button>
@@ -114,7 +115,7 @@ export default function ImprovedCategoryFilter({
> >
<div className="bg-white/10 backdrop-blur-sm rounded-lg p-3 inline-block"> <div className="bg-white/10 backdrop-blur-sm rounded-lg p-3 inline-block">
<p className="text-white/80 text-sm"> <p className="text-white/80 text-sm">
Showing <span className="font-semibold text-white">{fontCounts[selectedCategory]}</span> fonts Showing <span className="font-semibold text-white">{fontCounts?.[selectedCategory] ?? 0}</span> fonts
in <span className="font-semibold text-white">{categories.find(c => c.id === selectedCategory)?.name}</span> category in <span className="font-semibold text-white">{categories.find(c => c.id === selectedCategory)?.name}</span> category
</p> </p>
</div> </div>

View File

@@ -39,7 +39,7 @@ const PerformanceOptimizedFontCard = forwardRef(({
}); });
const handleCopy = useCallback(async () => { const handleCopy = useCallback(async () => {
const textToCopy = sStr(transformedText); const textToCopy = sStr(transformedText?.transformed ?? transformedText);
try { try {
await navigator.clipboard.writeText(textToCopy); await navigator.clipboard.writeText(textToCopy);
setCopied(true); setCopied(true);
@@ -76,7 +76,7 @@ const PerformanceOptimizedFontCard = forwardRef(({
}, [liked, fontName, onLike]); }, [liked, fontName, onLike]);
const handleShare = useCallback(async () => { const handleShare = useCallback(async () => {
const shareText = `${sStr(transformedText)}\n\nErstellt mit FancyText: ${window.location.href}`; const shareText = `${sStr(transformedText?.transformed ?? transformedText)}\n\nErstellt mit FancyText: ${window.location.href}`;
if (navigator.share) { if (navigator.share) {
try { try {
await navigator.share({ title: "Schau dir diese coole Schriftart an! 🔥", text: shareText, url: window.location.href }); await navigator.share({ title: "Schau dir diese coole Schriftart an! 🔥", text: shareText, url: window.location.href });
@@ -95,29 +95,23 @@ const PerformanceOptimizedFontCard = forwardRef(({
const getFontStyle = useCallback((name) => { const getFontStyle = useCallback((name) => {
const baseStyle = { wordBreak: "break-word", lineHeight: "1.3", willChange: "auto" }; const baseStyle = { wordBreak: "break-word", lineHeight: "1.3", willChange: "auto" };
const fontMap = { const fontEntry = fontTransforms[name];
Montserrat: { fontFamily: "Montserrat, sans-serif", fontWeight: "500" }, if (!fontEntry) {
'Bebas Neue': { fontFamily: '"Bebas Neue", cursive', fontWeight: "400", textTransform: "uppercase", letterSpacing: "0.05em" }, console.warn(`Font definition missing for ${name}`);
Oswald: { fontFamily: "Oswald, sans-serif", fontWeight: "500", textTransform: "uppercase" }, }
Raleway: { fontFamily: "Raleway, sans-serif", fontWeight: "400" }, if (!fontEntry) return baseStyle;
Poppins: { fontFamily: "Poppins, sans-serif", fontWeight: "500" },
Inter: { fontFamily: "Inter, sans-serif", fontWeight: "400" }, const style = { ...baseStyle };
Caveat: { fontFamily: "Caveat, cursive", fontWeight: "400" }, if (fontEntry.fontFamily) style.fontFamily = fontEntry.fontFamily;
Pacifico: { fontFamily: "Pacifico, cursive", fontWeight: "400" }, if (fontEntry.fontWeight) style.fontWeight = fontEntry.fontWeight;
'Dancing Script': { fontFamily: '"Dancing Script", cursive', fontWeight: "400" }, if (fontEntry.textTransform) style.textTransform = fontEntry.textTransform;
'Amatic SC': { fontFamily: '"Amatic SC", cursive', fontWeight: "400" }, if (fontEntry.letterSpacing) style.letterSpacing = fontEntry.letterSpacing;
Anton: { fontFamily: "Anton, sans-serif", fontWeight: "400", textTransform: "uppercase" }, if (fontEntry.fontSize) style.fontSize = fontEntry.fontSize;
'Luckiest Guy': { fontFamily: '"Luckiest Guy", cursive', fontWeight: "400", textTransform: "uppercase" }, return style;
'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 previewText = sStr(transformedText) || "Hallo Instagram!"; const previewText = sStr(transformedText?.transformed ?? transformedText) || "Hallo Instagram!";
const fontClass = transformedText?.fontClassName ?? "";
return ( return (
<div ref={ref} className="will-change-transform mb-6"> <div ref={ref} className="will-change-transform mb-6">
@@ -168,7 +162,7 @@ const PerformanceOptimizedFontCard = forwardRef(({
onKeyDown={(e) => (e.key === "Enter" || e.key === " ") && handleCopy()} onKeyDown={(e) => (e.key === "Enter" || e.key === " ") && handleCopy()}
aria-label="Click to copy text" aria-label="Click to copy text"
style={{ ...getFontStyle(fontName), pointerEvents: "auto" }} style={{ ...getFontStyle(fontName), pointerEvents: "auto" }}
className="text-xl sm-text-2xl md-text-3xl mb-4 p-3 sm:p-4 bg-gray-50 rounded-xl text-center select-all text-gray-800 min-h-[70px] sm:min-h-[80px] flex items-center justify-center cursor-pointer hover:bg-gray-100 transition-colors" className={`text-xl sm-text-2xl md-text-3xl mb-4 p-3 sm:p-4 bg-gray-50 rounded-xl text-center select-all text-gray-800 min-h-[70px] sm:min-h-[80px] flex items-center justify-center cursor-pointer hover:bg-gray-100 transition-colors ${fontClass}`}
> >
{previewText} {previewText}
</div> </div>

View File

@@ -1,20 +1,16 @@
// components/fontTransforms.jsx // 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)
const unicodeBlocks = { const unicodeBlocks = {
sansSerif: { upperStart: 0x1D5A0, lowerStart: 0x1D5BA }, // Mathematical Sans-Serif sansSerif: { upperStart: 0x1D5A0, lowerStart: 0x1D5BA },
sansSerifBold: { upperStart: 0x1D5D4, lowerStart: 0x1D5EE }, // Bold Sans-Serif sansSerifBold: { upperStart: 0x1D5D4, lowerStart: 0x1D5EE },
script: { upperStart: 0x1D49C, lowerStart: 0x1D4B6 }, // Mathematical Script script: { upperStart: 0x1D49C, lowerStart: 0x1D4B6 },
scriptBold: { upperStart: 0x1D4D0, lowerStart: 0x1D4EA }, // Bold Script scriptBold: { upperStart: 0x1D4D0, lowerStart: 0x1D4EA },
fraktur: { upperStart: 0x1D504, lowerStart: 0x1D51E }, // Mathematical Fraktur fraktur: { upperStart: 0x1D504, lowerStart: 0x1D51E },
frakturBold: { upperStart: 0x1D56C, lowerStart: 0x1D586 }, // Bold Fraktur frakturBold: { upperStart: 0x1D56C, lowerStart: 0x1D586 },
monospace: { upperStart: 0x1D670, lowerStart: 0x1D68A }, // Mathematical Monospace monospace: { upperStart: 0x1D670, lowerStart: 0x1D68A },
fullwidth: { upperStart: 0xFF21, lowerStart: 0xFF41 } // Fullwidth Latin fullwidth: { upperStart: 0xFF21, lowerStart: 0xFF41 }
}; };
// 2) Helfer zum Mappen von A-Z und a-z in den jeweiligen Unicode-Block
const mapUnicode = (char, block) => { const mapUnicode = (char, block) => {
const code = char.charCodeAt(0); const code = char.charCodeAt(0);
if (code >= 65 && code <= 90) return String.fromCodePoint(block.upperStart + (code - 65)); if (code >= 65 && code <= 90) return String.fromCodePoint(block.upperStart + (code - 65));
@@ -23,64 +19,57 @@ const mapUnicode = (char, block) => {
}; };
const createTransform = (blockKey) => (text) => const createTransform = (blockKey) => (text) =>
text text.split('').map((c) => mapUnicode(c, unicodeBlocks[blockKey])).join('');
.split('')
.map((c) => mapUnicode(c, unicodeBlocks[blockKey]))
.join('');
// 3) Font-Transformations für deine Liste const fontList = [
export const fontTransforms = { "Anton", "Bebas Neue", "Dancing Script", "Montserrat", "Orbitron", "Pacifico",
// 🔤 Modern Clean & professional "Playfair Display", "Poppins"
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' },
// ✍️ Handwriting Personal & casual const getCategory = (name) => {
Pacifico: { transform: createTransform('scriptBold'), category: 'handwriting', description: 'Pacifico Lockerer Pinsel Bold Script Unicode' }, const normalizedName = name.toLowerCase().replace(/ /g, "-");
Sacramento: { transform: createTransform('scriptBold'), category: 'handwriting', description: 'Sacramento Retro-Handlettering Bold Script Unicode' }, if (["dancing-script", "pacifico"].includes(normalizedName)) return "handwriting";
Caveat: { transform: createTransform('scriptBold'), category: 'handwriting', description: 'Caveat Natural Handwriting Bold Script Unicode' }, if (["anton", "bebas-neue", "playfair-display"].includes(normalizedName)) return "statement";
'Dancing Script': { transform: createTransform('scriptBold'), category: 'handwriting', description: 'Dancing Script Lebhafte Kursive Bold Script Unicode' }, if (["orbitron"].includes(normalizedName)) return "futuristic";
'Indie Flower': { transform: createTransform('scriptBold'), category: 'handwriting', description: 'Indie Flower Verspieltes Bold Script Unicode' }, if (["montserrat", "poppins"].includes(normalizedName)) return "modern";
'Amatic SC': { transform: createTransform('scriptBold'), category: 'handwriting', description: 'Amatic SC Skizzenartiges Bold Script Unicode' }, return "aesthetic";
'Kaushan Script': { transform: createTransform('scriptBold'), category: 'handwriting', description: 'Kaushan Script Fettere Kursive Bold Script 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' },
// 🚀 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' },
// 🧢 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 const blockForCategory = {
export const getPopularFonts = () => Object.keys(fontTransforms).slice(0, 10); modern: "sansSerif",
export const getFontsByCategory = (category) => ( handwriting: "scriptBold",
category === 'all' statement: "fullwidth",
? Object.keys(fontTransforms) futuristic: "monospace",
: Object.keys(fontTransforms).filter(f => fontTransforms[f].category === category) aesthetic: "frakturBold"
};
export const fontTransforms = Object.fromEntries(
fontList.map((font) => {
const normalizedFont = font.toLowerCase().replace(/ /g, "-");
const category = getCategory(font);
return [font, {
transform: (text) => text, // Echte Fonts verwenden, keine Unicode-Transformation
category,
description: `${font} Echte Schriftart verwendet`,
className: `font-${normalizedFont}`
}];
})
); );
export const transformText = (text, fontName) => { export const transformText = (text, fontName) => {
const font = fontTransforms[fontName]; const font = fontTransforms[fontName];
if (!font || !text) return text; if (!font || !text) return { transformed: text, fontClassName: "" };
return font.transform(text); return {
transformed: font.transform(text),
fontClassName: font.className
}; };
};
export const getPopularFonts = () => Object.keys(fontTransforms).slice(0, 5);
export const getFontsByCategory = (category) =>
category === "all"
? Object.keys(fontTransforms)
: Object.keys(fontTransforms).filter(
(f) => fontTransforms[f].category === category
);

View File

@@ -4,8 +4,7 @@ import { Card } from "@/components/ui/card";
import { Button } from "@/components/ui/button"; import { Button } from "@/components/ui/button";
import { Badge } from "@/components/ui/badge"; import { Badge } from "@/components/ui/badge";
import { Copy, Check, Heart, Share2, Info } from "lucide-react"; import { Copy, Check, Heart, Share2, Info } from "lucide-react";
import { fontTransforms } from "../fontTransforms"; import { transformText, fontTransforms } from "../fontTransforms";
import { getFontData } from "@/lib/fonts";
export default function FontCard({ export default function FontCard({
fontName, fontName,
@@ -18,63 +17,24 @@ export default function FontCard({
const [liked, setLiked] = useState(false); const [liked, setLiked] = useState(false);
const fontInfo = fontTransforms[fontName]; const fontInfo = fontTransforms[fontName];
const fontData = getFontData(fontName);
const displayText = transformedText || "Hallo Instagram!"; // Dynamisch Font-Klasse aus Fontnamen generieren (z.B. "Open Sans" → "font-open-sans")
const fontClass = `font-${fontName.toLowerCase().replace(/\s+/g, "-")}`;
// Fancy-Transformation
const rawText = "Hallo Instagram!";
const { transformed } = transformText(rawText, fontName);
const finalText = transformed || rawText;
const handleCopy = () => { const handleCopy = () => {
if (navigator.clipboard && window.isSecureContext) { navigator.clipboard.writeText(finalText).then(() => {
navigator.clipboard
.writeText(displayText)
.then(() => flashCopied())
.catch(() => fallbackCopy());
} else {
fallbackCopy();
}
};
const flashCopied = () => {
setCopied(true); setCopied(true);
setTimeout(() => setCopied(false), 2000); setTimeout(() => setCopied(false), 1500);
};
const fallbackCopy = () => {
const textarea = document.createElement("textarea");
textarea.value = displayText;
textarea.setAttribute("readonly", "");
textarea.style.position = "fixed";
textarea.style.top = "0";
textarea.style.left = "0";
textarea.style.width = "1px";
textarea.style.height = "1px";
textarea.style.padding = "0";
textarea.style.border = "none";
textarea.style.outline = "none";
textarea.style.boxShadow = "none";
textarea.style.background = "transparent";
document.body.appendChild(textarea);
textarea.focus();
textarea.select();
try {
document.execCommand("copy");
flashCopied();
} catch (err) {
console.error("Fallback Copy fehlgeschlagen:", err);
}
document.body.removeChild(textarea);
};
const handleShare = async () => {
if (!navigator.share) return;
try {
await navigator.share({
title: `FancyText ${fontName}`,
text: displayText,
url: window.location.href,
}); });
} catch (err) { };
console.error("Share fehlgeschlagen:", err);
} const handleShare = () => {
alert(`Teilen von: ${fontName}`);
}; };
return ( return (
@@ -108,7 +68,7 @@ export default function FontCard({
variant="ghost" variant="ghost"
size="sm" size="sm"
onClick={handleShare} onClick={handleShare}
className="text-gray-400 hover:text-blue-500" className="text-gray-400 hover:text-blue-500 pointer-events-auto"
> >
<Share2 className="w-4 h-4" /> <Share2 className="w-4 h-4" />
</Button> </Button>
@@ -124,9 +84,9 @@ export default function FontCard({
<input <input
type="text" type="text"
value={displayText} value={finalText}
readOnly readOnly
className={`${fontData.className} text-2xl md:text-3xl mb-6 p-4 bg-gray-50 rounded-xl text-center text-gray-800 min-h-[80px] w-full select-all border-0 focus:ring-0`} className={`${fontClass} text-2xl md:text-3xl mb-6 p-4 bg-gray-50 rounded-xl text-center text-gray-800 min-h-[80px] w-full select-all border-0 focus:ring-0 pointer-events-auto`}
style={{ lineHeight: "1.2" }} style={{ lineHeight: "1.2" }}
/> />

View File

@@ -5,5 +5,7 @@
"@/*": ["./*"] "@/*": ["./*"]
}, },
"forceConsistentCasingInFileNames": true "forceConsistentCasingInFileNames": true
} },
"include": ["next-env.d.ts", "**/*.ts", "**/*.tsx", "**/*.js", "**/*.jsx"],
"exclude": ["node_modules"]
} }

View File

@@ -1,153 +0,0 @@
// 1) GoogleFonts Platzhalter
export const inter = { className: "", variable: "--font-inter" };
export const roboto = { className: "", variable: "--font-roboto" };
export const openSans = { className: "", variable: "--font-opensans" };
export const montserrat = { className: "", variable: "--font-montserrat" };
export const raleway = { className: "", variable: "--font-raleway" };
export const poppins = { className: "", variable: "--font-poppins" };
export const manrope = { className: "", variable: "--font-manrope" };
export const dmSans = { className: "", variable: "--font-dmsans" };
export const plusJakartaSans = {
className: "",
variable: "--font-plusjakarta",
};
export const spaceGrotesk = { className: "", variable: "--font-spacegrotesk" };
export const dancingScript = {
className: "",
variable: "--font-dancingscript",
};
export const pacifico = { className: "", variable: "--font-pacifico" };
export const caveat = { className: "", variable: "--font-caveat" };
export const indieFlower = { className: "", variable: "--font-indieflower" };
export const greatVibes = { className: "", variable: "--font-greatvibes" };
export const sacramento = { className: "", variable: "--font-sacramento" };
export const alexBrush = { className: "", variable: "--font-alexbrush" };
export const amaticSC = { className: "", variable: "--font-amaticsc" };
export const marckScript = { className: "", variable: "--font-marckscript" };
export const protestRevolution = {
className: "",
variable: "--font-protestrevolution",
};
export const anton = { className: "", variable: "--font-anton" };
export const bebasNeue = { className: "", variable: "--font-bebasneue" };
export const oswald = { className: "", variable: "--font-oswald" };
export const bangers = { className: "", variable: "--font-bangers" };
export const ultra = { className: "", variable: "--font-ultra" };
export const abrilFatface = { className: "", variable: "--font-abrilfatface" };
export const fjallaOne = { className: "", variable: "--font-fjallaone" };
export const fredokaOne = { className: "", variable: "--font-fredokaone" };
export const luckiestGuy = { className: "", variable: "--font-luckiestguy" };
export const fugazOne = { className: "", variable: "--font-fugazone" };
export const shrikhand = { className: "", variable: "--font-shrikhand" };
export const chango = { className: "", variable: "--font-chango" };
export const gravitasOne = { className: "", variable: "--font-gravitasone" };
export const coiny = { className: "", variable: "--font-coiny" };
export const quicksand = { className: "", variable: "--font-quicksand" };
export const orbitron = { className: "", variable: "--font-orbitron" };
export const zenDots = { className: "", variable: "--font-zendots" };
export const audiowide = { className: "", variable: "--font-audiowide" };
export const exo2 = { className: "", variable: "--font-exo2" };
export const rajdhani = { className: "", variable: "--font-rajdhani" };
export const syncopate = { className: "", variable: "--font-syncopate" };
export const pressStart2p = { className: "", variable: "--font-pressstart2p" };
export const shareTechMono = {
className: "",
variable: "--font-sharetechmono",
};
export const playfairDisplay = {
className: "",
variable: "--font-playfairdisplay",
};
export const cinzel = { className: "", variable: "--font-cinzel" };
export const italiana = { className: "", variable: "--font-italiana" };
export const youngSerif = { className: "", variable: "--font-youngserif" };
export const caprasimo = { className: "", variable: "--font-caprasimo" };
export const righteous = { className: "", variable: "--font-righteous" };
export const luxuriousRoman = {
className: "",
variable: "--font-luxuriousroman",
};
export const vt323 = { className: "", variable: "--font-vt323" };
export const neonderthaw = { className: "", variable: "--font-neonderthaw" };
// 2) SystemFonts
export const systemFonts = {
helvetica: { className: "font-helvetica", variable: "--font-helvetica" },
arial: { className: "font-arial", variable: "--font-arial" },
comicSans: { className: "font-comicsans", variable: "--font-comicsans" },
};
// 3) PseudoFonts
export const pseudoFonts = {
bubble: { className: "", variable: "--font-bubble" },
glitch: { className: "", variable: "--font-glitch" },
wide: { className: "", variable: "--font-wide" },
upsideDown: { className: "", variable: "--font-upsidedown" },
strikethrough: { className: "", variable: "--font-strikethrough" },
underline: { className: "", variable: "--font-underline" },
};
// Zusammenfassung aller Fonts
export const fonts = {
Inter: inter,
Roboto: roboto,
Open_Sans: openSans,
Montserrat: montserrat,
Raleway: raleway,
Poppins: poppins,
Manrope: manrope,
DM_Sans: dmSans,
Plus_Jakarta_Sans: plusJakartaSans,
Space_Grotesk: spaceGrotesk,
Dancing_Script: dancingScript,
Pacifico: pacifico,
Caveat: caveat,
Indie_Flower: indieFlower,
Great_Vibes: greatVibes,
Sacramento: sacramento,
Alex_Brush: alexBrush,
Amatic_SC: amaticSC,
Marck_Script: marckScript,
Protest_Revolution: protestRevolution,
Anton: anton,
Bebas_Neue: bebasNeue,
Oswald: oswald,
Bangers: bangers,
Ultra: ultra,
Abril_Fatface: abrilFatface,
Fjalla_One: fjallaOne,
Fredoka_One: fredokaOne,
Luckiest_Guy: luckiestGuy,
Fugaz_One: fugazOne,
Shrikhand: shrikhand,
Chango: chango,
Gravitas_One: gravitasOne,
Coiny: coiny,
Quicksand: quicksand,
Orbitron: orbitron,
Zen_Dots: zenDots,
Audiowide: audiowide,
Exo_2: exo2,
Rajdhani: rajdhani,
Syncopate: syncopate,
Press_Start_2P: pressStart2p,
Share_Tech_Mono: shareTechMono,
Playfair_Display: playfairDisplay,
Cinzel: cinzel,
Italiana: italiana,
Young_Serif: youngSerif,
Caprasimo: caprasimo,
Righteous: righteous,
Luxurious_Roman: luxuriousRoman,
VT323: vt323,
Neonderthaw: neonderthaw,
...systemFonts,
...pseudoFonts,
};
export const getFontData = (key) => fonts[key] ?? inter;

View File

@@ -1,14 +0,0 @@
/**
* Enthält **nur** die CSSVariablenNamen, die next/font im Browser setzt.
* In fonts.js werden sie erzeugt, hier referenzieren wir sie nur.
*/
export default {
montserrat: "--font-montserrat",
bebasneue: "--font-bebasneue",
pacifico: "--font-pacifico",
caveat: "--font-caveat",
fredokaone: "--font-fredokaone",
playfair: "--font-playfair",
vt323: "--font-vt323",
// … alle weiteren Fonts, die du brauchst
};

View File

@@ -1,9 +1,8 @@
/** @type {import('next').NextConfig} */ /** @type {import('next').NextConfig} */
const nextConfig = { const nextConfig = {
// Deine sonstigen NextOptionen, z.B.: experimental: {
// reactStrictMode: true, // hier können andere gültige experimentelle Optionen stehen, falls nötig
// images: { domains: [...] }, },
// rewrites: async () => [ ... ],
}; };
module.exports = nextConfig; module.exports = nextConfig;

View File

@@ -1,12 +0,0 @@
// next.config.mjs
import path from "path";
import withFlowbiteReact from "flowbite-react/plugin/nextjs";
const nextConfig = {
webpack: (config) => {
config.resolve.alias["@"] = path.resolve(process.cwd());
return config;
},
};
export default withFlowbiteReact(nextConfig);

1193
package-lock.json generated

File diff suppressed because it is too large Load Diff

View File

@@ -1,17 +1,6 @@
// pages/_app.jsx import "@/styles/tailwind.build.css"; // dein Tailwind-Build
import "@/styles/tailwind.build.css"; // dein TailwindBuild import "../styles/globals.css";
import { fonts } from "@/lib/fonts";
// Alle CSSVariablen aus deinen next/fontLoaders, damit die Utilities greifen
const allFontVars = Object.values(fonts)
.map((f) => f.variable)
.join(" ");
export default function MyApp({ Component, pageProps }) { export default function MyApp({ Component, pageProps }) {
return ( return <Component {...pageProps} />;
<main className={allFontVars}>
<Component {...pageProps} />
</main>
);
} }

View File

@@ -14,10 +14,18 @@ export default class MyDocument extends Document {
crossOrigin="" crossOrigin=""
/> />
{/* Alle 30 GoogleFonts */} {/* Google Fonts ALLE 60 Fonts */}
<link <link
rel="stylesheet" rel="stylesheet"
href="https://fonts.googleapis.com/css2?family=Inter:wght@100..900&family=Roboto:wght@100..900&family=Open+Sans&family=Montserrat:wght@100..900&family=Raleway:wght@100..900&family=Poppins:wght@100..900&family=Manrope:wght@100..700&family=Dancing+Script&family=Pacifico&family=Caveat&family=Indie+Flower&family=Great+Vibes&family=Sacramento&family=Alex+Brush&family=Anton&family=Bebas+Neue&family=Oswald:wght@200..700&family=Bangers&family=Abril+Fatface&family=Fredoka+One&family=Luckiest+Guy&family=Orbitron&family=Audiowide&family=Exo+2&family=Rajdhani&family=Syncopate&family=Press+Start+2P&family=Share+Tech+Mono&family=Playfair+Display&family=Cinzel&family=Italiana&family=Young+Serif&family=Caprasimo&family=Righteous&family=Luxurious+Roman&family=VT323&family=Neonderthaw&display=swap" href="https://fonts.googleapis.com/css2?family=Inter:wght@100..900&family=Roboto&family=Open+Sans&family=Montserrat:wght@100..900&family=Raleway:wght@100..900&family=Poppins:wght@100..900&family=Manrope:wght@100..700&family=Jost:wght@100..900&family=Quicksand&family=Noto+Sans&family=Syncopate&family=Orbitron&family=Work+Sans&family=Spectral&family=Philosopher&family=Alegreya&family=Holtwood+One+SC&family=Italiana&family=Almendra&family=Cinzel+Decorative&family=Staatliches&family=Averia+Libre&family=Germania+One&display=swap"
/>
<link
rel="stylesheet"
href="https://fonts.googleapis.com/css2?family=Pacifico&family=Great+Vibes&family=Courgette&family=Architects+Daughter&family=Neucha&family=Satisfy&family=Yellowtail&family=Indie+Flower&family=Gloria+Hallelujah&family=Alex+Brush&family=Dancing+Script&family=Kaushan+Script&family=Sacramento&family=Amatic+SC&family=Caveat&display=swap"
/>
<link
rel="stylesheet"
href="https://fonts.googleapis.com/css2?family=Anton&family=Bebas+Neue&family=Ultra&family=Oswald:wght@200..700&family=Playfair+Display&family=Abril+Fatface&family=Black+Ops+One&family=Righteous&family=Metal+Mania&family=Press+Start+2P&family=Stint+Ultra+Condensed&family=Exo&family=Audiowide&family=Rajdhani&family=Questrial&family=Space+Mono&family=Unica+One&family=Glass+Antiqua&family=Fjalla+One&family=Bungee&family=Andika&family=Alfa+Slab+One&family=Permanent+Marker&display=swap"
/> />
</Head> </Head>
<body> <body>

View File

@@ -9,12 +9,14 @@ import {
getPopularFonts, getPopularFonts,
transformText, transformText,
} from "@/components/fontTransforms"; } from "@/components/fontTransforms";
import MobileOptimizedHeader from "@/components/MobileOptimizedHeader"; import MobileOptimizedHeader from "@/components/MobileOptimizedHeader";
import EnhancedTextInput from "@/components/EnhancedTextInput"; import EnhancedTextInput from "@/components/EnhancedTextInput";
import ImprovedCategoryFilter from "@/components/ImprovedCategoryFilter"; import ImprovedCategoryFilter from "@/components/ImprovedCategoryFilter";
import PerformanceOptimizedFontCard from "@/components/PerformanceOptimizedFontCard"; import PerformanceOptimizedFontCard from "@/components/PerformanceOptimizedFontCard";
import InfoSection from "@/components/InfoSection"; import InfoSection from "@/components/InfoSection";
import SocialButtons from "@/components/SocialButtons"; import SocialButtons from "@/components/SocialButtons";
import FancyTextPreview from "@/components/FancyTextPreview";
import SEOHead from "@/components/SEOHead"; import SEOHead from "@/components/SEOHead";
if (typeof window !== "undefined") { if (typeof window !== "undefined") {
@@ -28,6 +30,7 @@ export default function HomePage() {
const [searchQuery, setSearchQuery] = useState(""); const [searchQuery, setSearchQuery] = useState("");
const [recentFonts, setRecentFonts] = useState([]); const [recentFonts, setRecentFonts] = useState([]);
const [isMobile, setIsMobile] = useState(false); const [isMobile, setIsMobile] = useState(false);
const [animationsEnabled, setAnimationsEnabled] = useState(() => { const [animationsEnabled, setAnimationsEnabled] = useState(() => {
if (typeof window !== "undefined") { if (typeof window !== "undefined") {
const hasReducedMotion = window.matchMedia("(prefers-reduced-motion: reduce)").matches; const hasReducedMotion = window.matchMedia("(prefers-reduced-motion: reduce)").matches;
@@ -248,6 +251,7 @@ export default function HomePage() {
</AnimatePresence> </AnimatePresence>
</motion.div> </motion.div>
<SocialButtons onShare={handleQuickShare} /> <SocialButtons onShare={handleQuickShare} />
<InfoSection currentText={debouncedText} /> <InfoSection currentText={debouncedText} />
</div> </div>

Binary file not shown.

BIN
public/fonts/alegreya.woff2 Normal file

Binary file not shown.

Binary file not shown.

BIN
public/fonts/almendra.woff2 Normal file

Binary file not shown.

Binary file not shown.

BIN
public/fonts/andika.woff2 Normal file

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

BIN
public/fonts/caveat.woff2 Normal file

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

BIN
public/fonts/exo.woff2 Normal file

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

BIN
public/fonts/italiana.woff2 Normal file

Binary file not shown.

BIN
public/fonts/jost.woff2 Normal file

Binary file not shown.

Binary file not shown.

BIN
public/fonts/lato.woff2 Normal file

Binary file not shown.

Binary file not shown.

Binary file not shown.

BIN
public/fonts/neucha.woff2 Normal file

Binary file not shown.

Binary file not shown.

Binary file not shown.

BIN
public/fonts/orbitron.woff2 Normal file

Binary file not shown.

BIN
public/fonts/oswald.woff2 Normal file

Binary file not shown.

BIN
public/fonts/pacifico.woff2 Normal file

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

BIN
public/fonts/poppins.woff2 Normal file

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

BIN
public/fonts/rajdhani.woff2 Normal file

Binary file not shown.

BIN
public/fonts/raleway.woff2 Normal file

Binary file not shown.

Binary file not shown.

BIN
public/fonts/roboto.woff2 Normal file

Binary file not shown.

Binary file not shown.

BIN
public/fonts/satisfy.woff2 Normal file

Binary file not shown.

Binary file not shown.

BIN
public/fonts/spectral.woff2 Normal file

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

BIN
public/fonts/ultra.woff2 Normal file

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

View File

@@ -1,73 +1,254 @@
@import url("https://fonts.googleapis.com/css2?family=Montserrat:wght@400;500;600&display=swap"); /* globals.css */
@import url("https://fonts.googleapis.com/css2?family=Bebas+Neue&display=swap");
@import url("https://fonts.googleapis.com/css2?family=Pacifico&display=swap");
@import url("https://fonts.googleapis.com/css2?family=Caveat&display=swap");
@import url("https://fonts.googleapis.com/css2?family=Fredoka+One&display=swap");
@import url("https://fonts.googleapis.com/css2?family=Playfair+Display&display=swap");
@import url("https://fonts.googleapis.com/css2?family=VT323&display=swap");
@tailwind base; @tailwind base;
@tailwind components; @tailwind components;
@tailwind utilities; @tailwind utilities;
@layer utilities { /* === Font-Definitionen === */
.font-montserrat { @font-face {
font-family: "Montserrat", sans-serif; font-family: 'Anton';
font-style: normal;
font-weight: 400;
font-display: swap;
src: ur[](https://fonts.gstatic.com/s/anton/v26/1Ptgg87LROyAm3K8-C8QSw.woff2) format('woff2');
unicode-range: U+0102-0103, U+0110-0111, U+0128-0129, U+0168-0169, U+01A0-01A1, U+01AF-01B0, U+0300-0301, U+0303-0304, U+0308-0309, U+0323, U+0329, U+1EA0-1EF9, U+20AB;
} }
.font-bebasneue { @font-face {
font-family: "Bebas Neue", cursive; font-family: 'Anton';
font-style: normal;
font-weight: 400;
font-display: swap;
src: ur[](https://fonts.gstatic.com/s/anton/v26/1Ptgg87LROyAm3K9-C8QSw.woff2) format('woff2');
unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF;
}
@font-face {
font-family: 'Anton';
font-style: normal;
font-weight: 400;
font-display: swap;
src: ur[](https://fonts.gstatic.com/s/anton/v26/1Ptgg87LROyAm3Kz-C8.woff2) format('woff2');
unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}
@font-face {
font-family: 'Bebas Neue';
font-style: normal;
font-weight: 400;
font-display: swap;
src: ur[](https://fonts.gstatic.com/s/bebasneue/v15/JTUSjIg69CK48gW7PXoo9Wdhyzbi.woff2) format('woff2');
unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF;
}
@font-face {
font-family: 'Bebas Neue';
font-style: normal;
font-weight: 400;
font-display: swap;
src: ur[](https://fonts.gstatic.com/s/bebasneue/v15/JTUSjIg69CK48gW7PXoo9Wlhyw.woff2) format('woff2');
unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}
@font-face {
font-family: 'Dancing Script';
font-style: normal;
font-weight: 400;
font-display: swap;
src: ur[](https://fonts.gstatic.com/s/dancingscript/v28/If2cXTr6YS-zF4S-kcSWSVi_sxjsohD9F50Ruu7BMSo3Rep8ltA.woff2) format('woff2');
unicode-range: U+0102-0103, U+0110-0111, U+0128-0129, U+0168-0169, U+01A0-01A1, U+01AF-01B0, U+0300-0301, U+0303-0304, U+0308-0309, U+0323, U+0329, U+1EA0-1EF9, U+20AB;
}
@font-face {
font-family: 'Dancing Script';
font-style: normal;
font-weight: 400;
font-display: swap;
src: ur[](https://fonts.gstatic.com/s/dancingscript/v28/If2cXTr6YS-zF4S-kcSWSVi_sxjsohD9F50Ruu7BMSo3ROp8ltA.woff2) format('woff2');
unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF;
}
@font-face {
font-family: 'Dancing Script';
font-style: normal;
font-weight: 400;
font-display: swap;
src: ur[](https://fonts.gstatic.com/s/dancingscript/v28/If2cXTr6YS-zF4S-kcSWSVi_sxjsohD9F50Ruu7BMSo3Sup8.woff2) format('woff2');
unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}
@font-face {
font-family: 'Montserrat';
font-style: normal;
font-weight: 500;
font-display: swap;
src: ur[](https://fonts.gstatic.com/s/montserrat/v30/JTUHjIg1_i6t8kCHKm4532VJOt5-QNFgpCtZ6Hw0aXpsog.woff2) format('woff2');
unicode-range: U+0460-052F, U+1C80-1C8A, U+20B4, U+2DE0-2DFF, U+A640-A69F, U+FE2E-FE2F;
}
@font-face {
font-family: 'Montserrat';
font-style: normal;
font-weight: 500;
font-display: swap;
src: ur[](https://fonts.gstatic.com/s/montserrat/v30/JTUHjIg1_i6t8kCHKm4532VJOt5-QNFgpCtZ6Hw9aXpsog.woff2) format('woff2');
unicode-range: U+0301, U+0400-045F, U+0490-0491, U+04B0-04B1, U+2116;
}
@font-face {
font-family: 'Montserrat';
font-style: normal;
font-weight: 500;
font-display: swap;
src: ur[](https://fonts.gstatic.com/s/montserrat/v30/JTUHjIg1_i6t8kCHKm4532VJOt5-QNFgpCtZ6Hw2aXpsog.woff2) format('woff2');
unicode-range: U+0102-0103, U+0110-0111, U+0128-0129, U+0168-0169, U+01A0-01A1, U+01AF-01B0, U+0300-0301, U+0303-0304, U+0308-0309, U+0323, U+0329, U+1EA0-1EF9, U+20AB;
}
@font-face {
font-family: 'Montserrat';
font-style: normal;
font-weight: 500;
font-display: swap;
src: ur[](https://fonts.gstatic.com/s/montserrat/v30/JTUHjIg1_i6t8kCHKm4532VJOt5-QNFgpCtZ6Hw3aXpsog.woff2) format('woff2');
unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF;
}
@font-face {
font-family: 'Montserrat';
font-style: normal;
font-weight: 500;
font-display: swap;
src: ur[](https://fonts.gstatic.com/s/montserrat/v30/JTUHjIg1_i6t8kCHKm4532VJOt5-QNFgpCtZ6Hw5aXo.woff2) format('woff2');
unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}
@font-face {
font-family: 'Orbitron';
font-style: normal;
font-weight: 400;
font-display: swap;
src: ur[](https://fonts.gstatic.com/s/orbitron/v34/yMJMMIlzdpvBhQQL_SC3X9yhF25-T1nyGy6BoWgz.woff2) format('woff2');
unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}
@font-face {
font-family: 'Pacifico';
font-style: normal;
font-weight: 400;
font-display: swap;
src: ur[](https://fonts.gstatic.com/s/pacifico/v22/FwZY7-Qmy14u9lezJ-6K6MmTpA.woff2) format('woff2');
unicode-range: U+0460-052F, U+1C80-1C8A, U+20B4, U+2DE0-2DFF, U+A640-A69F, U+FE2E-FE2F;
}
@font-face {
font-family: 'Pacifico';
font-style: normal;
font-weight: 400;
font-display: swap;
src: ur[](https://fonts.gstatic.com/s/pacifico/v22/FwZY7-Qmy14u9lezJ-6D6MmTpA.woff2) format('woff2');
unicode-range: U+0301, U+0400-045F, U+0490-0491, U+04B0-04B1, U+2116;
}
@font-face {
font-family: 'Pacifico';
font-style: normal;
font-weight: 400;
font-display: swap;
src: ur[](https://fonts.gstatic.com/s/pacifico/v22/FwZY7-Qmy14u9lezJ-6I6MmTpA.woff2) format('woff2');
unicode-range: U+0102-0103, U+0110-0111, U+0128-0129, U+0168-0169, U+01A0-01A1, U+01AF-01B0, U+0300-0301, U+0303-0304, U+0308-0309, U+0323, U+0329, U+1EA0-1EF9, U+20AB;
}
@font-face {
font-family: 'Pacifico';
font-style: normal;
font-weight: 400;
font-display: swap;
src: ur[](https://fonts.gstatic.com/s/pacifico/v22/FwZY7-Qmy14u9lezJ-6J6MmTpA.woff2) format('woff2');
unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF;
}
@font-face {
font-family: 'Pacifico';
font-style: normal;
font-weight: 400;
font-display: swap;
src: ur[](https://fonts.gstatic.com/s/pacifico/v22/FwZY7-Qmy14u9lezJ-6H6Mk.woff2) format('woff2');
unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}
@font-face {
font-family: 'Playfair Display';
font-style: normal;
font-weight: 400;
font-display: swap;
src: ur[](https://fonts.gstatic.com/s/playfairdisplay/v39/nuFvD-vYSZviVYUb_rj3ij__anPXJzDwcbmjWBN2PKdFvXDTbtPY_Q.woff2) format('woff2');
unicode-range: U+0301, U+0400-045F, U+0490-0491, U+04B0-04B1, U+2116;
}
@font-face {
font-family: 'Playfair Display';
font-style: normal;
font-weight: 400;
font-display: swap;
src: ur[](https://fonts.gstatic.com/s/playfairdisplay/v39/nuFvD-vYSZviVYUb_rj3ij__anPXJzDwcbmjWBN2PKdFvXDYbtPY_Q.woff2) format('woff2');
unicode-range: U+0102-0103, U+0110-0111, U+0128-0129, U+0168-0169, U+01A0-01A1, U+01AF-01B0, U+0300-0301, U+0303-0304, U+0308-0309, U+0323, U+0329, U+1EA0-1EF9, U+20AB;
}
@font-face {
font-family: 'Playfair Display';
font-style: normal;
font-weight: 400;
font-display: swap;
src: ur[](https://fonts.gstatic.com/s/playfairdisplay/v39/nuFvD-vYSZviVYUb_rj3ij__anPXJzDwcbmjWBN2PKdFvXDZbtPY_Q.woff2) format('woff2');
unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF;
}
@font-face {
font-family: 'Playfair Display';
font-style: normal;
font-weight: 400;
font-display: swap;
src: ur[](https://fonts.gstatic.com/s/playfairdisplay/v39/nuFvD-vYSZviVYUb_rj3ij__anPXJzDwcbmjWBN2PKdFvXDXbtM.woff2) format('woff2');
unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}
@font-face {
font-family: 'Poppins';
font-style: normal;
font-weight: 500;
font-display: swap;
src: ur[](https://fonts.gstatic.com/s/poppins/v23/pxiByp8kv8JHgFVrLGT9Z11lFc-K.woff2) format('woff2');
unicode-range: U+0900-097F, U+1CD0-1CF9, U+200C-200D, U+20A8, U+20B9, U+20F0, U+25CC, U+A830-A839, U+A8E0-A8FF, U+11B00-11B09;
}
@font-face {
font-family: 'Poppins';
font-style: normal;
font-weight: 500;
font-display: swap;
src: ur[](https://fonts.gstatic.com/s/poppins/v23/pxiByp8kv8JHgFVrLGT9Z1JlFc-K.woff2) format('woff2');
unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF;
}
@font-face {
font-family: 'Poppins';
font-style: normal;
font-weight: 500;
font-display: swap;
src: ur[](https://fonts.gstatic.com/s/poppins/v23/pxiByp8kv8JHgFVrLGT9Z1xlFQ.woff2) format('woff2');
unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}
/* === Tailwind Utility-Klassen === */
@layer utilities {
.font-anton {
font-family: 'Anton', sans-serif;
}
.font-bebas-neue {
font-family: 'Bebas Neue', sans-serif;
}
.font-dancing-script {
font-family: 'Dancing Script', cursive;
}
.font-montserrat {
font-family: 'Montserrat', sans-serif;
}
.font-orbitron {
font-family: 'Orbitron', sans-serif;
} }
.font-pacifico { .font-pacifico {
font-family: "Pacifico", cursive; font-family: 'Pacifico', cursive;
} }
.font-caveat { .font-playfair-display {
font-family: "Caveat", cursive; font-family: 'Playfair Display', serif;
} }
.font-fredokaone { .font-poppins {
font-family: "Fredoka One", cursive; font-family: 'Poppins', sans-serif;
}
.font-playfair {
font-family: "Playfair Display", serif;
}
.font-vt323 {
font-family: "VT323", monospace;
}
/* Pseudo / Unicode Platzhalter */
.font-bubble {
font-family: inherit;
}
.font-glitch {
font-family: inherit;
}
.font-wide {
font-family: inherit;
}
.font-upsidedown {
font-family: inherit;
}
.font-strike {
text-decoration: line-through;
}
.font-underline {
text-decoration: underline;
}
}
/* eigene ZusatzUtilities */
@layer utilities {
.font-chilanka {
font-family: "Chilanka", cursive;
} }
} }
/* Komponenten */
@layer components { @layer components {
.text-shadow-lg { .text-shadow-lg {
text-shadow: 0 4px 6px rgba(0, 0, 0, 0.1); text-shadow: 0 4px 6px rgba(0, 0, 0, 0.1);
} }
} }
/* SchnellCheck */ /* Basis-Styling */
body { body {
background: #111; background: #111;
color: #fff; color: #fff;

0
styles/local-fonts.css Normal file
View File

File diff suppressed because it is too large Load Diff

View File

@@ -1,29 +1,30 @@
// tailwind.config.js /** @type {import('tailwindcss').Config} */
import { fonts } from "./lib/fonts.js"; module.exports = {
const fontFamily = Object.fromEntries(
Object.entries(fonts)
.filter(([, d]) => d?.variable)
.map(([name, d]) => [
name.toLowerCase().replace(/\s+/g, ""),
[`var(${d.variable})`],
])
);
export default {
content: [ content: [
"./pages/**/*.{js,jsx,ts,tsx}", "./pages/**/*.{js,jsx,ts,tsx}",
"./components/**/*.{js,jsx,ts,tsx}", "./components/**/*.{js,jsx,ts,tsx}",
"./lib/**/*.{js,jsx,ts,tsx}", "./lib/**/*.{js,jsx,ts,tsx}",
"./styles/**/*.{css,js}", "./styles/**/*.{css,js}",
], ],
theme: { extend: { fontFamily } }, theme: {
extend: {
fontFamily: {
'anton': ['"Anton"', 'sans-serif'],
'bebas-neue': ['"Bebas Neue"', 'sans-serif'],
'dancing-script': ['"Dancing Script"', 'cursive'],
'montserrat': ['"Montserrat"', 'sans-serif'],
'orbitron': ['"Orbitron"', 'sans-serif'],
'pacifico': ['"Pacifico"', 'cursive'],
'playfair-display': ['"Playfair Display"', 'serif'],
'poppins': ['"Poppins"', 'sans-serif'],
},
},
},
plugins: [], plugins: [],
// <<< Hier kommt die Safelist >>>
safelist: [ safelist: [
{ {
pattern: /^font-/, pattern: /^font-(anton|bebas-neue|dancing-script|montserrat|orbitron|pacifico|playfair-display|poppins)$/,
variants: ["sm", "md", "lg", "xl"], // optional, falls responsive Klassen gebraucht werden variants: ["sm", "md", "lg", "xl"],
}, },
], ],
}; };

View File

@@ -1,22 +0,0 @@
import tailwindFonts from "./lib/tailwind-font-map.js"; // ← **ASCIIMinus!**
/** @type {import('tailwindcss').Config} */
export default {
content: [
"./pages/**/*.{js,jsx,ts,tsx}",
"./components/**/*.{js,jsx,ts,tsx}",
"./entities/**/*.{js,jsx,ts,tsx}",
".flowbite-react/class-list.json",
],
theme: {
extend: {
fontFamily: Object.fromEntries(
Object.entries(tailwindFonts).map(([k, cssVar]) => [
k,
[`var(${cssVar})`],
])
),
},
},
plugins: [],
};