Initial commit

This commit is contained in:
Timo Knuth 2025-08-03 18:48:24 +02:00
parent 49bb62fc4e
commit 62ebe48adb
14 changed files with 1262 additions and 1092 deletions

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

@ -95,26 +95,16 @@ 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) return baseStyle;
'Bebas Neue': { fontFamily: '"Bebas Neue", cursive', fontWeight: "400", textTransform: "uppercase", letterSpacing: "0.05em" },
Oswald: { fontFamily: "Oswald, sans-serif", fontWeight: "500", textTransform: "uppercase" }, const style = { ...baseStyle };
Raleway: { fontFamily: "Raleway, sans-serif", fontWeight: "400" }, if (fontEntry.fontFamily) style.fontFamily = fontEntry.fontFamily;
Poppins: { fontFamily: "Poppins, sans-serif", fontWeight: "500" }, if (fontEntry.fontWeight) style.fontWeight = fontEntry.fontWeight;
Inter: { fontFamily: "Inter, sans-serif", fontWeight: "400" }, if (fontEntry.textTransform) style.textTransform = fontEntry.textTransform;
Caveat: { fontFamily: "Caveat, cursive", fontWeight: "400" }, if (fontEntry.letterSpacing) style.letterSpacing = fontEntry.letterSpacing;
Pacifico: { fontFamily: "Pacifico, cursive", fontWeight: "400" }, if (fontEntry.fontSize) style.fontSize = fontEntry.fontSize;
'Dancing Script': { fontFamily: '"Dancing Script", cursive', fontWeight: "400" }, return style;
'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 previewText = sStr(transformedText) || "Hallo Instagram!"; const previewText = sStr(transformedText) || "Hallo Instagram!";
@ -185,7 +175,7 @@ const PerformanceOptimizedFontCard = forwardRef(({
{copied ? ( {copied ? (
<><Check className="w-4 h-4 mr-2" /> Copy! </> <><Check className="w-4 h-4 mr-2" /> Copy! </>
) : ( ) : (
<><Copy className="w-4 h-4 mr-2" /> Copy! </> <><Copy className="w-4 h-4 mr-2" /> Start Typing </>
)} )}
</Button> </Button>
</div> </div>

View File

@ -1,20 +1,18 @@
// 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) // 1) 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 // 2) Unicode-Mapping-Helfer
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 +21,105 @@ 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 // 3) Font-Transformationen
export const fontTransforms = { export const fontTransforms = Object.fromEntries(
// 🔤 Modern Clean & professional Object.entries({
Montserrat: { transform: createTransform('sansSerifBold'), category: 'modern', description: 'Montserrat Sans-Serif Bold Unicode' }, // 🔤 Modern
Lato: { transform: createTransform('sansSerif'), category: 'modern', description: 'Lato Humanistischer Sans-Serif Unicode' }, Montserrat: ['sansSerifBold', 'modern', 'Montserrat Sans-Serif Bold Unicode'],
Raleway: { transform: createTransform('sansSerif'), category: 'modern', description: 'Raleway Elegant Display Unicode' }, Lato: ['sansSerif', 'modern', 'Lato Humanistischer Sans-Serif Unicode'],
Poppins: { transform: createTransform('sansSerif'), category: 'modern', description: 'Poppins Rund & freundlich Unicode' }, Raleway: ['sansSerif', 'modern', 'Raleway Elegant Display Unicode'],
'Open Sans': { transform: createTransform('sansSerif'), category: 'modern', description: 'Open Sans Vielseitig Unicode' }, Poppins: ['sansSerif', 'modern', 'Poppins Rund & freundlich Unicode'],
Roboto: { transform: createTransform('sansSerif'), category: 'modern', description: 'Roboto Modernes Grotesk Unicode' }, 'Open Sans': ['sansSerif', 'modern', 'Open Sans Vielseitig Unicode'],
'Work Sans': { transform: createTransform('sansSerif'), category: 'modern', description: 'Work Sans Tech & Clean 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 // Handwriting
Pacifico: { transform: createTransform('scriptBold'), category: 'handwriting', description: 'Pacifico Lockerer Pinsel Bold Script Unicode' }, Pacifico: ['scriptBold', 'handwriting', 'Pacifico Lockerer Pinsel Bold Script Unicode'],
Sacramento: { transform: createTransform('scriptBold'), category: 'handwriting', description: 'Sacramento Retro-Handlettering Bold Script Unicode' }, Sacramento: ['scriptBold', 'handwriting', 'Sacramento Retro-Handlettering Bold Script Unicode'],
Caveat: { transform: createTransform('scriptBold'), category: 'handwriting', description: 'Caveat Natural Handwriting Bold Script Unicode' }, Caveat: ['scriptBold', 'handwriting', 'Caveat Natural Handwriting Bold Script Unicode'],
'Dancing Script': { transform: createTransform('scriptBold'), category: 'handwriting', description: 'Dancing Script Lebhafte Kursive Bold Script Unicode' }, 'Dancing Script': ['scriptBold', 'handwriting', 'Dancing Script Lebhafte Kursive Bold Script Unicode'],
'Indie Flower': { transform: createTransform('scriptBold'), category: 'handwriting', description: 'Indie Flower Verspieltes Bold Script Unicode' }, 'Indie Flower': ['scriptBold', 'handwriting', 'Indie Flower Verspieltes Bold Script Unicode'],
'Amatic SC': { transform: createTransform('scriptBold'), category: 'handwriting', description: 'Amatic SC Skizzenartiges Bold Script Unicode' }, 'Amatic SC': ['scriptBold', 'handwriting', 'Amatic SC Skizzenartiges Bold Script Unicode'],
'Kaushan Script': { transform: createTransform('scriptBold'), category: 'handwriting', description: 'Kaushan Script Fettere Kursive 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 // 🧑🎤 Statement
Oswald: { transform: createTransform('sansSerifBold'), category: 'statement', description: 'Oswald Bold Grotesk Unicode' }, Oswald: ['sansSerifBold', 'statement', 'Oswald Bold Grotesk Unicode'],
'Bebas Neue': { transform: createTransform('fullwidth'), category: 'statement', description: 'Bebas Neue Fullwidth Caps Unicode' }, 'Bebas Neue': ['fullwidth', 'statement', 'Bebas Neue Fullwidth Caps Unicode'],
Anton: { transform: createTransform('fullwidth'), category: 'statement', description: 'Anton Plakative Fullwidth Unicode' }, Anton: ['fullwidth', 'statement', 'Anton Plakative Fullwidth Unicode'],
Ultra: { transform: createTransform('sansSerifBold'), category: 'statement', description: 'Ultra Kompakte Bold Unicode' }, Ultra: ['sansSerifBold', 'statement', 'Ultra Kompakte Bold Unicode'],
'Stint Ultra Condensed': { transform: createTransform('sansSerifBold'), category: 'statement', description: 'Stint Ultra Condensed Kompakte Bold Unicode' }, 'Stint Ultra Condensed': ['sansSerifBold', 'statement', 'Stint Ultra Condensed Kompakte Bold Unicode'],
'Playfair Display': { transform: createTransform('scriptBold'), category: 'statement', description: 'Playfair Display Elegante Bold Script Unicode' }, 'Playfair Display': ['scriptBold', 'statement', 'Playfair Display Elegante Bold Script Unicode'],
'Abril Fatface': { transform: createTransform('scriptBold'), category: 'statement', description: 'Abril Fatface Fettere 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 // 🚀 Futuristic
Exo: { transform: createTransform('sansSerif'), category: 'futuristic', description: 'Exo Tech Grotesk Unicode' }, Exo: ['sansSerif', 'futuristic', 'Exo Tech Grotesk Unicode'],
Orbitron: { transform: createTransform('monospace'), category: 'futuristic', description: 'Orbitron Sci-Fi Monospace Unicode' }, Orbitron: ['monospace', 'futuristic', 'Orbitron Sci-Fi Monospace Unicode'],
Audiowide: { transform: createTransform('monospace'), category: 'futuristic', description: 'Audiowide Rundes Monospace Unicode' }, Audiowide: ['monospace', 'futuristic', 'Audiowide Rundes Monospace Unicode'],
Rajdhani: { transform: createTransform('monospace'), category: 'futuristic', description: 'Rajdhani Digital Monospace Unicode' }, Rajdhani: ['monospace', 'futuristic', 'Rajdhani Digital Monospace Unicode'],
'Space Mono': { transform: createTransform('monospace'), category: 'futuristic', description: 'Space Mono Tech Monospace Unicode' }, 'Space Mono': ['monospace', 'futuristic', 'Space Mono Tech Monospace Unicode'],
Questrial: { transform: createTransform('sansSerif'), category: 'futuristic', description: 'Questrial Clean Sans-Serif 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 // 🧢 Aesthetic
'Press Start 2P': { transform: createTransform('monospace'), category: 'aesthetic', description: 'Press Start 2P Pixel Monospace Unicode' }, 'Press Start 2P': ['monospace', 'aesthetic', 'Press Start 2P Pixel Monospace Unicode'],
Righteous: { transform: createTransform('frakturBold'), category: 'aesthetic', description: 'Righteous Stylische Bold Fraktur Unicode' }, Righteous: ['frakturBold', 'aesthetic', 'Righteous Stylische Bold Fraktur Unicode'],
'Metal Mania': { transform: createTransform('scriptBold'), category: 'aesthetic', description: 'Metal Mania Fettere Script Unicode' } 'Metal Mania': ['scriptBold', 'aesthetic', 'Metal Mania Fettere Script Unicode'],
}; 'Alegreya': ['frakturBold', 'aesthetic', 'Alegreya Literatur Serif Unicode'],
'Spectral': ['frakturBold', 'aesthetic', 'Spectral Editorial Serif Unicode'],
// Hilfsfunktionen 'Fjalla One': ['sansSerifBold', 'aesthetic', 'Fjalla One Headline Sans Unicode'],
export const getPopularFonts = () => Object.keys(fontTransforms).slice(0, 10); 'Glass Antiqua': ['scriptBold', 'aesthetic', 'Glass Antiqua Zarte Antiqua Script Unicode'],
export const getFontsByCategory = (category) => ( 'Cinzel Decorative': ['scriptBold', 'aesthetic', 'Cinzel Decorative Klassische Zier-Serif Unicode'],
category === 'all' 'Andika': ['sansSerif', 'aesthetic', 'Andika Leserlich Unicode'],
? Object.keys(fontTransforms) 'Almendra': ['scriptBold', 'aesthetic', 'Almendra Historische Handschrift Unicode'],
: Object.keys(fontTransforms).filter(f => fontTransforms[f].category === category) }).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) => { 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,
};
}; };
// 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
);

View File

@ -4,8 +4,9 @@ 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"; import { getFontData } from "@/lib/fonts";
import fontMap from "@/lib/tailwind-font-map";
export default function FontCard({ export default function FontCard({
fontName, fontName,
@ -19,12 +20,20 @@ export default function FontCard({
const fontInfo = fontTransforms[fontName]; const fontInfo = fontTransforms[fontName];
const fontData = getFontData(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 = () => { const handleCopy = () => {
if (navigator.clipboard && window.isSecureContext) { if (navigator.clipboard && window.isSecureContext) {
navigator.clipboard navigator.clipboard
.writeText(displayText) .writeText(copyText)
.then(() => flashCopied()) .then(() => flashCopied())
.catch(() => fallbackCopy()); .catch(() => fallbackCopy());
} else { } else {
@ -39,7 +48,7 @@ export default function FontCard({
const fallbackCopy = () => { const fallbackCopy = () => {
const textarea = document.createElement("textarea"); const textarea = document.createElement("textarea");
textarea.value = displayText; textarea.value = copyText;
textarea.setAttribute("readonly", ""); textarea.setAttribute("readonly", "");
textarea.style.position = "fixed"; textarea.style.position = "fixed";
textarea.style.top = "0"; textarea.style.top = "0";
@ -69,7 +78,7 @@ export default function FontCard({
try { try {
await navigator.share({ await navigator.share({
title: `FancyText ${fontName}`, title: `FancyText ${fontName}`,
text: displayText, text: copyText,
url: window.location.href, url: window.location.href,
}); });
} catch (err) { } catch (err) {
@ -124,10 +133,10 @@ 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`}
style={{ lineHeight: "1.2" }} style={{ ...fontVar, lineHeight: "1.2" }}
/> />
<Button <Button

View File

@ -1,153 +1,324 @@
// 1) GoogleFonts Platzhalter // lib/fonts.js
export const inter = { className: "", variable: "--font-inter" }; import {
export const roboto = { className: "", variable: "--font-roboto" }; Montserrat,
export const openSans = { className: "", variable: "--font-opensans" }; Open_Sans,
export const montserrat = { className: "", variable: "--font-montserrat" }; Roboto,
export const raleway = { className: "", variable: "--font-raleway" }; Lato,
export const poppins = { className: "", variable: "--font-poppins" }; Raleway,
export const manrope = { className: "", variable: "--font-manrope" }; Poppins,
export const dmSans = { className: "", variable: "--font-dmsans" }; Work_Sans,
export const plusJakartaSans = { Jost,
className: "", Noto_Sans,
variable: "--font-plusjakarta", Quicksand,
}; Averia_Libre,
export const spaceGrotesk = { className: "", variable: "--font-spacegrotesk" }; Philosopher,
Pacifico,
Caveat,
Sacramento,
Dancing_Script,
Indie_Flower,
Amatic_SC,
Kaushan_Script,
Architects_Daughter,
Neucha,
Great_Vibes,
Satisfy,
Yellowtail,
Gloria_Hallelujah,
Courgette,
Almendra,
Oswald,
Bebas_Neue,
Anton,
Ultra,
Stint_Ultra_Condensed,
Playfair_Display,
Abril_Fatface,
Permanent_Marker,
Alfa_Slab_One,
Black_Ops_One,
Germania_One,
Holtwood_One_SC,
Exo,
Orbitron,
Audiowide,
Rajdhani,
Space_Mono,
Questrial,
Syncopate,
Unica_One,
Italiana,
Staatliches,
Press_Start_2P,
Righteous,
Metal_Mania,
Alegreya,
Spectral,
Fjalla_One,
Glass_Antiqua,
Cinzel_Decorative,
Andika,
} from "next/font/google";
export const dancingScript = { function createFont(fontFn, name) {
className: "", return {
...fontFn,
className: `font-${name.toLowerCase().replace(/\s+/g, "")}`,
};
}
// 🔤 Modern Fonts
const montserrat = Montserrat({
subsets: ["latin"],
variable: "--font-montserrat",
});
const opensans = Open_Sans({ subsets: ["latin"], variable: "--font-opensans" });
const roboto = Roboto({ subsets: ["latin"], variable: "--font-roboto" });
const lato = Lato({ subsets: ["latin"], variable: "--font-lato" });
const raleway = Raleway({ subsets: ["latin"], variable: "--font-raleway" });
const poppins = Poppins({ subsets: ["latin"], variable: "--font-poppins" });
const worksans = Work_Sans({ subsets: ["latin"], variable: "--font-worksans" });
const jost = Jost({ subsets: ["latin"], variable: "--font-jost" });
const notosans = Noto_Sans({ subsets: ["latin"], variable: "--font-notosans" });
const quicksand = Quicksand({
subsets: ["latin"],
variable: "--font-quicksand",
});
const averialibre = Averia_Libre({
subsets: ["latin"],
variable: "--font-averialibre",
});
const philosopher = Philosopher({
subsets: ["latin"],
variable: "--font-philosopher",
});
// ✍️ Handwriting
const pacifico = Pacifico({ subsets: ["latin"], variable: "--font-pacifico" });
const caveat = Caveat({ subsets: ["latin"], variable: "--font-caveat" });
const sacramento = Sacramento({
subsets: ["latin"],
variable: "--font-sacramento",
});
const dancingscript = Dancing_Script({
subsets: ["latin"],
variable: "--font-dancingscript", variable: "--font-dancingscript",
}; });
export const pacifico = { className: "", variable: "--font-pacifico" }; const indieflower = Indie_Flower({
export const caveat = { className: "", variable: "--font-caveat" }; subsets: ["latin"],
export const indieFlower = { className: "", variable: "--font-indieflower" }; variable: "--font-indieflower",
export const greatVibes = { className: "", variable: "--font-greatvibes" }; });
export const sacramento = { className: "", variable: "--font-sacramento" }; const amaticsc = Amatic_SC({ subsets: ["latin"], variable: "--font-amatic" });
export const alexBrush = { className: "", variable: "--font-alexbrush" }; const kaushanscript = Kaushan_Script({
export const amaticSC = { className: "", variable: "--font-amaticsc" }; subsets: ["latin"],
export const marckScript = { className: "", variable: "--font-marckscript" }; variable: "--font-kaushan",
export const protestRevolution = { });
className: "", const architectsdaughter = Architects_Daughter({
variable: "--font-protestrevolution", subsets: ["latin"],
}; variable: "--font-architects",
});
const neucha = Neucha({ subsets: ["latin"], variable: "--font-neucha" });
const greatvibes = Great_Vibes({
subsets: ["latin"],
variable: "--font-greatvibes",
});
const satisfy = Satisfy({ subsets: ["latin"], variable: "--font-satisfy" });
const yellowtail = Yellowtail({
subsets: ["latin"],
variable: "--font-yellowtail",
});
const gloriahallelujah = Gloria_Hallelujah({
subsets: ["latin"],
variable: "--font-gloria",
});
const courgette = Courgette({
subsets: ["latin"],
variable: "--font-courgette",
});
const almendra = Almendra({ subsets: ["latin"], variable: "--font-almendra" });
export const anton = { className: "", variable: "--font-anton" }; // 🧑‍🎤 Statement
export const bebasNeue = { className: "", variable: "--font-bebasneue" }; const oswald = Oswald({ subsets: ["latin"], variable: "--font-oswald" });
export const oswald = { className: "", variable: "--font-oswald" }; const bebasneue = Bebas_Neue({
export const bangers = { className: "", variable: "--font-bangers" }; subsets: ["latin"],
export const ultra = { className: "", variable: "--font-ultra" }; variable: "--font-bebasneue",
export const abrilFatface = { className: "", variable: "--font-abrilfatface" }; });
export const fjallaOne = { className: "", variable: "--font-fjallaone" }; const anton = Anton({
export const fredokaOne = { className: "", variable: "--font-fredokaone" }; subsets: ["latin"],
export const luckiestGuy = { className: "", variable: "--font-luckiestguy" }; weight: "400",
export const fugazOne = { className: "", variable: "--font-fugazone" }; variable: "--font-anton",
export const shrikhand = { className: "", variable: "--font-shrikhand" }; });
export const chango = { className: "", variable: "--font-chango" }; const ultra = Ultra({ subsets: ["latin"], variable: "--font-ultra" });
export const gravitasOne = { className: "", variable: "--font-gravitasone" }; const stintultracondensed = Stint_Ultra_Condensed({
export const coiny = { className: "", variable: "--font-coiny" }; subsets: ["latin"],
export const quicksand = { className: "", variable: "--font-quicksand" }; variable: "--font-stint",
});
const playfair = Playfair_Display({
subsets: ["latin"],
variable: "--font-playfair",
});
const abril = Abril_Fatface({
subsets: ["latin"],
weight: "400",
variable: "--font-abril",
});
const permanentmarker = Permanent_Marker({
subsets: ["latin"],
weight: "400",
variable: "--font-permanentmarker",
});
const alfaslab = Alfa_Slab_One({
subsets: ["latin"],
weight: "400",
variable: "--font-alfaslab",
});
const blackops = Black_Ops_One({
subsets: ["latin"],
weight: "400",
variable: "--font-blackops",
});
const germania = Germania_One({
subsets: ["latin"],
weight: "400",
variable: "--font-germania",
});
const holtwood = Holtwood_One_SC({
subsets: ["latin"],
weight: "400",
variable: "--font-holtwood",
});
export const orbitron = { className: "", variable: "--font-orbitron" }; // 🚀 Futuristic
export const zenDots = { className: "", variable: "--font-zendots" }; const exo = Exo({ subsets: ["latin"], variable: "--font-exo" });
export const audiowide = { className: "", variable: "--font-audiowide" }; const orbitron = Orbitron({
export const exo2 = { className: "", variable: "--font-exo2" }; subsets: ["latin"],
export const rajdhani = { className: "", variable: "--font-rajdhani" }; weight: "400",
export const syncopate = { className: "", variable: "--font-syncopate" }; variable: "--font-orbitron",
export const pressStart2p = { className: "", variable: "--font-pressstart2p" }; });
export const shareTechMono = { const audiowide = Audiowide({
className: "", subsets: ["latin"],
variable: "--font-sharetechmono", weight: "400",
}; variable: "--font-audiowide",
});
const rajdhani = Rajdhani({ subsets: ["latin"], variable: "--font-rajdhani" });
const spacemono = Space_Mono({
subsets: ["latin"],
variable: "--font-spacemono",
});
const questrial = Questrial({
subsets: ["latin"],
variable: "--font-questrial",
});
const syncopate = Syncopate({
subsets: ["latin"],
variable: "--font-syncopate",
});
const unicaone = Unica_One({ subsets: ["latin"], variable: "--font-unicaone" });
const italiana = Italiana({ subsets: ["latin"], variable: "--font-italiana" });
const staatliches = Staatliches({
subsets: ["latin"],
weight: "400",
variable: "--font-staatliches",
});
export const playfairDisplay = { // 🧢 Aesthetic
className: "", const pressstart2p = Press_Start_2P({
variable: "--font-playfairdisplay", subsets: ["latin"],
}; variable: "--font-pressstart2p",
export const cinzel = { className: "", variable: "--font-cinzel" }; });
export const italiana = { className: "", variable: "--font-italiana" }; const righteous = Righteous({
export const youngSerif = { className: "", variable: "--font-youngserif" }; subsets: ["latin"],
export const caprasimo = { className: "", variable: "--font-caprasimo" }; weight: "400",
export const righteous = { className: "", variable: "--font-righteous" }; variable: "--font-righteous",
export const luxuriousRoman = { });
className: "", const metalmania = Metal_Mania({
variable: "--font-luxuriousroman", subsets: ["latin"],
}; weight: "400",
variable: "--font-metalmania",
});
const alegreya = Alegreya({ subsets: ["latin"], variable: "--font-alegreya" });
const spectral = Spectral({ subsets: ["latin"], variable: "--font-spectral" });
const fjallaone = Fjalla_One({
subsets: ["latin"],
variable: "--font-fjallaone",
});
const glassantiqua = Glass_Antiqua({
subsets: ["latin"],
variable: "--font-glassantiqua",
});
const cinzeldecorative = Cinzel_Decorative({
subsets: ["latin"],
variable: "--font-cinzeldecorative",
});
const andika = Andika({
subsets: ["latin"],
weight: "400",
variable: "--font-andika",
});
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 = { export const fonts = {
Inter: inter, Montserrat: createFont(montserrat, "montserrat"),
Roboto: roboto, "Open Sans": createFont(opensans, "opensans"),
Open_Sans: openSans, Roboto: createFont(roboto, "roboto"),
Montserrat: montserrat, Lato: createFont(lato, "lato"),
Raleway: raleway, Raleway: createFont(raleway, "raleway"),
Poppins: poppins, Poppins: createFont(poppins, "poppins"),
Manrope: manrope, "Work Sans": createFont(worksans, "worksans"),
DM_Sans: dmSans, Jost: createFont(jost, "jost"),
Plus_Jakarta_Sans: plusJakartaSans, "Noto Sans": createFont(notosans, "notosans"),
Space_Grotesk: spaceGrotesk, Quicksand: createFont(quicksand, "quicksand"),
Dancing_Script: dancingScript, "Averia Libre": createFont(averialibre, "averialibre"),
Pacifico: pacifico, Philosopher: createFont(philosopher, "philosopher"),
Caveat: caveat,
Indie_Flower: indieFlower, Pacifico: createFont(pacifico, "pacifico"),
Great_Vibes: greatVibes, Caveat: createFont(caveat, "caveat"),
Sacramento: sacramento, Sacramento: createFont(sacramento, "sacramento"),
Alex_Brush: alexBrush, "Dancing Script": createFont(dancingscript, "dancingscript"),
Amatic_SC: amaticSC, "Indie Flower": createFont(indieflower, "indieflower"),
Marck_Script: marckScript, "Amatic SC": createFont(amaticsc, "amatic"),
Protest_Revolution: protestRevolution, "Kaushan Script": createFont(kaushanscript, "kaushan"),
Anton: anton, "Architects Daughter": createFont(architectsdaughter, "architects"),
Bebas_Neue: bebasNeue, Neucha: createFont(neucha, "neucha"),
Oswald: oswald, "Great Vibes": createFont(greatvibes, "greatvibes"),
Bangers: bangers, Satisfy: createFont(satisfy, "satisfy"),
Ultra: ultra, Yellowtail: createFont(yellowtail, "yellowtail"),
Abril_Fatface: abrilFatface, "Gloria Hallelujah": createFont(gloriahallelujah, "gloria"),
Fjalla_One: fjallaOne, Courgette: createFont(courgette, "courgette"),
Fredoka_One: fredokaOne, Almendra: createFont(almendra, "almendra"),
Luckiest_Guy: luckiestGuy,
Fugaz_One: fugazOne, Oswald: createFont(oswald, "oswald"),
Shrikhand: shrikhand, "Bebas Neue": createFont(bebasneue, "bebasneue"),
Chango: chango, Anton: createFont(anton, "anton"),
Gravitas_One: gravitasOne, Ultra: createFont(ultra, "ultra"),
Coiny: coiny, "Stint Ultra Condensed": createFont(stintultracondensed, "stint"),
Quicksand: quicksand, "Playfair Display": createFont(playfair, "playfair"),
Orbitron: orbitron, "Abril Fatface": createFont(abril, "abril"),
Zen_Dots: zenDots, "Permanent Marker": createFont(permanentmarker, "permanentmarker"),
Audiowide: audiowide, "Alfa Slab One": createFont(alfaslab, "alfaslab"),
Exo_2: exo2, "Black Ops One": createFont(blackops, "blackops"),
Rajdhani: rajdhani, "Germania One": createFont(germania, "germania"),
Syncopate: syncopate, "Holtwood One SC": createFont(holtwood, "holtwood"),
Press_Start_2P: pressStart2p,
Share_Tech_Mono: shareTechMono, Exo: createFont(exo, "exo"),
Playfair_Display: playfairDisplay, Orbitron: createFont(orbitron, "orbitron"),
Cinzel: cinzel, Audiowide: createFont(audiowide, "audiowide"),
Italiana: italiana, Rajdhani: createFont(rajdhani, "rajdhani"),
Young_Serif: youngSerif, "Space Mono": createFont(spacemono, "spacemono"),
Caprasimo: caprasimo, Questrial: createFont(questrial, "questrial"),
Righteous: righteous, Syncopate: createFont(syncopate, "syncopate"),
Luxurious_Roman: luxuriousRoman, "Unica One": createFont(unicaone, "unicaone"),
VT323: vt323, Italiana: createFont(italiana, "italiana"),
Neonderthaw: neonderthaw, Staatliches: createFont(staatliches, "staatliches"),
...systemFonts,
...pseudoFonts, "Press Start 2P": createFont(pressstart2p, "pressstart2p"),
Righteous: createFont(righteous, "righteous"),
"Metal Mania": createFont(metalmania, "metalmania"),
Alegreya: createFont(alegreya, "alegreya"),
Spectral: createFont(spectral, "spectral"),
"Fjalla One": createFont(fjallaone, "fjallaone"),
"Glass Antiqua": createFont(glassantiqua, "glassantiqua"),
"Cinzel Decorative": createFont(cinzeldecorative, "cinzeldecorative"),
Andika: createFont(andika, "andika"),
}; };
export const getFontData = (key) => fonts[key] ?? inter; export const getFontData = (key) => fonts[key] ?? fonts["Anton"];

View File

@ -1,14 +1,69 @@
/** /**
* Enthält **nur** die CSSVariablenNamen, die next/font im Browser setzt. * Enthält **nur** die CSSVariablenNamen, die next/font im Browser setzt.
* In fonts.js werden sie erzeugt, hier referenzieren wir sie nur. * In fonts.js oder per @font-face werden sie erzeugt hier referenzieren wir sie.
*/ */
export default { export default {
montserrat: "--font-montserrat", montserrat: "--font-montserrat",
bebasneue: "--font-bebasneue", lato: "--font-lato",
raleway: "--font-raleway",
poppins: "--font-poppins",
opensans: "--font-opensans",
roboto: "--font-roboto",
worksans: "--font-worksans",
notosans: "--font-notosans",
jost: "--font-jost",
quicksand: "--font-quicksand",
averialibre: "--font-averialibre",
philosopher: "--font-philosopher",
pacifico: "--font-pacifico", pacifico: "--font-pacifico",
sacramento: "--font-sacramento",
caveat: "--font-caveat", caveat: "--font-caveat",
fredokaone: "--font-fredokaone", dancingscript: "--font-dancingscript",
playfair: "--font-playfair", indieflower: "--font-indieflower",
vt323: "--font-vt323", amaticsc: "--font-amatic",
// … alle weiteren Fonts, die du brauchst kaushanscript: "--font-kaushan",
architectsdaughter: "--font-architects",
neucha: "--font-neucha",
greatvibes: "--font-greatvibes",
satisfy: "--font-satisfy",
yellowtail: "--font-yellowtail",
gloriahallelujah: "--font-gloria",
oswald: "--font-oswald",
bebasneue: "--font-bebasneue",
anton: "--font-anton",
ultra: "--font-ultra",
stintultracondensed: "--font-stint",
playfairdisplay: "--font-playfair",
abrilfatface: "--font-abril",
permanentmarker: "--font-permanentmarker",
alfaslabone: "--font-alfaslab",
blackopsone: "--font-blackops",
germaniaone: "--font-germania",
holtwoodonesc: "--font-holtwood",
courgette: "--font-courgette",
exo: "--font-exo",
orbitron: "--font-orbitron",
audiowide: "--font-audiowide",
rajdhani: "--font-rajdhani",
spacemono: "--font-spacemono",
questrial: "--font-questrial",
syncopate: "--font-syncopate",
unicaone: "--font-unicaone",
italiana: "--font-italiana",
staatliches: "--font-staatliches",
pressstart2p: "--font-pressstart2p",
righteous: "--font-righteous",
metalmania: "--font-metalmania",
alegreya: "--font-alegreya",
spectral: "--font-spectral",
fjallaone: "--font-fjallaone",
glassantiqua: "--font-glassantiqua",
cinzeldecorative: "--font-cinzeldecorative",
andika: "--font-andika",
almendra: "--font-almendra",
}; };

View File

@ -1,9 +1,15 @@
/** @type {import('next').NextConfig} */ /** @type {import('next').NextConfig} */
const nextConfig = { const nextConfig = {
// Deine sonstigen NextOptionen, z.B.: experimental: {
// reactStrictMode: true, fontLoaders: [
// images: { domains: [...] }, {
// rewrites: async () => [ ... ], loader: "@next/font/google",
options: {
subsets: ["latin"],
},
},
],
},
}; };
module.exports = nextConfig; module.exports = nextConfig;

1193
package-lock.json generated

File diff suppressed because it is too large Load Diff

View File

@ -1,10 +1,10 @@
// pages/_app.jsx // pages/_app.jsx
import "@/styles/tailwind.build.css"; // dein TailwindBuild import "@/styles/tailwind.build.css"; // dein TailwindBuild
import { fonts } from "@/lib/fonts"; import { fonts } from "@/lib/fonts";
// Alle CSSVariablen aus deinen next/fontLoaders, damit die Utilities greifen // CSS-Variablen für alle Fonts aus next/font/google
const allFontVars = Object.values(fonts) const allFontVars = Object.values(fonts)
.filter((f) => f?.variable)
.map((f) => f.variable) .map((f) => f.variable)
.join(" "); .join(" ");

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

@ -1,15 +1,185 @@
@import url("https://fonts.googleapis.com/css2?family=Montserrat:wght@400;500;600&display=swap");
@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;
/* === Lokale Fonts einbinden via @font-face === */
@font-face {
font-family: "Montserrat";
src: url("/fonts/Montserrat-Regular.ttf") format("truetype");
font-weight: 400;
}
@font-face {
font-family: "Bebas Neue";
src: url("/fonts/BebasNeue-Regular.ttf") format("truetype");
font-weight: 400;
}
@font-face {
font-family: "Pacifico";
src: url("/fonts/Pacifico-Regular.ttf") format("truetype");
font-weight: 400;
}
@font-face {
font-family: "Caveat";
src: url("/fonts/Caveat-Regular.ttf") format("truetype");
font-weight: 400;
}
@font-face {
font-family: "Fredoka One";
src: url("/fonts/FredokaOne-Regular.ttf") format("truetype");
font-weight: 400;
}
@font-face {
font-family: "Playfair Display";
src: url("/fonts/PlayfairDisplay-Regular.ttf") format("truetype");
font-weight: 400;
}
@font-face {
font-family: "VT323";
src: url("/fonts/VT323-Regular.ttf") format("truetype");
font-weight: 400;
}
@font-face {
font-family: "Amatic SC";
src: url("/fonts/AmaticSC-Regular.ttf") format("truetype");
font-weight: 400;
}
@font-face {
font-family: "Architects Daughter";
src: url("/fonts/ArchitectsDaughter-Regular.ttf") format("truetype");
font-weight: 400;
}
@font-face {
font-family: "Averia Libre";
src: url("/fonts/AveriaLibre-Regular.ttf") format("truetype");
font-weight: 400;
}
@font-face {
font-family: "Black Ops One";
src: url("/fonts/BlackOpsOne-Regular.ttf") format("truetype");
font-weight: 400;
}
@font-face {
font-family: "Cinzel Decorative";
src: url("/fonts/CinzelDecorative-Regular.ttf") format("truetype");
font-weight: 400;
}
@font-face {
font-family: "Courgette";
src: url("/fonts/Courgette-Regular.ttf") format("truetype");
font-weight: 400;
}
@font-face {
font-family: "Dancing Script";
src: url("/fonts/DancingScript-Regular.ttf") format("truetype");
font-weight: 400;
}
@font-face {
font-family: "Fjalla One";
src: url("/fonts/FjallaOne-Regular.ttf") format("truetype");
font-weight: 400;
}
@font-face {
font-family: "Germania One";
src: url("/fonts/GermaniaOne-Regular.ttf") format("truetype");
font-weight: 400;
}
@font-face {
font-family: "Glass Antiqua";
src: url("/fonts/GlassAntiqua-Regular.ttf") format("truetype");
font-weight: 400;
}
@font-face {
font-family: "Great Vibes";
src: url("/fonts/GreatVibes-Regular.ttf") format("truetype");
font-weight: 400;
}
@font-face {
font-family: "Neucha";
src: url("/fonts/Neucha-Regular.ttf") format("truetype");
font-weight: 400;
}
@font-face {
font-family: "Noto Sans";
src: url("/fonts/NotoSans-Regular.ttf") format("truetype");
font-weight: 400;
}
@font-face {
font-family: "Philosopher";
src: url("/fonts/Philosopher-Regular.ttf") format("truetype");
font-weight: 400;
}
@font-face {
font-family: "Press Start 2P";
src: url("/fonts/PressStart2P-Regular.ttf") format("truetype");
font-weight: 400;
}
@font-face {
font-family: "Righteous";
src: url("/fonts/Righteous-Regular.ttf") format("truetype");
font-weight: 400;
}
@font-face {
font-family: "Satisfy";
src: url("/fonts/Satisfy-Regular.ttf") format("truetype");
font-weight: 400;
}
@font-face {
font-family: "Sacramento";
src: url("/fonts/Sacramento-Regular.ttf") format("truetype");
font-weight: 400;
}
@font-face {
font-family: "Syncopate";
src: url("/fonts/Syncopate-Regular.ttf") format("truetype");
font-weight: 400;
}
@font-face {
font-family: "Orbitron";
src: url("/fonts/Orbitron-Regular.ttf") format("truetype");
font-weight: 400;
}
@font-face {
font-family: "Ultra";
src: url("/fonts/Ultra-Regular.ttf") format("truetype");
font-weight: 400;
}
@font-face {
font-family: "Staatliches";
src: url("/fonts/Staatliches-Regular.ttf") format("truetype");
font-weight: 400;
}
@font-face {
font-family: "Unica One";
src: url("/fonts/UnicaOne-Regular.ttf") format("truetype");
font-weight: 400;
}
@font-face {
font-family: "Italiana";
src: url("/fonts/Italiana-Regular.ttf") format("truetype");
font-weight: 400;
}
@font-face {
font-family: "Alfa Slab One";
src: url("/fonts/AlfaSlabOne-Regular.ttf") format("truetype");
font-weight: 400;
}
@font-face {
font-family: "Andika";
src: url("/fonts/Andika-Regular.ttf") format("truetype");
font-weight: 400;
}
@font-face {
font-family: "Alegreya";
src: url("/fonts/Alegreya-Regular.ttf") format("truetype");
font-weight: 400;
}
@font-face {
font-family: "Spectral";
src: url("/fonts/Spectral-Regular.ttf") format("truetype");
font-weight: 400;
}
/* Utility-Klassen für lokale Fonts */
@layer utilities { @layer utilities {
.font-montserrat { .font-montserrat {
font-family: "Montserrat", sans-serif; font-family: "Montserrat", sans-serif;
@ -32,42 +202,99 @@
.font-vt323 { .font-vt323 {
font-family: "VT323", monospace; font-family: "VT323", monospace;
} }
.font-amaticsc {
/* Pseudo / Unicode Platzhalter */ font-family: "Amatic SC", cursive;
.font-bubble {
font-family: inherit;
} }
.font-glitch { .font-architectsdaughter {
font-family: inherit; font-family: "Architects Daughter", cursive;
} }
.font-wide { .font-averialibre {
font-family: inherit; font-family: "Averia Libre", cursive;
} }
.font-upsidedown { .font-blackopsone {
font-family: inherit; font-family: "Black Ops One", sans-serif;
} }
.font-strike { .font-cinzeldecorative {
text-decoration: line-through; font-family: "Cinzel Decorative", serif;
} }
.font-underline { .font-courgette {
text-decoration: underline; font-family: "Courgette", cursive;
} }
} .font-dancingscript {
font-family: "Dancing Script", cursive;
/* eigene ZusatzUtilities */ }
@layer utilities { .font-fjallaone {
.font-chilanka { font-family: "Fjalla One", sans-serif;
font-family: "Chilanka", cursive; }
.font-germaniaone {
font-family: "Germania One", serif;
}
.font-glassantiqua {
font-family: "Glass Antiqua", cursive;
}
.font-greatvibes {
font-family: "Great Vibes", cursive;
}
.font-neucha {
font-family: "Neucha", cursive;
}
.font-notosans {
font-family: "Noto Sans", sans-serif;
}
.font-philosopher {
font-family: "Philosopher", sans-serif;
}
.font-pressstart2p {
font-family: "Press Start 2P", monospace;
}
.font-righteous {
font-family: "Righteous", cursive;
}
.font-satisfy {
font-family: "Satisfy", cursive;
}
.font-sacramento {
font-family: "Sacramento", cursive;
}
.font-syncopate {
font-family: "Syncopate", sans-serif;
}
.font-orbitron {
font-family: "Orbitron", sans-serif;
}
.font-ultra {
font-family: "Ultra", serif;
}
.font-staatliches {
font-family: "Staatliches", sans-serif;
}
.font-unicaone {
font-family: "Unica One", sans-serif;
}
.font-italiana {
font-family: "Italiana", serif;
}
.font-alfaslabone {
font-family: "Alfa Slab One", serif;
}
.font-andika {
font-family: "Andika", sans-serif;
}
.font-alegreya {
font-family: "Alegreya", serif;
}
.font-spectral {
font-family: "Spectral", serif;
} }
} }
/* Komponenten und sonstige Styles */
@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 */
body { body {
background: #111; background: #111;
color: #fff; color: #fff;

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

View File

@ -1,29 +1,57 @@
// 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: {
montserrat: ["'Montserrat'", "sans-serif"],
bebasneue: ["'Bebas Neue'", "cursive"],
pacifico: ["'Pacifico'", "cursive"],
caveat: ["'Caveat'", "cursive"],
fredokaone: ["'Fredoka One'", "cursive"],
playfair: ["'Playfair Display'", "serif"],
vt323: ["'VT323'", "monospace"],
amaticsc: ["'Amatic SC'", "cursive"],
architectsdaughter: ["'Architects Daughter'", "cursive"],
averialibre: ["'Averia Libre'", "cursive"],
blackopsone: ["'Black Ops One'", "sans-serif"],
cinzeldecorative: ["'Cinzel Decorative'", "serif"],
courgette: ["'Courgette'", "cursive"],
dancingscript: ["'Dancing Script'", "cursive"],
fjallaone: ["'Fjalla One'", "sans-serif"],
germaniaone: ["'Germania One'", "serif"],
glassantiqua: ["'Glass Antiqua'", "cursive"],
greatvibes: ["'Great Vibes'", "cursive"],
neucha: ["'Neucha'", "cursive"],
notosans: ["'Noto Sans'", "sans-serif"],
philosopher: ["'Philosopher'", "sans-serif"],
pressstart2p: ["'Press Start 2P'", "monospace"],
righteous: ["'Righteous'", "cursive"],
satisfy: ["'Satisfy'", "cursive"],
sacramento: ["'Sacramento'", "cursive"],
syncopate: ["'Syncopate'", "sans-serif"],
orbitron: ["'Orbitron'", "sans-serif"],
ultra: ["'Ultra'", "serif"],
staatliches: ["'Staatliches'", "sans-serif"],
unicaone: ["'Unica One'", "sans-serif"],
italiana: ["'Italiana'", "serif"],
alfaslabone: ["'Alfa Slab One'", "serif"],
andika: ["'Andika'", "sans-serif"],
alegreya: ["'Alegreya'", "serif"],
spectral: ["'Spectral'", "serif"],
},
},
},
plugins: [], plugins: [],
// <<< Hier kommt die Safelist >>>
safelist: [ safelist: [
{ {
pattern: /^font-/, pattern: /^font-/,
variants: ["sm", "md", "lg", "xl"], // optional, falls responsive Klassen gebraucht werden variants: ["sm", "md", "lg", "xl"],
}, },
], ],
}; };

View File

@ -1,4 +1,4 @@
import tailwindFonts from "./lib/tailwind-font-map.js"; // ← **ASCIIMinus!** import tailwindFonts from "./lib/tailwind-font-map.js"; // ← **ASCIIMinus wichtig!**
/** @type {import('tailwindcss').Config} */ /** @type {import('tailwindcss').Config} */
export default { export default {
@ -10,13 +10,16 @@ export default {
], ],
theme: { theme: {
extend: { extend: {
fontFamily: Object.fromEntries( fontFamily: {
Object.entries(tailwindFonts).map(([k, cssVar]) => [ // Dynamische Zuordnung: z.B. roboto: ['var(--font-roboto)']
k, ...Object.fromEntries(
Object.entries(tailwindFonts).map(([key, cssVar]) => [
key,
[`var(${cssVar})`], [`var(${cssVar})`],
]) ])
), ),
}, },
}, },
},
plugins: [], plugins: [],
}; };