Compare commits

...

11 Commits

Author SHA1 Message Date
Andreas Knuth bcc6e8652b port 3010 2025-08-18 15:24:43 -05:00
Andreas Knuth 77fc0ab119 node 22 2025-08-18 14:58:41 -05:00
Andreas Knuth 5fbd696ad0 few changes 2025-08-18 14:50:38 -05:00
Andreas Knuth 447af46fa0 posthog 2025-08-17 14:30:52 -05:00
Timo Knuth 1179b406b8 Posthog integration 2025-08-11 08:57:04 +02:00
Andreas Knuth 878dbc63f7 remove special chars & .next ignore 2025-08-09 12:31:08 -05:00
Andreas Knuth 97057765b4 remove .next directory 2025-08-09 12:30:26 -05:00
Timo Knuth 519b282246 verbesserungen 2025-08-06 13:08:45 +02:00
Timo Knuth feb3f96984 Sollte richtig sein aber zu viele fonts 2025-08-06 11:17:40 +02:00
Timo Knuth da306a8f0f neue methode fonts zu laden 2025-08-05 17:03:53 +02:00
Timo Knuth 69a825e613 neue methode fonts zu laden 2025-08-05 16:39:27 +02:00
105 changed files with 4295 additions and 9482 deletions

2
.env.local Normal file
View File

@ -0,0 +1,2 @@
NEXT_PUBLIC_POSTHOG_KEY=phc_xxx
NEXT_PUBLIC_POSTHOG_HOST=https://us.i.posthog.com

1
.gitignore vendored
View File

@ -1 +1,2 @@
node_modules
.next

View File

@ -1,32 +0,0 @@
{
"polyfillFiles": [
"static/chunks/polyfills.js"
],
"devFiles": [
"static/chunks/react-refresh.js"
],
"ampDevFiles": [],
"lowPriorityFiles": [
"static/development/_buildManifest.js",
"static/development/_ssgManifest.js"
],
"rootMainFiles": [],
"pages": {
"/": [
"static/chunks/webpack.js",
"static/chunks/main.js",
"static/chunks/pages/index.js"
],
"/_app": [
"static/chunks/webpack.js",
"static/chunks/main.js",
"static/chunks/pages/_app.js"
],
"/_error": [
"static/chunks/webpack.js",
"static/chunks/main.js",
"static/chunks/pages/_error.js"
]
},
"ampFirstPages": []
}

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.

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.

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.

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.

Binary file not shown.

Binary file not shown.

Binary file not shown.

View File

@ -1 +0,0 @@
{"type": "commonjs"}

View File

@ -1 +0,0 @@
{}

File diff suppressed because one or more lines are too long

View File

@ -1 +0,0 @@
self.__INTERCEPTION_ROUTE_REWRITE_MANIFEST="[]"

View File

@ -1,34 +0,0 @@
self.__BUILD_MANIFEST = {
"polyfillFiles": [
"static/chunks/polyfills.js"
],
"devFiles": [
"static/chunks/react-refresh.js"
],
"ampDevFiles": [],
"lowPriorityFiles": [],
"rootMainFiles": [],
"pages": {
"/": [
"static/chunks/webpack.js",
"static/chunks/main.js",
"static/chunks/pages/index.js"
],
"/_app": [
"static/chunks/webpack.js",
"static/chunks/main.js",
"static/chunks/pages/_app.js"
],
"/_error": [
"static/chunks/webpack.js",
"static/chunks/main.js",
"static/chunks/pages/_error.js"
]
},
"ampFirstPages": []
};
self.__BUILD_MANIFEST.lowPriorityFiles = [
"/static/" + process.env.__NEXT_BUILD_ID + "/_buildManifest.js",
,"/static/" + process.env.__NEXT_BUILD_ID + "/_ssgManifest.js",
];

View File

@ -1,6 +0,0 @@
{
"version": 3,
"middleware": {},
"functions": {},
"sortedMiddleware": []
}

View File

@ -1 +0,0 @@
self.__REACT_LOADABLE_MANIFEST="{}"

View File

@ -1 +0,0 @@
self.__NEXT_FONT_MANIFEST="{\"pages\":{},\"app\":{},\"appUsingSizeAdjust\":false,\"pagesUsingSizeAdjust\":false}"

View File

@ -1 +0,0 @@
{"pages":{},"app":{},"appUsingSizeAdjust":false,"pagesUsingSizeAdjust":false}

View File

@ -1,6 +0,0 @@
{
"/_document": "pages/_document.js",
"/_app": "pages/_app.js",
"/_error": "pages/_error.js",
"/": "pages/index.js"
}

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@ -1,35 +0,0 @@
"use strict";
/*
* ATTENTION: An "eval-source-map" devtool has been used.
* This devtool is neither made for production nor for readable output files.
* It uses "eval()" calls to create a separate source file with attached SourceMaps in the browser devtools.
* If you are trying to read the output file, select a different devtool (https://webpack.js.org/configuration/devtool/)
* or disable the default devtool with "devtool: false".
* If you are looking for production-ready output files, see mode: "production" (https://webpack.js.org/configuration/mode/).
*/
exports.id = "vendor-chunks/@swc";
exports.ids = ["vendor-chunks/@swc"];
exports.modules = {
/***/ "./node_modules/@swc/helpers/cjs/_interop_require_default.cjs":
/*!********************************************************************!*\
!*** ./node_modules/@swc/helpers/cjs/_interop_require_default.cjs ***!
\********************************************************************/
/***/ ((__unused_webpack_module, exports) => {
eval("\n\nexports._ = exports._interop_require_default = _interop_require_default;\nfunction _interop_require_default(obj) {\n return obj && obj.__esModule ? obj : { default: obj };\n}\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiLi9ub2RlX21vZHVsZXMvQHN3Yy9oZWxwZXJzL2Nqcy9faW50ZXJvcF9yZXF1aXJlX2RlZmF1bHQuY2pzIiwibWFwcGluZ3MiOiJBQUFhOztBQUViLFNBQVMsR0FBRyxnQ0FBZ0M7QUFDNUM7QUFDQSwyQ0FBMkM7QUFDM0MiLCJzb3VyY2VzIjpbIndlYnBhY2s6Ly9mYW5jeXRleHQtZ2VuZXJhdG9yLy4vbm9kZV9tb2R1bGVzL0Bzd2MvaGVscGVycy9janMvX2ludGVyb3BfcmVxdWlyZV9kZWZhdWx0LmNqcz8zYmQ2Il0sInNvdXJjZXNDb250ZW50IjpbIlwidXNlIHN0cmljdFwiO1xuXG5leHBvcnRzLl8gPSBleHBvcnRzLl9pbnRlcm9wX3JlcXVpcmVfZGVmYXVsdCA9IF9pbnRlcm9wX3JlcXVpcmVfZGVmYXVsdDtcbmZ1bmN0aW9uIF9pbnRlcm9wX3JlcXVpcmVfZGVmYXVsdChvYmopIHtcbiAgICByZXR1cm4gb2JqICYmIG9iai5fX2VzTW9kdWxlID8gb2JqIDogeyBkZWZhdWx0OiBvYmogfTtcbn1cbiJdLCJuYW1lcyI6W10sInNvdXJjZVJvb3QiOiIifQ==\n//# sourceURL=webpack-internal:///./node_modules/@swc/helpers/cjs/_interop_require_default.cjs\n");
/***/ }),
/***/ "./node_modules/@swc/helpers/cjs/_interop_require_wildcard.cjs":
/*!*********************************************************************!*\
!*** ./node_modules/@swc/helpers/cjs/_interop_require_wildcard.cjs ***!
\*********************************************************************/
/***/ ((__unused_webpack_module, exports) => {
eval("\n\nfunction _getRequireWildcardCache(nodeInterop) {\n if (typeof WeakMap !== \"function\") return null;\n\n var cacheBabelInterop = new WeakMap();\n var cacheNodeInterop = new WeakMap();\n\n return (_getRequireWildcardCache = function(nodeInterop) {\n return nodeInterop ? cacheNodeInterop : cacheBabelInterop;\n })(nodeInterop);\n}\nexports._ = exports._interop_require_wildcard = _interop_require_wildcard;\nfunction _interop_require_wildcard(obj, nodeInterop) {\n if (!nodeInterop && obj && obj.__esModule) return obj;\n if (obj === null || typeof obj !== \"object\" && typeof obj !== \"function\") return { default: obj };\n\n var cache = _getRequireWildcardCache(nodeInterop);\n\n if (cache && cache.has(obj)) return cache.get(obj);\n\n var newObj = { __proto__: null };\n var hasPropertyDescriptor = Object.defineProperty && Object.getOwnPropertyDescriptor;\n\n for (var key in obj) {\n if (key !== \"default\" && Object.prototype.hasOwnProperty.call(obj, key)) {\n var desc = hasPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : null;\n if (desc && (desc.get || desc.set)) Object.defineProperty(newObj, key, desc);\n else newObj[key] = obj[key];\n }\n }\n\n newObj.default = obj;\n\n if (cache) cache.set(obj, newObj);\n\n return newObj;\n}\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiLi9ub2RlX21vZHVsZXMvQHN3Yy9oZWxwZXJzL2Nqcy9faW50ZXJvcF9yZXF1aXJlX3dpbGRjYXJkLmNqcyIsIm1hcHBpbmdzIjoiQUFBYTs7QUFFYjtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBLEtBQUs7QUFDTDtBQUNBLFNBQVMsR0FBRyxpQ0FBaUM7QUFDN0M7QUFDQTtBQUNBLHVGQUF1Rjs7QUFFdkY7O0FBRUE7O0FBRUEsbUJBQW1CO0FBQ25COztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBOztBQUVBOztBQUVBO0FBQ0EiLCJzb3VyY2VzIjpbIndlYnBhY2s6Ly9mYW5jeXRleHQtZ2VuZXJhdG9yLy4vbm9kZV9tb2R1bGVzL0Bzd2MvaGVscGVycy9janMvX2ludGVyb3BfcmVxdWlyZV93aWxkY2FyZC5janM/Nzc5NyJdLCJzb3VyY2VzQ29udGVudCI6WyJcInVzZSBzdHJpY3RcIjtcblxuZnVuY3Rpb24gX2dldFJlcXVpcmVXaWxkY2FyZENhY2hlKG5vZGVJbnRlcm9wKSB7XG4gICAgaWYgKHR5cGVvZiBXZWFrTWFwICE9PSBcImZ1bmN0aW9uXCIpIHJldHVybiBudWxsO1xuXG4gICAgdmFyIGNhY2hlQmFiZWxJbnRlcm9wID0gbmV3IFdlYWtNYXAoKTtcbiAgICB2YXIgY2FjaGVOb2RlSW50ZXJvcCA9IG5ldyBXZWFrTWFwKCk7XG5cbiAgICByZXR1cm4gKF9nZXRSZXF1aXJlV2lsZGNhcmRDYWNoZSA9IGZ1bmN0aW9uKG5vZGVJbnRlcm9wKSB7XG4gICAgICAgIHJldHVybiBub2RlSW50ZXJvcCA/IGNhY2hlTm9kZUludGVyb3AgOiBjYWNoZUJhYmVsSW50ZXJvcDtcbiAgICB9KShub2RlSW50ZXJvcCk7XG59XG5leHBvcnRzLl8gPSBleHBvcnRzLl9pbnRlcm9wX3JlcXVpcmVfd2lsZGNhcmQgPSBfaW50ZXJvcF9yZXF1aXJlX3dpbGRjYXJkO1xuZnVuY3Rpb24gX2ludGVyb3BfcmVxdWlyZV93aWxkY2FyZChvYmosIG5vZGVJbnRlcm9wKSB7XG4gICAgaWYgKCFub2RlSW50ZXJvcCAmJiBvYmogJiYgb2JqLl9fZXNNb2R1bGUpIHJldHVybiBvYmo7XG4gICAgaWYgKG9iaiA9PT0gbnVsbCB8fCB0eXBlb2Ygb2JqICE9PSBcIm9iamVjdFwiICYmIHR5cGVvZiBvYmogIT09IFwiZnVuY3Rpb25cIikgcmV0dXJuIHsgZGVmYXVsdDogb2JqIH07XG5cbiAgICB2YXIgY2FjaGUgPSBfZ2V0UmVxdWlyZVdpbGRjYXJkQ2FjaGUobm9kZUludGVyb3ApO1xuXG4gICAgaWYgKGNhY2hlICYmIGNhY2hlLmhhcyhvYmopKSByZXR1cm4gY2FjaGUuZ2V0KG9iaik7XG5cbiAgICB2YXIgbmV3T2JqID0geyBfX3Byb3RvX186IG51bGwgfTtcbiAgICB2YXIgaGFzUHJvcGVydHlEZXNjcmlwdG9yID0gT2JqZWN0LmRlZmluZVByb3BlcnR5ICYmIE9iamVjdC5nZXRPd25Qcm9wZXJ0eURlc2NyaXB0b3I7XG5cbiAgICBmb3IgKHZhciBrZXkgaW4gb2JqKSB7XG4gICAgICAgIGlmIChrZXkgIT09IFwiZGVmYXVsdFwiICYmIE9iamVjdC5wcm90b3R5cGUuaGFzT3duUHJvcGVydHkuY2FsbChvYmosIGtleSkpIHtcbiAgICAgICAgICAgIHZhciBkZXNjID0gaGFzUHJvcGVydHlEZXNjcmlwdG9yID8gT2JqZWN0LmdldE93blByb3BlcnR5RGVzY3JpcHRvcihvYmosIGtleSkgOiBudWxsO1xuICAgICAgICAgICAgaWYgKGRlc2MgJiYgKGRlc2MuZ2V0IHx8IGRlc2Muc2V0KSkgT2JqZWN0LmRlZmluZVByb3BlcnR5KG5ld09iaiwga2V5LCBkZXNjKTtcbiAgICAgICAgICAgIGVsc2UgbmV3T2JqW2tleV0gPSBvYmpba2V5XTtcbiAgICAgICAgfVxuICAgIH1cblxuICAgIG5ld09iai5kZWZhdWx0ID0gb2JqO1xuXG4gICAgaWYgKGNhY2hlKSBjYWNoZS5zZXQob2JqLCBuZXdPYmopO1xuXG4gICAgcmV0dXJuIG5ld09iajtcbn1cbiJdLCJuYW1lcyI6W10sInNvdXJjZVJvb3QiOiIifQ==\n//# sourceURL=webpack-internal:///./node_modules/@swc/helpers/cjs/_interop_require_wildcard.cjs\n");
/***/ })
};
;

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@ -1,237 +0,0 @@
/*
* ATTENTION: An "eval-source-map" devtool has been used.
* This devtool is neither made for production nor for readable output files.
* It uses "eval()" calls to create a separate source file with attached SourceMaps in the browser devtools.
* If you are trying to read the output file, select a different devtool (https://webpack.js.org/configuration/devtool/)
* or disable the default devtool with "devtool: false".
* If you are looking for production-ready output files, see mode: "production" (https://webpack.js.org/configuration/mode/).
*/
/******/ (() => { // webpackBootstrap
/******/ "use strict";
/******/ var __webpack_modules__ = ({});
/************************************************************************/
/******/ // The module cache
/******/ var __webpack_module_cache__ = {};
/******/
/******/ // The require function
/******/ function __webpack_require__(moduleId) {
/******/ // Check if module is in cache
/******/ var cachedModule = __webpack_module_cache__[moduleId];
/******/ if (cachedModule !== undefined) {
/******/ return cachedModule.exports;
/******/ }
/******/ // Create a new module (and put it into the cache)
/******/ var module = __webpack_module_cache__[moduleId] = {
/******/ // no module.id needed
/******/ // no module.loaded needed
/******/ exports: {}
/******/ };
/******/
/******/ // Execute the module function
/******/ var threw = true;
/******/ try {
/******/ __webpack_modules__[moduleId](module, module.exports, __webpack_require__);
/******/ threw = false;
/******/ } finally {
/******/ if(threw) delete __webpack_module_cache__[moduleId];
/******/ }
/******/
/******/ // Return the exports of the module
/******/ return module.exports;
/******/ }
/******/
/******/ // expose the modules object (__webpack_modules__)
/******/ __webpack_require__.m = __webpack_modules__;
/******/
/************************************************************************/
/******/ /* webpack/runtime/async module */
/******/ (() => {
/******/ var webpackQueues = typeof Symbol === "function" ? Symbol("webpack queues") : "__webpack_queues__";
/******/ var webpackExports = typeof Symbol === "function" ? Symbol("webpack exports") : "__webpack_exports__";
/******/ var webpackError = typeof Symbol === "function" ? Symbol("webpack error") : "__webpack_error__";
/******/ var resolveQueue = (queue) => {
/******/ if(queue && queue.d < 1) {
/******/ queue.d = 1;
/******/ queue.forEach((fn) => (fn.r--));
/******/ queue.forEach((fn) => (fn.r-- ? fn.r++ : fn()));
/******/ }
/******/ }
/******/ var wrapDeps = (deps) => (deps.map((dep) => {
/******/ if(dep !== null && typeof dep === "object") {
/******/ if(dep[webpackQueues]) return dep;
/******/ if(dep.then) {
/******/ var queue = [];
/******/ queue.d = 0;
/******/ dep.then((r) => {
/******/ obj[webpackExports] = r;
/******/ resolveQueue(queue);
/******/ }, (e) => {
/******/ obj[webpackError] = e;
/******/ resolveQueue(queue);
/******/ });
/******/ var obj = {};
/******/ obj[webpackQueues] = (fn) => (fn(queue));
/******/ return obj;
/******/ }
/******/ }
/******/ var ret = {};
/******/ ret[webpackQueues] = x => {};
/******/ ret[webpackExports] = dep;
/******/ return ret;
/******/ }));
/******/ __webpack_require__.a = (module, body, hasAwait) => {
/******/ var queue;
/******/ hasAwait && ((queue = []).d = -1);
/******/ var depQueues = new Set();
/******/ var exports = module.exports;
/******/ var currentDeps;
/******/ var outerResolve;
/******/ var reject;
/******/ var promise = new Promise((resolve, rej) => {
/******/ reject = rej;
/******/ outerResolve = resolve;
/******/ });
/******/ promise[webpackExports] = exports;
/******/ promise[webpackQueues] = (fn) => (queue && fn(queue), depQueues.forEach(fn), promise["catch"](x => {}));
/******/ module.exports = promise;
/******/ body((deps) => {
/******/ currentDeps = wrapDeps(deps);
/******/ var fn;
/******/ var getResult = () => (currentDeps.map((d) => {
/******/ if(d[webpackError]) throw d[webpackError];
/******/ return d[webpackExports];
/******/ }))
/******/ var promise = new Promise((resolve) => {
/******/ fn = () => (resolve(getResult));
/******/ fn.r = 0;
/******/ var fnQueue = (q) => (q !== queue && !depQueues.has(q) && (depQueues.add(q), q && !q.d && (fn.r++, q.push(fn))));
/******/ currentDeps.map((dep) => (dep[webpackQueues](fnQueue)));
/******/ });
/******/ return fn.r ? promise : getResult();
/******/ }, (err) => ((err ? reject(promise[webpackError] = err) : outerResolve(exports)), resolveQueue(queue)));
/******/ queue && queue.d < 0 && (queue.d = 0);
/******/ };
/******/ })();
/******/
/******/ /* webpack/runtime/compat get default export */
/******/ (() => {
/******/ // getDefaultExport function for compatibility with non-harmony modules
/******/ __webpack_require__.n = (module) => {
/******/ var getter = module && module.__esModule ?
/******/ () => (module['default']) :
/******/ () => (module);
/******/ __webpack_require__.d(getter, { a: getter });
/******/ return getter;
/******/ };
/******/ })();
/******/
/******/ /* webpack/runtime/define property getters */
/******/ (() => {
/******/ // define getter functions for harmony exports
/******/ __webpack_require__.d = (exports, definition) => {
/******/ for(var key in definition) {
/******/ if(__webpack_require__.o(definition, key) && !__webpack_require__.o(exports, key)) {
/******/ Object.defineProperty(exports, key, { enumerable: true, get: definition[key] });
/******/ }
/******/ }
/******/ };
/******/ })();
/******/
/******/ /* webpack/runtime/ensure chunk */
/******/ (() => {
/******/ __webpack_require__.f = {};
/******/ // This file contains only the entry chunk.
/******/ // The chunk loading function for additional chunks
/******/ __webpack_require__.e = (chunkId) => {
/******/ return Promise.all(Object.keys(__webpack_require__.f).reduce((promises, key) => {
/******/ __webpack_require__.f[key](chunkId, promises);
/******/ return promises;
/******/ }, []));
/******/ };
/******/ })();
/******/
/******/ /* webpack/runtime/get javascript chunk filename */
/******/ (() => {
/******/ // This function allow to reference async chunks and sibling chunks for the entrypoint
/******/ __webpack_require__.u = (chunkId) => {
/******/ // return url for filenames based on template
/******/ return "" + chunkId + ".js";
/******/ };
/******/ })();
/******/
/******/ /* webpack/runtime/hasOwnProperty shorthand */
/******/ (() => {
/******/ __webpack_require__.o = (obj, prop) => (Object.prototype.hasOwnProperty.call(obj, prop))
/******/ })();
/******/
/******/ /* webpack/runtime/make namespace object */
/******/ (() => {
/******/ // define __esModule on exports
/******/ __webpack_require__.r = (exports) => {
/******/ if(typeof Symbol !== 'undefined' && Symbol.toStringTag) {
/******/ Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
/******/ }
/******/ Object.defineProperty(exports, '__esModule', { value: true });
/******/ };
/******/ })();
/******/
/******/ /* webpack/runtime/startup entrypoint */
/******/ (() => {
/******/ __webpack_require__.X = (result, chunkIds, fn) => {
/******/ // arguments: chunkIds, moduleId are deprecated
/******/ var moduleId = chunkIds;
/******/ if(!fn) chunkIds = result, fn = () => (__webpack_require__(__webpack_require__.s = moduleId));
/******/ chunkIds.map(__webpack_require__.e, __webpack_require__)
/******/ var r = fn();
/******/ return r === undefined ? result : r;
/******/ }
/******/ })();
/******/
/******/ /* webpack/runtime/require chunk loading */
/******/ (() => {
/******/ // no baseURI
/******/
/******/ // object to store loaded chunks
/******/ // "1" means "loaded", otherwise not loaded yet
/******/ var installedChunks = {
/******/ "webpack-runtime": 1
/******/ };
/******/
/******/ // no on chunks loaded
/******/
/******/ var installChunk = (chunk) => {
/******/ var moreModules = chunk.modules, chunkIds = chunk.ids, runtime = chunk.runtime;
/******/ for(var moduleId in moreModules) {
/******/ if(__webpack_require__.o(moreModules, moduleId)) {
/******/ __webpack_require__.m[moduleId] = moreModules[moduleId];
/******/ }
/******/ }
/******/ if(runtime) runtime(__webpack_require__);
/******/ for(var i = 0; i < chunkIds.length; i++)
/******/ installedChunks[chunkIds[i]] = 1;
/******/
/******/ };
/******/
/******/ // require() chunk loading for javascript
/******/ __webpack_require__.f.require = (chunkId, promises) => {
/******/ // "1" is the signal for "already loaded"
/******/ if(!installedChunks[chunkId]) {
/******/ if("webpack-runtime" != chunkId) {
/******/ installChunk(require("./" + __webpack_require__.u(chunkId)));
/******/ } else installedChunks[chunkId] = 1;
/******/ }
/******/ };
/******/
/******/ module.exports = __webpack_require__;
/******/ __webpack_require__.C = installChunk;
/******/
/******/ // no HMR
/******/
/******/ // no HMR manifest
/******/ })();
/******/
/************************************************************************/
/******/
/******/
/******/ })()
;

View File

@ -1,28 +0,0 @@
/*
* ATTENTION: An "eval-source-map" devtool has been used.
* This devtool is neither made for production nor for readable output files.
* It uses "eval()" calls to create a separate source file with attached SourceMaps in the browser devtools.
* If you are trying to read the output file, select a different devtool (https://webpack.js.org/configuration/devtool/)
* or disable the default devtool with "devtool: false".
* If you are looking for production-ready output files, see mode: "production" (https://webpack.js.org/configuration/mode/).
*/
(self["webpackChunk_N_E"] = self["webpackChunk_N_E"] || []).push([["/_error"],{
/***/ "./node_modules/next/dist/build/webpack/loaders/next-client-pages-loader.js?absolutePagePath=%2Fmnt%2Fc%2FUsers%2Fa931627%2FDocuments%2Ffancytextstuff%2Fnode_modules%2Fnext%2Fdist%2Fpages%2F_error.js&page=%2F_error!":
/*!******************************************************************************************************************************************************************************************************************************!*\
!*** ./node_modules/next/dist/build/webpack/loaders/next-client-pages-loader.js?absolutePagePath=%2Fmnt%2Fc%2FUsers%2Fa931627%2FDocuments%2Ffancytextstuff%2Fnode_modules%2Fnext%2Fdist%2Fpages%2F_error.js&page=%2F_error! ***!
\******************************************************************************************************************************************************************************************************************************/
/***/ (function(module, __unused_webpack_exports, __webpack_require__) {
eval(__webpack_require__.ts("\n (window.__NEXT_P = window.__NEXT_P || []).push([\n \"/_error\",\n function () {\n return __webpack_require__(/*! ./node_modules/next/dist/pages/_error.js */ \"./node_modules/next/dist/pages/_error.js\");\n }\n ]);\n if(true) {\n module.hot.dispose(function () {\n window.__NEXT_P.push([\"/_error\"])\n });\n }\n //# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiLi9ub2RlX21vZHVsZXMvbmV4dC9kaXN0L2J1aWxkL3dlYnBhY2svbG9hZGVycy9uZXh0LWNsaWVudC1wYWdlcy1sb2FkZXIuanM/YWJzb2x1dGVQYWdlUGF0aD0lMkZtbnQlMkZjJTJGVXNlcnMlMkZhOTMxNjI3JTJGRG9jdW1lbnRzJTJGZmFuY3l0ZXh0c3R1ZmYlMkZub2RlX21vZHVsZXMlMkZuZXh0JTJGZGlzdCUyRnBhZ2VzJTJGX2Vycm9yLmpzJnBhZ2U9JTJGX2Vycm9yISIsIm1hcHBpbmdzIjoiO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsZUFBZSxtQkFBTyxDQUFDLDBGQUEwQztBQUNqRTtBQUNBO0FBQ0EsT0FBTyxJQUFVO0FBQ2pCLE1BQU0sVUFBVTtBQUNoQjtBQUNBLE9BQU87QUFDUDtBQUNBIiwic291cmNlcyI6WyJ3ZWJwYWNrOi8vX05fRS8/ZGU5MSJdLCJzb3VyY2VzQ29udGVudCI6WyJcbiAgICAod2luZG93Ll9fTkVYVF9QID0gd2luZG93Ll9fTkVYVF9QIHx8IFtdKS5wdXNoKFtcbiAgICAgIFwiL19lcnJvclwiLFxuICAgICAgZnVuY3Rpb24gKCkge1xuICAgICAgICByZXR1cm4gcmVxdWlyZShcIi4vbm9kZV9tb2R1bGVzL25leHQvZGlzdC9wYWdlcy9fZXJyb3IuanNcIik7XG4gICAgICB9XG4gICAgXSk7XG4gICAgaWYobW9kdWxlLmhvdCkge1xuICAgICAgbW9kdWxlLmhvdC5kaXNwb3NlKGZ1bmN0aW9uICgpIHtcbiAgICAgICAgd2luZG93Ll9fTkVYVF9QLnB1c2goW1wiL19lcnJvclwiXSlcbiAgICAgIH0pO1xuICAgIH1cbiAgIl0sIm5hbWVzIjpbXSwic291cmNlUm9vdCI6IiJ9\n//# sourceURL=webpack-internal:///./node_modules/next/dist/build/webpack/loaders/next-client-pages-loader.js?absolutePagePath=%2Fmnt%2Fc%2FUsers%2Fa931627%2FDocuments%2Ffancytextstuff%2Fnode_modules%2Fnext%2Fdist%2Fpages%2F_error.js&page=%2F_error!\n"));
/***/ })
},
/******/ function(__webpack_require__) { // webpackRuntimeModules
/******/ var __webpack_exec__ = function(moduleId) { return __webpack_require__(__webpack_require__.s = moduleId); }
/******/ __webpack_require__.O(0, ["main"], function() { return __webpack_exec__("./node_modules/next/dist/build/webpack/loaders/next-client-pages-loader.js?absolutePagePath=%2Fmnt%2Fc%2FUsers%2Fa931627%2FDocuments%2Ffancytextstuff%2Fnode_modules%2Fnext%2Fdist%2Fpages%2F_error.js&page=%2F_error!"); });
/******/ var __webpack_exports__ = __webpack_require__.O();
/******/ _N_E = __webpack_exports__;
/******/ }
]);

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@ -1,28 +0,0 @@
/*
* ATTENTION: An "eval-source-map" devtool has been used.
* This devtool is neither made for production nor for readable output files.
* It uses "eval()" calls to create a separate source file with attached SourceMaps in the browser devtools.
* If you are trying to read the output file, select a different devtool (https://webpack.js.org/configuration/devtool/)
* or disable the default devtool with "devtool: false".
* If you are looking for production-ready output files, see mode: "production" (https://webpack.js.org/configuration/mode/).
*/
(self["webpackChunk_N_E"] = self["webpackChunk_N_E"] || []).push([["pages/_error"],{
/***/ "./node_modules/next/dist/build/webpack/loaders/next-client-pages-loader.js?absolutePagePath=private-next-pages%2F_error&page=%2F_error!":
/*!***********************************************************************************************************************************************!*\
!*** ./node_modules/next/dist/build/webpack/loaders/next-client-pages-loader.js?absolutePagePath=private-next-pages%2F_error&page=%2F_error! ***!
\***********************************************************************************************************************************************/
/***/ (function(module, __unused_webpack_exports, __webpack_require__) {
eval(__webpack_require__.ts("\n (window.__NEXT_P = window.__NEXT_P || []).push([\n \"/_error\",\n function () {\n return __webpack_require__(/*! private-next-pages/_error */ \"./node_modules/next/dist/pages/_error.js\");\n }\n ]);\n if(true) {\n module.hot.dispose(function () {\n window.__NEXT_P.push([\"/_error\"])\n });\n }\n //# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiLi9ub2RlX21vZHVsZXMvbmV4dC9kaXN0L2J1aWxkL3dlYnBhY2svbG9hZGVycy9uZXh0LWNsaWVudC1wYWdlcy1sb2FkZXIuanM/YWJzb2x1dGVQYWdlUGF0aD1wcml2YXRlLW5leHQtcGFnZXMlMkZfZXJyb3ImcGFnZT0lMkZfZXJyb3IhIiwibWFwcGluZ3MiOiI7QUFDQTtBQUNBO0FBQ0E7QUFDQSxlQUFlLG1CQUFPLENBQUMsMkVBQTJCO0FBQ2xEO0FBQ0E7QUFDQSxPQUFPLElBQVU7QUFDakIsTUFBTSxVQUFVO0FBQ2hCO0FBQ0EsT0FBTztBQUNQO0FBQ0EiLCJzb3VyY2VzIjpbIndlYnBhY2s6Ly9fTl9FLz84MDdiIl0sInNvdXJjZXNDb250ZW50IjpbIlxuICAgICh3aW5kb3cuX19ORVhUX1AgPSB3aW5kb3cuX19ORVhUX1AgfHwgW10pLnB1c2goW1xuICAgICAgXCIvX2Vycm9yXCIsXG4gICAgICBmdW5jdGlvbiAoKSB7XG4gICAgICAgIHJldHVybiByZXF1aXJlKFwicHJpdmF0ZS1uZXh0LXBhZ2VzL19lcnJvclwiKTtcbiAgICAgIH1cbiAgICBdKTtcbiAgICBpZihtb2R1bGUuaG90KSB7XG4gICAgICBtb2R1bGUuaG90LmRpc3Bvc2UoZnVuY3Rpb24gKCkge1xuICAgICAgICB3aW5kb3cuX19ORVhUX1AucHVzaChbXCIvX2Vycm9yXCJdKVxuICAgICAgfSk7XG4gICAgfVxuICAiXSwibmFtZXMiOltdLCJzb3VyY2VSb290IjoiIn0=\n//# sourceURL=webpack-internal:///./node_modules/next/dist/build/webpack/loaders/next-client-pages-loader.js?absolutePagePath=private-next-pages%2F_error&page=%2F_error!\n"));
/***/ })
},
/******/ function(__webpack_require__) { // webpackRuntimeModules
/******/ var __webpack_exec__ = function(moduleId) { return __webpack_require__(__webpack_require__.s = moduleId); }
/******/ __webpack_require__.O(0, ["pages/_app","main"], function() { return __webpack_exec__("./node_modules/next/dist/build/webpack/loaders/next-client-pages-loader.js?absolutePagePath=private-next-pages%2F_error&page=%2F_error!"); });
/******/ var __webpack_exports__ = __webpack_require__.O();
/******/ _N_E = __webpack_exports__;
/******/ }
]);

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because it is too large Load Diff

View File

@ -1 +0,0 @@
self.__BUILD_MANIFEST = {__rewrites:{afterFiles:[],beforeFiles:[],fallback:[]},"/":["static\u002Fchunks\u002Fpages\u002Findex.js"],"/_error":["static\u002Fchunks\u002Fpages\u002F_error.js"],sortedPages:["\u002F","\u002F_app","\u002F_error"]};self.__BUILD_MANIFEST_CB && self.__BUILD_MANIFEST_CB()

View File

@ -1 +0,0 @@
self.__SSG_MANIFEST=new Set;self.__SSG_MANIFEST_CB&&self.__SSG_MANIFEST_CB()

View File

@ -1 +0,0 @@
{"c":["webpack"],"r":[],"m":[]}

View File

@ -1 +0,0 @@
{"c":[],"r":[],"m":[]}

View File

@ -1,18 +0,0 @@
"use strict";
/*
* ATTENTION: An "eval-source-map" devtool has been used.
* This devtool is neither made for production nor for readable output files.
* It uses "eval()" calls to create a separate source file with attached SourceMaps in the browser devtools.
* If you are trying to read the output file, select a different devtool (https://webpack.js.org/configuration/devtool/)
* or disable the default devtool with "devtool: false".
* If you are looking for production-ready output files, see mode: "production" (https://webpack.js.org/configuration/mode/).
*/
self["webpackHotUpdate_N_E"]("webpack",{},
/******/ function(__webpack_require__) { // webpackRuntimeModules
/******/ /* webpack/runtime/getFullHash */
/******/ !function() {
/******/ __webpack_require__.h = function() { return "d1363c6e2dfbe09d"; }
/******/ }();
/******/
/******/ }
);

File diff suppressed because one or more lines are too long

View File

@ -1,5 +1,5 @@
# 1) Base
FROM node:18-alpine AS base
FROM node:22-alpine AS base
WORKDIR /app
ENV NEXT_TELEMETRY_DISABLED=1
@ -22,7 +22,7 @@ RUN npm run build
RUN npm prune --omit=dev
# 4) Runner
FROM node:18-alpine AS runner
FROM node:22-alpine AS runner
WORKDIR /app
ENV NODE_ENV=production \
NEXT_TELEMETRY_DISABLED=1 \

100
build-fontfaces.sh Normal file
View File

@ -0,0 +1,100 @@
#!/usr/bin/env bash
set -euo pipefail
UA="Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/123 Safari/537.36"
DISPLAY="swap"
WEIGHT="400"
# Paare: Google-Fontname (URL-Form) | CSS-Fontname (CamelCase wie in deinen Utilities)
readarray -t FONTS <<'EOF'
Abril+Fatface|AbrilFatface
Alegreya|Alegreya
Alfa+Slab+One|AlfaSlabOne
Almendra|Almendra
Amatic+SC|AmaticSc
Andika|Andika
Architects+Daughter|ArchitectsDaughter
Audiowide|Audiowide
Averia+Libre|AveriaLibre
Bebas+Neue|BebasNeue
Black+Ops+One|BlackOpsOne
Caveat|Caveat
Cinzel+Decorative|CinzelDecorative
Courgette|Courgette
Dancing+Script|DancingScript
Exo|Exo
Fjalla+One|FjallaOne
Germania+One|GermaniaOne
Glass+Antiqua|GlassAntiqua
Gloria+Hallelujah|GloriaHallelujah
Great+Vibes|GreatVibes
Holtwood+One+SC|HoltwoodOneSc
Indie+Flower|IndieFlower
Italiana|Italiana
Jost|Jost
Kaushan+Script|KaushanScript
Lato|Lato
Metal+Mania|MetalMania
Montserrat|Montserrat
Neucha|Neucha
Noto+Sans|NotoSans
Open+Sans|OpenSans
Orbitron|Orbitron
Oswald|Oswald
Pacifico|Pacifico
Permanent+Marker|PermanentMarker
Philosopher|Philosopher
Playfair+Display|PlayfairDisplay
Poppins|Poppins
Press+Start+2P|PressStart2P
Questrial|Questrial
Quicksand|Quicksand
Rajdhani|Rajdhani
Raleway|Raleway
Righteous|Righteous
Roboto|Roboto
Sacramento|Sacramento
Satisfy|Satisfy
Space+Mono|SpaceMono
Spectral|Spectral
Staatliches|Staatliches
Stint+Ultra+Condensed|StintUltraCondensed
Syncopate|Syncopate
Ultra|Ultra
Unica+One|UnicaOne
Work+Sans|WorkSans
Yellowtail|Yellowtail
EOF
for line in "${FONTS[@]}"; do
GF="${line%%|*}"
CSS_FAMILY="${line##*|}"
API_URL="https://fonts.googleapis.com/css2?family=${GF}:wght@${WEIGHT}&display=${DISPLAY}"
CSS="$(curl -s -H "User-Agent: ${UA}" --compressed "$API_URL")"
# Bevorzugt den /* latin */-Block, sonst den ersten @font-face mit font-style: normal
BLOCK="$(awk '/\/\* latin \*\//,/\}/' <<<"$CSS")"
if [[ -z "$BLOCK" ]]; then
BLOCK="$(awk -v RS='}' '/@font-face/ && /font-style:[[:space:]]*normal/ {print $0 RS; exit}' <<<"$CSS")"
fi
SRC="$(grep -o 'https://fonts\.gstatic\.com[^)]*\.woff2' <<<"$BLOCK" | head -n1 || true)"
URANGE="$(sed -n 's/^[[:space:]]*unicode-range:[[:space:]]*\(.*\);/\1/p' <<<"$BLOCK" || true)"
if [[ -z "$SRC" ]]; then
echo "/* WARN: no woff2 for ${GF} */" >&2
continue
fi
cat <<CSSBLOCK
@font-face {
font-family: "${CSS_FAMILY}";
font-style: normal;
font-weight: ${WEIGHT};
font-display: ${DISPLAY};
src: url("${SRC}") format("woff2");
${URANGE:+ unicode-range: ${URANGE};}
}
CSSBLOCK
done

View File

@ -1,3 +1,4 @@
// components/PerformanceOptimizedFontCard.jsx
import React, { useState, useCallback, forwardRef, memo } from "react";
import { Card } from "@/components/ui/card";
import { Button } from "@/components/ui/button";
@ -93,22 +94,10 @@ const PerformanceOptimizedFontCard = forwardRef(({
}
}, [transformedText, fontName, onShare]);
const getFontStyle = useCallback((name) => {
const baseStyle = { wordBreak: "break-word", lineHeight: "1.3", willChange: "auto" };
const fontEntry = fontTransforms[name];
if (!fontEntry) return baseStyle;
const style = { ...baseStyle };
if (fontEntry.fontFamily) style.fontFamily = fontEntry.fontFamily;
if (fontEntry.fontWeight) style.fontWeight = fontEntry.fontWeight;
if (fontEntry.textTransform) style.textTransform = fontEntry.textTransform;
if (fontEntry.letterSpacing) style.letterSpacing = fontEntry.letterSpacing;
if (fontEntry.fontSize) style.fontSize = fontEntry.fontSize;
return style;
}, []);
const previewText = sStr(transformedText?.transformed ?? transformedText) || "Hallo Instagram!";
const fontClass = transformedText?.fontClassName ?? "";
const displayName = fontTransforms[fontName]?.description;
return (
<div ref={ref} className="will-change-transform mb-6">
@ -146,10 +135,10 @@ const PerformanceOptimizedFontCard = forwardRef(({
</Button>
</div>
</div>
{fontTransforms[fontName]?.description && (
{displayName && (
<p className="text-xs text-gray-500 mb-3 flex items-start gap-1 leading-tight">
<Info className="w-3 h-3 mt-0.5 shrink-0" />
{fontTransforms[fontName].description}
{displayName}
</p>
)}
<div
@ -158,7 +147,7 @@ const PerformanceOptimizedFontCard = forwardRef(({
tabIndex={0}
onKeyDown={(e) => (e.key === "Enter" || e.key === " ") && handleCopy()}
aria-label="Click to copy text"
style={{ ...getFontStyle(fontName), pointerEvents: "auto" }}
style={{ 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 ${fontClass}`}
>
{previewText}
@ -186,4 +175,4 @@ const PerformanceOptimizedFontCard = forwardRef(({
});
PerformanceOptimizedFontCard.displayName = "PerformanceOptimizedFontCard";
export default memo(PerformanceOptimizedFontCard);
export default memo(PerformanceOptimizedFontCard);

View File

@ -1,87 +1,50 @@
// components/fontTransforms.jsx
// 1) Unicode-Blöcke
const unicodeBlocks = {
sansSerif: { upperStart: 0x1D5A0, lowerStart: 0x1D5BA },
sansSerifBold: { upperStart: 0x1D5D4, lowerStart: 0x1D5EE },
script: { upperStart: 0x1D49C, lowerStart: 0x1D4B6 },
scriptBold: { upperStart: 0x1D4D0, lowerStart: 0x1D4EA },
fraktur: { upperStart: 0x1D504, lowerStart: 0x1D51E },
frakturBold: { upperStart: 0x1D56C, lowerStart: 0x1D586 },
monospace: { upperStart: 0x1D670, lowerStart: 0x1D68A },
fullwidth: { upperStart: 0xFF21, lowerStart: 0xFF41 }
};
// 2) Unicode-Mapping-Funktion
const mapUnicode = (char, block) => {
const code = char.charCodeAt(0);
if (code >= 65 && code <= 90) return String.fromCodePoint(block.upperStart + (code - 65));
if (code >= 97 && code <= 122) return String.fromCodePoint(block.lowerStart + (code - 97));
return char;
};
const createTransform = (blockKey) => (text) =>
text.split('').map((c) => mapUnicode(c, unicodeBlocks[blockKey])).join('');
// 3) Font-Definitionen
const fontList = [
"abril-fatface", "alegreya", "alfa-slab-one", "almendra", "amatic-sc", "andika",
"architects-daughter", "audiowide", "averia-libre", "bebas-neue", "black-ops-one",
"caveat", "cinzel-decorative", "courgette", "dancing-script", "exo", "fjalla-one",
"germania-one", "glass-antiqua", "gloria-hallelujah", "great-vibes", "holtwood-one-sc",
"indie-flower", "italiana", "jost", "kaushan-script", "lato", "metal-mania", "montserrat",
"neucha", "noto-sans", "open-sans", "orbitron", "oswald", "pacifico", "permanent-marker",
"philosopher", "playfair-display", "poppins", "press-start-2p", "questrial", "quicksand",
"rajdhani", "raleway", "righteous", "roboto", "sacramento", "satisfy", "space-mono",
"spectral", "staatliches", "stint-ultra-condensed", "syncopate", "ultra", "unica-one",
"work-sans", "yellowtail"
export const fontList = [
  "abril-fatface", "alegreya", "alfa-slab-one", "almendra", "amatic-sc", "andika",
  "architects-daughter", "audiowide", "averia-libre", "bebas-neue", "black-ops-one",
  "caveat", "cinzel-decorative", "courgette", "dancing-script", "exo", "fjalla-one",
  "germania-one", "glass-antiqua", "gloria-hallelujah", "great-vibes", "holtwood-one-sc",
  "indie-flower", "italiana", "jost", "kaushan-script", "lato", "metal-mania", "montserrat",
  "neucha", "noto-sans", "open-sans", "orbitron", "oswald", "pacifico", "permanent-marker",
  "philosopher", "playfair-display", "poppins", "press-start-2p", "questrial", "quicksand",
  "rajdhani", "raleway", "righteous", "roboto", "sacramento", "satisfy", "space-mono",
  "spectral", "staatliches", "stint-ultra-condensed", "syncopate", "ultra", "unica-one",
  "work-sans", "yellowtail"
];
// 4) Kategorie-Regeln (vereinfacht)
const getCategory = (name) => {
if (["caveat", "dancing-script", "pacifico", "amatic-sc", "kaushan-script", "courgette", "great-vibes", "satisfy", "sacramento", "neucha", "gloria-hallelujah", "almendra", "indie-flower", "architects-daughter"].includes(name)) return "handwriting";
if (["bebas-neue", "black-ops-one", "holtwood-one-sc", "abril-fatface", "playfair-display", "permanent-marker", "alfa-slab-one", "germania-one", "oswald", "stint-ultra-condensed"].includes(name)) return "statement";
if (["exo", "orbitron", "audiowide", "rajdhani", "space-mono", "questrial", "syncopate", "unica-one", "italiana", "staatliches"].includes(name)) return "futuristic";
if (["press-start-2p", "righteous", "metal-mania", "alegreya", "spectral", "fjalla-one", "glass-antiqua", "cinzel-decorative", "andika"].includes(name)) return "aesthetic";
return "modern";
};
const blockForCategory = {
modern: "sansSerif",
handwriting: "scriptBold",
statement: "fullwidth",
futuristic: "monospace",
aesthetic: "frakturBold"
  if (["caveat", "dancing-script", "pacifico", "amatic-sc", "kaushan-script", "courgette", "great-vibes", "satisfy", "sacramento", "neucha", "gloria-hallelujah", "almendra", "indie-flower", "architects-daughter"].includes(name)) return "handwriting";
  if (["bebas-neue", "black-ops-one", "holtwood-one-sc", "abril-fatface", "playfair-display", "permanent-marker", "alfa-slab-one", "germania-one", "oswald", "stint-ultra-condensed"].includes(name)) return "statement";
  if (["exo", "orbitron", "audiowide", "rajdhani", "space-mono", "questrial", "syncopate", "unica-one", "italiana", "staatliches"].includes(name)) return "futuristic";
  if (["press-start-2p", "righteous", "metal-mania", "alegreya", "spectral", "fjalla-one", "glass-antiqua", "cinzel-decorative", "andika"].includes(name)) return "aesthetic";
  return "modern";
};
export const fontTransforms = Object.fromEntries(
fontList.map((font) => {
const name = font.replace(/-/g, " ").replace(/\b\w/g, (l) => l.toUpperCase());
const category = getCategory(font);
const block = blockForCategory[category];
return [name, {
transform: createTransform(block),
category,
description: `${name} Unicode-Stil automatisch zugewiesen` ,
className: `font-${font}`
}];
})
  fontList.map((font) => {
    const name = font.replace(/-/g, " ").replace(/\b\w/g, (l) => l.toUpperCase());
    const category = getCategory(font);
    return [font, {
      category,
      description: `Eine moderne, saubere Schriftart.`,
      className: `font-${font}`
    }];
  })
);
export const transformText = (text, fontName) => {
const font = fontTransforms[fontName];
if (!font || !text) return { transformed: text, fontClassName: "" };
return {
transformed: font.transform(text),
fontClassName: font.className
};
  const font = fontTransforms[fontName];
  if (!font || !text) return { transformed: text, fontClassName: "" };
  return {
    transformed: text,
    fontClassName: font.className
  };
};
export const getPopularFonts = () => Object.keys(fontTransforms).slice(0, 10);
export const getPopularFonts = () => fontList.slice(0, 10);
export const getFontsByCategory = (category) =>
category === "all"
? Object.keys(fontTransforms)
: Object.keys(fontTransforms).filter(
(f) => fontTransforms[f].category === category
);
  category === "all"
    ? fontList
    : fontList.filter((f) => getCategory(f) === category);

View File

@ -38,7 +38,8 @@ export default function FontCard({
};
return (
<div style={{ pointerEvents: "none" }}>
// Dieses Attribut wurde entfernt, da es alle Klicks blockiert hat.
<div>
<Card className="bg-white/90 backdrop-blur-sm border-0 shadow-xl hover:shadow-2xl transition-all duration-300 overflow-hidden">
<div className="p-6">
<div className="flex items-center justify-between mb-4">
@ -111,4 +112,4 @@ export default function FontCard({
</Card>
</div>
);
}
}

View File

@ -1,8 +1,7 @@
version: "3.8"
services:
fancytext-app:
build: .
ports:
- "3001:3000"
- "3010:3000"
environment:
- NODE_ENV=production

40
dump_unicode_ranges.py Normal file
View File

@ -0,0 +1,40 @@
from fontTools.ttLib import TTFont
from pathlib import Path
import sys, csv
def cps_from_font(p):
f = TTFont(p)
s = set()
for t in f["cmap"].tables:
s.update(t.cmap.keys())
return sorted(c for c in s if c is not None)
def to_ranges(cps):
if not cps:
return ""
out = []
a = b = cps[0]
for x in cps[1:]:
if x == b + 1:
b = x
else:
out.append((a, b))
a = b = x
out.append((a, b))
return ", ".join(
f"U+{a:04X}" if a == b else f"U+{a:04X}-{b:04X}"
for a, b in out
)
def main(argv):
w = csv.writer(sys.stdout)
w.writerow(["file", "unicode-range"])
for fp in argv:
cps = cps_from_font(fp)
w.writerow([Path(fp).name, to_ranges(cps)])
if __name__ == "__main__":
if len(sys.argv) < 2:
print("Usage: python3 dump_unicode_ranges.py <font1.woff2> ...", file=sys.stderr)
sys.exit(1)
main(sys.argv[1:])

120
fetch-font-urls.sh Normal file
View File

@ -0,0 +1,120 @@
#!/usr/bin/env bash
set -euo pipefail
# --- Einstellungen ---
SUBSET="latin" # für DE/EN am kleinsten; bei Bedarf "latin-ext"
WEIGHT="400"
DISPLAY="swap"
# Moderner UA erzwingt woff2 im Google-Fonts CSS
UA="Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/123 Safari/537.36"
# Familienliste (Leerzeichen -> '+')
FAMILIES=(
"Abril+Fatface"
"Alegreya"
"Alfa+Slab+One"
"Almendra"
"Amatic+SC"
"Andika"
"Architects+Daughter"
"Audiowide"
"Averia+Libre"
"Bebas+Neue"
"Black+Ops+One"
"Caveat"
"Cinzel+Decorative"
"Courgette"
"Dancing+Script"
"Exo"
"Fjalla+One"
"Germania+One"
"Glass+Antiqua"
"Gloria+Hallelujah"
"Great+Vibes"
"Holtwood+One+SC"
"Indie+Flower"
"Italiana"
"Jost"
"Kaushan+Script"
"Lato"
"Metal+Mania"
"Montserrat"
"Neucha"
"Noto+Sans"
"Open+Sans"
"Orbitron"
"Oswald"
"Pacifico"
"Permanent+Marker"
"Philosopher"
"Playfair+Display"
"Poppins"
"Press+Start+2P"
"Questrial"
"Quicksand"
"Rajdhani"
"Raleway"
"Righteous"
"Roboto"
"Sacramento"
"Satisfy"
"Space+Mono"
"Spectral"
"Staatliches"
"Stint+Ultra+Condensed"
"Syncopate"
"Ultra"
"Unica+One"
"Work+Sans"
"Yellowtail"
)
# --- Output vorbereiten ---
: > font-src-urls.csv
echo "family,woff2_url" >> font-src-urls.csv
: > fonts.css
echo "Hole woff2-URLs (Subset: $SUBSET, Weight: $WEIGHT) …" >&2
for FAMILY in "${FAMILIES[@]}"; do
API_URL="https://fonts.googleapis.com/css2?family=${FAMILY}:wght@${WEIGHT}&display=${DISPLAY}"
CSS="$(curl -s -H "User-Agent: ${UA}" "${API_URL}")"
# bevorzugt den /* latin */-Block
URL="$(printf "%s\n" "$CSS" \
| awk '/\/\* '"$SUBSET"' \*\//,/\}/' \
| grep -o 'https://fonts.gstatic.com[^)]*\.woff2' \
| head -n1 || true)"
# Fallback: erste woff2-URL überhaupt
if [[ -z "${URL}" ]]; then
URL="$(printf "%s\n" "$CSS" \
| grep -o 'https://fonts.gstatic.com[^)]*\.woff2' \
| head -n1 || true)"
fi
if [[ -z "${URL}" ]]; then
echo "WARN: Keine woff2-URL für ${FAMILY} gefunden" >&2
continue
fi
# CSV-Zeile
echo "${FAMILY},${URL}" >> font-src-urls.csv
# @font-face Snippet
CSS_FAMILY="${FAMILY//+/ }"
cat >> fonts.css <<CSS
@font-face {
font-family: '${CSS_FAMILY}';
font-style: normal;
font-weight: ${WEIGHT};
font-display: ${DISPLAY};
src: url('${URL}') format('woff2');
/* subset: ${SUBSET} (aus Google Fonts CSS v2) */
}
CSS
done
echo "Fertig. Siehe font-src-urls.csv und fonts.css" >&2

58
font-src-urls.csv Normal file
View File

@ -0,0 +1,58 @@
family,woff2_url
Abril+Fatface,https://fonts.gstatic.com/s/abrilfatface/v24/zOL64pLDlL1D99S8g8PtiKchq-dmjQ.woff2
Alegreya,https://fonts.gstatic.com/s/alegreya/v38/4UacrEBBsBhlBjvfkQjt71kZfyBzPgNG9hU4-6qj.woff2
Alfa+Slab+One,https://fonts.gstatic.com/s/alfaslabone/v20/6NUQ8FmMKwSEKjnm5-4v-4Jh2dJhew.woff2
Almendra,https://fonts.gstatic.com/s/almendra/v27/H4ckBXKAlMnTn0CskxY9yL4.woff2
Amatic+SC,https://fonts.gstatic.com/s/amaticsc/v27/TUZyzwprpvBS1izr_vOECuSf.woff2
Andika,https://fonts.gstatic.com/s/andika/v26/mem_Ya6iyW-LwqgwarYQ.woff2
Architects+Daughter,https://fonts.gstatic.com/s/architectsdaughter/v19/KtkxAKiDZI_td1Lkx62xHZHDtgO_Y-bvTYlg4w.woff2
Audiowide,https://fonts.gstatic.com/s/audiowide/v21/l7gdbjpo0cum0ckerWCdlg_O.woff2
Averia+Libre,https://fonts.gstatic.com/s/averialibre/v16/2V0aKIcMGZEnV6xygz7eNjESBanI.woff2
Bebas+Neue,https://fonts.gstatic.com/s/bebasneue/v15/JTUSjIg69CK48gW7PXoo9Wlhyw.woff2
Black+Ops+One,https://fonts.gstatic.com/s/blackopsone/v20/qWcsB6-ypo7xBdr6Xshe96H3aDvbtw.woff2
Caveat,https://fonts.gstatic.com/s/caveat/v22/WnznHAc5bAfYB2QRah7pcpNvOx-pjfJ9eIWpYQ.woff2
Cinzel+Decorative,https://fonts.gstatic.com/s/cinzeldecorative/v18/daaCSScvJGqLYhG8nNt8KPPswUAPni7TTMw.woff2
Courgette,https://fonts.gstatic.com/s/courgette/v18/wEO_EBrAnc9BLjLQAUk1VvoK.woff2
Dancing+Script,https://fonts.gstatic.com/s/dancingscript/v28/If2cXTr6YS-zF4S-kcSWSVi_sxjsohD9F50Ruu7BMSo3Sup8.woff2
Exo,https://fonts.gstatic.com/s/exo/v24/4UaZrEtFpBI4f1ZSIK9d4LjJ4lM3OwRmOw.woff2
Fjalla+One,https://fonts.gstatic.com/s/fjallaone/v15/Yq6R-LCAWCX3-6Ky7FAFrOF6kg.woff2
Germania+One,https://fonts.gstatic.com/s/germaniaone/v20/Fh4yPjrqIyv2ucM2qzBjeS3uywhP.woff2
Glass+Antiqua,https://fonts.gstatic.com/s/glassantiqua/v25/xfu30Wr0Wn3NOQM2piC0uXOjrLj6Ng.woff2
Gloria+Hallelujah,https://fonts.gstatic.com/s/gloriahallelujah/v23/LYjYdHv3kUk9BMV96EIswT9DIbW-MIS11zM.woff2
Great+Vibes,https://fonts.gstatic.com/s/greatvibes/v20/RWmMoKWR9v4ksMfaWd_JN9XFiaQ.woff2
Holtwood+One+SC,https://fonts.gstatic.com/s/holtwoodonesc/v22/yYLx0hLR0P-3vMFSk1TCq3Txg5BHdrz7.woff2
Indie+Flower,https://fonts.gstatic.com/s/indieflower/v23/m8JVjfNVeKWVnh3QMuKkFcZVaUuH.woff2
Italiana,https://fonts.gstatic.com/s/italiana/v21/QldNNTtLsx4E__B0XQmWaXw.woff2
Jost,https://fonts.gstatic.com/s/jost/v19/92zPtBhPNqw79Ij1E865zBUv7myjJTVBNIg.woff2
Kaushan+Script,https://fonts.gstatic.com/s/kaushanscript/v18/vm8vdRfvXFLG3OLnsO15WYS5DG74wNI.woff2
Lato,https://fonts.gstatic.com/s/lato/v24/S6uyw4BMUTPHjx4wXg.woff2
Metal+Mania,https://fonts.gstatic.com/s/metalmania/v22/RWmMoKWb4e8kqMfBUdPFJdXFiaQ.woff2
Montserrat,https://fonts.gstatic.com/s/montserrat/v30/JTUHjIg1_i6t8kCHKm4532VJOt5-QNFgpCtr6Hw5aXo.woff2
Neucha,https://fonts.gstatic.com/s/neucha/v17/q5uGsou0JOdh94bfvQlt.woff2
Noto+Sans,https://fonts.gstatic.com/s/notosans/v39/o-0mIpQlx3QUlC5A4PNB6Ryti20_6n1iPHjcz6L1SoM-jCpoiyD9A-9a6VI.woff2
Open+Sans,https://fonts.gstatic.com/s/opensans/v43/memSYaGs126MiZpBA-UvWbX2vVnXBbObj2OVZyOOSr4dVJWUgsjZ0B4gaVI.woff2
Orbitron,https://fonts.gstatic.com/s/orbitron/v34/yMJMMIlzdpvBhQQL_SC3X9yhF25-T1nyGy6BoWgz.woff2
Oswald,https://fonts.gstatic.com/s/oswald/v56/TK3_WkUHHAIjg75cFRf3bXL8LICs1_FvsUZiZQ.woff2
Pacifico,https://fonts.gstatic.com/s/pacifico/v22/FwZY7-Qmy14u9lezJ-6H6Mk.woff2
Permanent+Marker,https://fonts.gstatic.com/s/permanentmarker/v16/Fh4uPib9Iyv2ucM6pGQMWimMp004La2Cfw.woff2
Philosopher,https://fonts.gstatic.com/s/philosopher/v20/vEFV2_5QCwIS4_Dhez5jcWBuT00.woff2
Playfair+Display,https://fonts.gstatic.com/s/playfairdisplay/v39/nuFvD-vYSZviVYUb_rj3ij__anPXJzDwcbmjWBN2PKdFvXDXbtM.woff2
Poppins,https://fonts.gstatic.com/s/poppins/v23/pxiEyp8kv8JHgFVrJJfecg.woff2
Press+Start+2P,https://fonts.gstatic.com/s/pressstart2p/v15/e3t4euO8T-267oIAQAu6jDQyK3nVivM.woff2
Questrial,https://fonts.gstatic.com/s/questrial/v18/QdVUSTchPBm7nuUeVf70viFl.woff2
Quicksand,https://fonts.gstatic.com/s/quicksand/v36/6xK-dSZaM9iE8KbpRA_LJ3z8mH9BOJvgkP8o58a-wg.woff2
Rajdhani,https://fonts.gstatic.com/s/rajdhani/v16/LDIxapCSOBg7S-QT7p4HM-Y.woff2
Raleway,https://fonts.gstatic.com/s/raleway/v36/1Ptxg8zYS_SKggPN4iEgvnHyvveLxVvaorCIPrE.woff2
Righteous,https://fonts.gstatic.com/s/righteous/v18/1cXxaUPXBpj2rGoU7C9WiHGF.woff2
Roboto,https://fonts.gstatic.com/s/roboto/v48/KFOMCnqEu92Fr1ME7kSn66aGLdTylUAMQXC89YmC2DPNWubEbVmUiAo.woff2
Sacramento,https://fonts.gstatic.com/s/sacramento/v16/buEzpo6gcdjy0EiZMBUG4C0f_Q.woff2
Satisfy,https://fonts.gstatic.com/s/satisfy/v22/rP2Hp2yn6lkG50LoCZOIHQ.woff2
Space+Mono,https://fonts.gstatic.com/s/spacemono/v17/i7dPIFZifjKcF5UAWdDRYEF8RQ.woff2
Spectral,https://fonts.gstatic.com/s/spectral/v14/rnCr-xNNww_2s0amA9M5kng.woff2
Staatliches,https://fonts.gstatic.com/s/staatliches/v14/HI_OiY8KO6hCsQSoAPmtMYebvpA.woff2
Stint+Ultra+Condensed,https://fonts.gstatic.com/s/stintultracondensed/v24/-W_gXIrsVjjeyEnPC45qD2NoFPtBE0xCh2AOrR8P.woff2
Syncopate,https://fonts.gstatic.com/s/syncopate/v23/pe0sMIuPIYBCpEV5eFdCBfe_.woff2
Ultra,https://fonts.gstatic.com/s/ultra/v25/zOLy4prXmrtY-uT9wrI.woff2
Unica+One,https://fonts.gstatic.com/s/unicaone/v19/DPEuYwWHyAYGVTSmalsRcd3e.woff2
Work+Sans,https://fonts.gstatic.com/s/worksans/v23/QGY_z_wNahGAdqQ43RhVcIgYT2Xz5u32K0nXBi8Jpg.woff2
Yellowtail,https://fonts.gstatic.com/s/yellowtail/v24/OZpGg_pnoDtINPfRIlLohlvHwQ.woff2
1 family woff2_url
2 Abril+Fatface https://fonts.gstatic.com/s/abrilfatface/v24/zOL64pLDlL1D99S8g8PtiKchq-dmjQ.woff2
3 Alegreya https://fonts.gstatic.com/s/alegreya/v38/4UacrEBBsBhlBjvfkQjt71kZfyBzPgNG9hU4-6qj.woff2
4 Alfa+Slab+One https://fonts.gstatic.com/s/alfaslabone/v20/6NUQ8FmMKwSEKjnm5-4v-4Jh2dJhew.woff2
5 Almendra https://fonts.gstatic.com/s/almendra/v27/H4ckBXKAlMnTn0CskxY9yL4.woff2
6 Amatic+SC https://fonts.gstatic.com/s/amaticsc/v27/TUZyzwprpvBS1izr_vOECuSf.woff2
7 Andika https://fonts.gstatic.com/s/andika/v26/mem_Ya6iyW-LwqgwarYQ.woff2
8 Architects+Daughter https://fonts.gstatic.com/s/architectsdaughter/v19/KtkxAKiDZI_td1Lkx62xHZHDtgO_Y-bvTYlg4w.woff2
9 Audiowide https://fonts.gstatic.com/s/audiowide/v21/l7gdbjpo0cum0ckerWCdlg_O.woff2
10 Averia+Libre https://fonts.gstatic.com/s/averialibre/v16/2V0aKIcMGZEnV6xygz7eNjESBanI.woff2
11 Bebas+Neue https://fonts.gstatic.com/s/bebasneue/v15/JTUSjIg69CK48gW7PXoo9Wlhyw.woff2
12 Black+Ops+One https://fonts.gstatic.com/s/blackopsone/v20/qWcsB6-ypo7xBdr6Xshe96H3aDvbtw.woff2
13 Caveat https://fonts.gstatic.com/s/caveat/v22/WnznHAc5bAfYB2QRah7pcpNvOx-pjfJ9eIWpYQ.woff2
14 Cinzel+Decorative https://fonts.gstatic.com/s/cinzeldecorative/v18/daaCSScvJGqLYhG8nNt8KPPswUAPni7TTMw.woff2
15 Courgette https://fonts.gstatic.com/s/courgette/v18/wEO_EBrAnc9BLjLQAUk1VvoK.woff2
16 Dancing+Script https://fonts.gstatic.com/s/dancingscript/v28/If2cXTr6YS-zF4S-kcSWSVi_sxjsohD9F50Ruu7BMSo3Sup8.woff2
17 Exo https://fonts.gstatic.com/s/exo/v24/4UaZrEtFpBI4f1ZSIK9d4LjJ4lM3OwRmOw.woff2
18 Fjalla+One https://fonts.gstatic.com/s/fjallaone/v15/Yq6R-LCAWCX3-6Ky7FAFrOF6kg.woff2
19 Germania+One https://fonts.gstatic.com/s/germaniaone/v20/Fh4yPjrqIyv2ucM2qzBjeS3uywhP.woff2
20 Glass+Antiqua https://fonts.gstatic.com/s/glassantiqua/v25/xfu30Wr0Wn3NOQM2piC0uXOjrLj6Ng.woff2
21 Gloria+Hallelujah https://fonts.gstatic.com/s/gloriahallelujah/v23/LYjYdHv3kUk9BMV96EIswT9DIbW-MIS11zM.woff2
22 Great+Vibes https://fonts.gstatic.com/s/greatvibes/v20/RWmMoKWR9v4ksMfaWd_JN9XFiaQ.woff2
23 Holtwood+One+SC https://fonts.gstatic.com/s/holtwoodonesc/v22/yYLx0hLR0P-3vMFSk1TCq3Txg5BHdrz7.woff2
24 Indie+Flower https://fonts.gstatic.com/s/indieflower/v23/m8JVjfNVeKWVnh3QMuKkFcZVaUuH.woff2
25 Italiana https://fonts.gstatic.com/s/italiana/v21/QldNNTtLsx4E__B0XQmWaXw.woff2
26 Jost https://fonts.gstatic.com/s/jost/v19/92zPtBhPNqw79Ij1E865zBUv7myjJTVBNIg.woff2
27 Kaushan+Script https://fonts.gstatic.com/s/kaushanscript/v18/vm8vdRfvXFLG3OLnsO15WYS5DG74wNI.woff2
28 Lato https://fonts.gstatic.com/s/lato/v24/S6uyw4BMUTPHjx4wXg.woff2
29 Metal+Mania https://fonts.gstatic.com/s/metalmania/v22/RWmMoKWb4e8kqMfBUdPFJdXFiaQ.woff2
30 Montserrat https://fonts.gstatic.com/s/montserrat/v30/JTUHjIg1_i6t8kCHKm4532VJOt5-QNFgpCtr6Hw5aXo.woff2
31 Neucha https://fonts.gstatic.com/s/neucha/v17/q5uGsou0JOdh94bfvQlt.woff2
32 Noto+Sans https://fonts.gstatic.com/s/notosans/v39/o-0mIpQlx3QUlC5A4PNB6Ryti20_6n1iPHjcz6L1SoM-jCpoiyD9A-9a6VI.woff2
33 Open+Sans https://fonts.gstatic.com/s/opensans/v43/memSYaGs126MiZpBA-UvWbX2vVnXBbObj2OVZyOOSr4dVJWUgsjZ0B4gaVI.woff2
34 Orbitron https://fonts.gstatic.com/s/orbitron/v34/yMJMMIlzdpvBhQQL_SC3X9yhF25-T1nyGy6BoWgz.woff2
35 Oswald https://fonts.gstatic.com/s/oswald/v56/TK3_WkUHHAIjg75cFRf3bXL8LICs1_FvsUZiZQ.woff2
36 Pacifico https://fonts.gstatic.com/s/pacifico/v22/FwZY7-Qmy14u9lezJ-6H6Mk.woff2
37 Permanent+Marker https://fonts.gstatic.com/s/permanentmarker/v16/Fh4uPib9Iyv2ucM6pGQMWimMp004La2Cfw.woff2
38 Philosopher https://fonts.gstatic.com/s/philosopher/v20/vEFV2_5QCwIS4_Dhez5jcWBuT00.woff2
39 Playfair+Display https://fonts.gstatic.com/s/playfairdisplay/v39/nuFvD-vYSZviVYUb_rj3ij__anPXJzDwcbmjWBN2PKdFvXDXbtM.woff2
40 Poppins https://fonts.gstatic.com/s/poppins/v23/pxiEyp8kv8JHgFVrJJfecg.woff2
41 Press+Start+2P https://fonts.gstatic.com/s/pressstart2p/v15/e3t4euO8T-267oIAQAu6jDQyK3nVivM.woff2
42 Questrial https://fonts.gstatic.com/s/questrial/v18/QdVUSTchPBm7nuUeVf70viFl.woff2
43 Quicksand https://fonts.gstatic.com/s/quicksand/v36/6xK-dSZaM9iE8KbpRA_LJ3z8mH9BOJvgkP8o58a-wg.woff2
44 Rajdhani https://fonts.gstatic.com/s/rajdhani/v16/LDIxapCSOBg7S-QT7p4HM-Y.woff2
45 Raleway https://fonts.gstatic.com/s/raleway/v36/1Ptxg8zYS_SKggPN4iEgvnHyvveLxVvaorCIPrE.woff2
46 Righteous https://fonts.gstatic.com/s/righteous/v18/1cXxaUPXBpj2rGoU7C9WiHGF.woff2
47 Roboto https://fonts.gstatic.com/s/roboto/v48/KFOMCnqEu92Fr1ME7kSn66aGLdTylUAMQXC89YmC2DPNWubEbVmUiAo.woff2
48 Sacramento https://fonts.gstatic.com/s/sacramento/v16/buEzpo6gcdjy0EiZMBUG4C0f_Q.woff2
49 Satisfy https://fonts.gstatic.com/s/satisfy/v22/rP2Hp2yn6lkG50LoCZOIHQ.woff2
50 Space+Mono https://fonts.gstatic.com/s/spacemono/v17/i7dPIFZifjKcF5UAWdDRYEF8RQ.woff2
51 Spectral https://fonts.gstatic.com/s/spectral/v14/rnCr-xNNww_2s0amA9M5kng.woff2
52 Staatliches https://fonts.gstatic.com/s/staatliches/v14/HI_OiY8KO6hCsQSoAPmtMYebvpA.woff2
53 Stint+Ultra+Condensed https://fonts.gstatic.com/s/stintultracondensed/v24/-W_gXIrsVjjeyEnPC45qD2NoFPtBE0xCh2AOrR8P.woff2
54 Syncopate https://fonts.gstatic.com/s/syncopate/v23/pe0sMIuPIYBCpEV5eFdCBfe_.woff2
55 Ultra https://fonts.gstatic.com/s/ultra/v25/zOLy4prXmrtY-uT9wrI.woff2
56 Unica+One https://fonts.gstatic.com/s/unicaone/v19/DPEuYwWHyAYGVTSmalsRcd3e.woff2
57 Work+Sans https://fonts.gstatic.com/s/worksans/v23/QGY_z_wNahGAdqQ43RhVcIgYT2Xz5u32K0nXBi8Jpg.woff2
58 Yellowtail https://fonts.gstatic.com/s/yellowtail/v24/OZpGg_pnoDtINPfRIlLohlvHwQ.woff2

456
fonts.css Normal file
View File

@ -0,0 +1,456 @@
@font-face {
font-family: 'Abril Fatface';
font-style: normal;
font-weight: 400;
font-display: swap;
src: url('https://fonts.gstatic.com/s/abrilfatface/v24/zOL64pLDlL1D99S8g8PtiKchq-dmjQ.woff2') format('woff2');
/* subset: latin (aus Google Fonts CSS v2) */
}
@font-face {
font-family: 'Alegreya';
font-style: normal;
font-weight: 400;
font-display: swap;
src: url('https://fonts.gstatic.com/s/alegreya/v38/4UacrEBBsBhlBjvfkQjt71kZfyBzPgNG9hU4-6qj.woff2') format('woff2');
/* subset: latin (aus Google Fonts CSS v2) */
}
@font-face {
font-family: 'Alfa Slab One';
font-style: normal;
font-weight: 400;
font-display: swap;
src: url('https://fonts.gstatic.com/s/alfaslabone/v20/6NUQ8FmMKwSEKjnm5-4v-4Jh2dJhew.woff2') format('woff2');
/* subset: latin (aus Google Fonts CSS v2) */
}
@font-face {
font-family: 'Almendra';
font-style: normal;
font-weight: 400;
font-display: swap;
src: url('https://fonts.gstatic.com/s/almendra/v27/H4ckBXKAlMnTn0CskxY9yL4.woff2') format('woff2');
/* subset: latin (aus Google Fonts CSS v2) */
}
@font-face {
font-family: 'Amatic SC';
font-style: normal;
font-weight: 400;
font-display: swap;
src: url('https://fonts.gstatic.com/s/amaticsc/v27/TUZyzwprpvBS1izr_vOECuSf.woff2') format('woff2');
/* subset: latin (aus Google Fonts CSS v2) */
}
@font-face {
font-family: 'Andika';
font-style: normal;
font-weight: 400;
font-display: swap;
src: url('https://fonts.gstatic.com/s/andika/v26/mem_Ya6iyW-LwqgwarYQ.woff2') format('woff2');
/* subset: latin (aus Google Fonts CSS v2) */
}
@font-face {
font-family: 'Architects Daughter';
font-style: normal;
font-weight: 400;
font-display: swap;
src: url('https://fonts.gstatic.com/s/architectsdaughter/v19/KtkxAKiDZI_td1Lkx62xHZHDtgO_Y-bvTYlg4w.woff2') format('woff2');
/* subset: latin (aus Google Fonts CSS v2) */
}
@font-face {
font-family: 'Audiowide';
font-style: normal;
font-weight: 400;
font-display: swap;
src: url('https://fonts.gstatic.com/s/audiowide/v21/l7gdbjpo0cum0ckerWCdlg_O.woff2') format('woff2');
/* subset: latin (aus Google Fonts CSS v2) */
}
@font-face {
font-family: 'Averia Libre';
font-style: normal;
font-weight: 400;
font-display: swap;
src: url('https://fonts.gstatic.com/s/averialibre/v16/2V0aKIcMGZEnV6xygz7eNjESBanI.woff2') format('woff2');
/* subset: latin (aus Google Fonts CSS v2) */
}
@font-face {
font-family: 'Bebas Neue';
font-style: normal;
font-weight: 400;
font-display: swap;
src: url('https://fonts.gstatic.com/s/bebasneue/v15/JTUSjIg69CK48gW7PXoo9Wlhyw.woff2') format('woff2');
/* subset: latin (aus Google Fonts CSS v2) */
}
@font-face {
font-family: 'Black Ops One';
font-style: normal;
font-weight: 400;
font-display: swap;
src: url('https://fonts.gstatic.com/s/blackopsone/v20/qWcsB6-ypo7xBdr6Xshe96H3aDvbtw.woff2') format('woff2');
/* subset: latin (aus Google Fonts CSS v2) */
}
@font-face {
font-family: 'Caveat';
font-style: normal;
font-weight: 400;
font-display: swap;
src: url('https://fonts.gstatic.com/s/caveat/v22/WnznHAc5bAfYB2QRah7pcpNvOx-pjfJ9eIWpYQ.woff2') format('woff2');
/* subset: latin (aus Google Fonts CSS v2) */
}
@font-face {
font-family: 'Cinzel Decorative';
font-style: normal;
font-weight: 400;
font-display: swap;
src: url('https://fonts.gstatic.com/s/cinzeldecorative/v18/daaCSScvJGqLYhG8nNt8KPPswUAPni7TTMw.woff2') format('woff2');
/* subset: latin (aus Google Fonts CSS v2) */
}
@font-face {
font-family: 'Courgette';
font-style: normal;
font-weight: 400;
font-display: swap;
src: url('https://fonts.gstatic.com/s/courgette/v18/wEO_EBrAnc9BLjLQAUk1VvoK.woff2') format('woff2');
/* subset: latin (aus Google Fonts CSS v2) */
}
@font-face {
font-family: 'Dancing Script';
font-style: normal;
font-weight: 400;
font-display: swap;
src: url('https://fonts.gstatic.com/s/dancingscript/v28/If2cXTr6YS-zF4S-kcSWSVi_sxjsohD9F50Ruu7BMSo3Sup8.woff2') format('woff2');
/* subset: latin (aus Google Fonts CSS v2) */
}
@font-face {
font-family: 'Exo';
font-style: normal;
font-weight: 400;
font-display: swap;
src: url('https://fonts.gstatic.com/s/exo/v24/4UaZrEtFpBI4f1ZSIK9d4LjJ4lM3OwRmOw.woff2') format('woff2');
/* subset: latin (aus Google Fonts CSS v2) */
}
@font-face {
font-family: 'Fjalla One';
font-style: normal;
font-weight: 400;
font-display: swap;
src: url('https://fonts.gstatic.com/s/fjallaone/v15/Yq6R-LCAWCX3-6Ky7FAFrOF6kg.woff2') format('woff2');
/* subset: latin (aus Google Fonts CSS v2) */
}
@font-face {
font-family: 'Germania One';
font-style: normal;
font-weight: 400;
font-display: swap;
src: url('https://fonts.gstatic.com/s/germaniaone/v20/Fh4yPjrqIyv2ucM2qzBjeS3uywhP.woff2') format('woff2');
/* subset: latin (aus Google Fonts CSS v2) */
}
@font-face {
font-family: 'Glass Antiqua';
font-style: normal;
font-weight: 400;
font-display: swap;
src: url('https://fonts.gstatic.com/s/glassantiqua/v25/xfu30Wr0Wn3NOQM2piC0uXOjrLj6Ng.woff2') format('woff2');
/* subset: latin (aus Google Fonts CSS v2) */
}
@font-face {
font-family: 'Gloria Hallelujah';
font-style: normal;
font-weight: 400;
font-display: swap;
src: url('https://fonts.gstatic.com/s/gloriahallelujah/v23/LYjYdHv3kUk9BMV96EIswT9DIbW-MIS11zM.woff2') format('woff2');
/* subset: latin (aus Google Fonts CSS v2) */
}
@font-face {
font-family: 'Great Vibes';
font-style: normal;
font-weight: 400;
font-display: swap;
src: url('https://fonts.gstatic.com/s/greatvibes/v20/RWmMoKWR9v4ksMfaWd_JN9XFiaQ.woff2') format('woff2');
/* subset: latin (aus Google Fonts CSS v2) */
}
@font-face {
font-family: 'Holtwood One SC';
font-style: normal;
font-weight: 400;
font-display: swap;
src: url('https://fonts.gstatic.com/s/holtwoodonesc/v22/yYLx0hLR0P-3vMFSk1TCq3Txg5BHdrz7.woff2') format('woff2');
/* subset: latin (aus Google Fonts CSS v2) */
}
@font-face {
font-family: 'Indie Flower';
font-style: normal;
font-weight: 400;
font-display: swap;
src: url('https://fonts.gstatic.com/s/indieflower/v23/m8JVjfNVeKWVnh3QMuKkFcZVaUuH.woff2') format('woff2');
/* subset: latin (aus Google Fonts CSS v2) */
}
@font-face {
font-family: 'Italiana';
font-style: normal;
font-weight: 400;
font-display: swap;
src: url('https://fonts.gstatic.com/s/italiana/v21/QldNNTtLsx4E__B0XQmWaXw.woff2') format('woff2');
/* subset: latin (aus Google Fonts CSS v2) */
}
@font-face {
font-family: 'Jost';
font-style: normal;
font-weight: 400;
font-display: swap;
src: url('https://fonts.gstatic.com/s/jost/v19/92zPtBhPNqw79Ij1E865zBUv7myjJTVBNIg.woff2') format('woff2');
/* subset: latin (aus Google Fonts CSS v2) */
}
@font-face {
font-family: 'Kaushan Script';
font-style: normal;
font-weight: 400;
font-display: swap;
src: url('https://fonts.gstatic.com/s/kaushanscript/v18/vm8vdRfvXFLG3OLnsO15WYS5DG74wNI.woff2') format('woff2');
/* subset: latin (aus Google Fonts CSS v2) */
}
@font-face {
font-family: 'Lato';
font-style: normal;
font-weight: 400;
font-display: swap;
src: url('https://fonts.gstatic.com/s/lato/v24/S6uyw4BMUTPHjx4wXg.woff2') format('woff2');
/* subset: latin (aus Google Fonts CSS v2) */
}
@font-face {
font-family: 'Metal Mania';
font-style: normal;
font-weight: 400;
font-display: swap;
src: url('https://fonts.gstatic.com/s/metalmania/v22/RWmMoKWb4e8kqMfBUdPFJdXFiaQ.woff2') format('woff2');
/* subset: latin (aus Google Fonts CSS v2) */
}
@font-face {
font-family: 'Montserrat';
font-style: normal;
font-weight: 400;
font-display: swap;
src: url('https://fonts.gstatic.com/s/montserrat/v30/JTUHjIg1_i6t8kCHKm4532VJOt5-QNFgpCtr6Hw5aXo.woff2') format('woff2');
/* subset: latin (aus Google Fonts CSS v2) */
}
@font-face {
font-family: 'Neucha';
font-style: normal;
font-weight: 400;
font-display: swap;
src: url('https://fonts.gstatic.com/s/neucha/v17/q5uGsou0JOdh94bfvQlt.woff2') format('woff2');
/* subset: latin (aus Google Fonts CSS v2) */
}
@font-face {
font-family: 'Noto Sans';
font-style: normal;
font-weight: 400;
font-display: swap;
src: url('https://fonts.gstatic.com/s/notosans/v39/o-0mIpQlx3QUlC5A4PNB6Ryti20_6n1iPHjcz6L1SoM-jCpoiyD9A-9a6VI.woff2') format('woff2');
/* subset: latin (aus Google Fonts CSS v2) */
}
@font-face {
font-family: 'Open Sans';
font-style: normal;
font-weight: 400;
font-display: swap;
src: url('https://fonts.gstatic.com/s/opensans/v43/memSYaGs126MiZpBA-UvWbX2vVnXBbObj2OVZyOOSr4dVJWUgsjZ0B4gaVI.woff2') format('woff2');
/* subset: latin (aus Google Fonts CSS v2) */
}
@font-face {
font-family: 'Orbitron';
font-style: normal;
font-weight: 400;
font-display: swap;
src: url('https://fonts.gstatic.com/s/orbitron/v34/yMJMMIlzdpvBhQQL_SC3X9yhF25-T1nyGy6BoWgz.woff2') format('woff2');
/* subset: latin (aus Google Fonts CSS v2) */
}
@font-face {
font-family: 'Oswald';
font-style: normal;
font-weight: 400;
font-display: swap;
src: url('https://fonts.gstatic.com/s/oswald/v56/TK3_WkUHHAIjg75cFRf3bXL8LICs1_FvsUZiZQ.woff2') format('woff2');
/* subset: latin (aus Google Fonts CSS v2) */
}
@font-face {
font-family: 'Pacifico';
font-style: normal;
font-weight: 400;
font-display: swap;
src: url('https://fonts.gstatic.com/s/pacifico/v22/FwZY7-Qmy14u9lezJ-6H6Mk.woff2') format('woff2');
/* subset: latin (aus Google Fonts CSS v2) */
}
@font-face {
font-family: 'Permanent Marker';
font-style: normal;
font-weight: 400;
font-display: swap;
src: url('https://fonts.gstatic.com/s/permanentmarker/v16/Fh4uPib9Iyv2ucM6pGQMWimMp004La2Cfw.woff2') format('woff2');
/* subset: latin (aus Google Fonts CSS v2) */
}
@font-face {
font-family: 'Philosopher';
font-style: normal;
font-weight: 400;
font-display: swap;
src: url('https://fonts.gstatic.com/s/philosopher/v20/vEFV2_5QCwIS4_Dhez5jcWBuT00.woff2') format('woff2');
/* subset: latin (aus Google Fonts CSS v2) */
}
@font-face {
font-family: 'Playfair Display';
font-style: normal;
font-weight: 400;
font-display: swap;
src: url('https://fonts.gstatic.com/s/playfairdisplay/v39/nuFvD-vYSZviVYUb_rj3ij__anPXJzDwcbmjWBN2PKdFvXDXbtM.woff2') format('woff2');
/* subset: latin (aus Google Fonts CSS v2) */
}
@font-face {
font-family: 'Poppins';
font-style: normal;
font-weight: 400;
font-display: swap;
src: url('https://fonts.gstatic.com/s/poppins/v23/pxiEyp8kv8JHgFVrJJfecg.woff2') format('woff2');
/* subset: latin (aus Google Fonts CSS v2) */
}
@font-face {
font-family: 'Press Start 2P';
font-style: normal;
font-weight: 400;
font-display: swap;
src: url('https://fonts.gstatic.com/s/pressstart2p/v15/e3t4euO8T-267oIAQAu6jDQyK3nVivM.woff2') format('woff2');
/* subset: latin (aus Google Fonts CSS v2) */
}
@font-face {
font-family: 'Questrial';
font-style: normal;
font-weight: 400;
font-display: swap;
src: url('https://fonts.gstatic.com/s/questrial/v18/QdVUSTchPBm7nuUeVf70viFl.woff2') format('woff2');
/* subset: latin (aus Google Fonts CSS v2) */
}
@font-face {
font-family: 'Quicksand';
font-style: normal;
font-weight: 400;
font-display: swap;
src: url('https://fonts.gstatic.com/s/quicksand/v36/6xK-dSZaM9iE8KbpRA_LJ3z8mH9BOJvgkP8o58a-wg.woff2') format('woff2');
/* subset: latin (aus Google Fonts CSS v2) */
}
@font-face {
font-family: 'Rajdhani';
font-style: normal;
font-weight: 400;
font-display: swap;
src: url('https://fonts.gstatic.com/s/rajdhani/v16/LDIxapCSOBg7S-QT7p4HM-Y.woff2') format('woff2');
/* subset: latin (aus Google Fonts CSS v2) */
}
@font-face {
font-family: 'Raleway';
font-style: normal;
font-weight: 400;
font-display: swap;
src: url('https://fonts.gstatic.com/s/raleway/v36/1Ptxg8zYS_SKggPN4iEgvnHyvveLxVvaorCIPrE.woff2') format('woff2');
/* subset: latin (aus Google Fonts CSS v2) */
}
@font-face {
font-family: 'Righteous';
font-style: normal;
font-weight: 400;
font-display: swap;
src: url('https://fonts.gstatic.com/s/righteous/v18/1cXxaUPXBpj2rGoU7C9WiHGF.woff2') format('woff2');
/* subset: latin (aus Google Fonts CSS v2) */
}
@font-face {
font-family: 'Roboto';
font-style: normal;
font-weight: 400;
font-display: swap;
src: url('https://fonts.gstatic.com/s/roboto/v48/KFOMCnqEu92Fr1ME7kSn66aGLdTylUAMQXC89YmC2DPNWubEbVmUiAo.woff2') format('woff2');
/* subset: latin (aus Google Fonts CSS v2) */
}
@font-face {
font-family: 'Sacramento';
font-style: normal;
font-weight: 400;
font-display: swap;
src: url('https://fonts.gstatic.com/s/sacramento/v16/buEzpo6gcdjy0EiZMBUG4C0f_Q.woff2') format('woff2');
/* subset: latin (aus Google Fonts CSS v2) */
}
@font-face {
font-family: 'Satisfy';
font-style: normal;
font-weight: 400;
font-display: swap;
src: url('https://fonts.gstatic.com/s/satisfy/v22/rP2Hp2yn6lkG50LoCZOIHQ.woff2') format('woff2');
/* subset: latin (aus Google Fonts CSS v2) */
}
@font-face {
font-family: 'Space Mono';
font-style: normal;
font-weight: 400;
font-display: swap;
src: url('https://fonts.gstatic.com/s/spacemono/v17/i7dPIFZifjKcF5UAWdDRYEF8RQ.woff2') format('woff2');
/* subset: latin (aus Google Fonts CSS v2) */
}
@font-face {
font-family: 'Spectral';
font-style: normal;
font-weight: 400;
font-display: swap;
src: url('https://fonts.gstatic.com/s/spectral/v14/rnCr-xNNww_2s0amA9M5kng.woff2') format('woff2');
/* subset: latin (aus Google Fonts CSS v2) */
}
@font-face {
font-family: 'Staatliches';
font-style: normal;
font-weight: 400;
font-display: swap;
src: url('https://fonts.gstatic.com/s/staatliches/v14/HI_OiY8KO6hCsQSoAPmtMYebvpA.woff2') format('woff2');
/* subset: latin (aus Google Fonts CSS v2) */
}
@font-face {
font-family: 'Stint Ultra Condensed';
font-style: normal;
font-weight: 400;
font-display: swap;
src: url('https://fonts.gstatic.com/s/stintultracondensed/v24/-W_gXIrsVjjeyEnPC45qD2NoFPtBE0xCh2AOrR8P.woff2') format('woff2');
/* subset: latin (aus Google Fonts CSS v2) */
}
@font-face {
font-family: 'Syncopate';
font-style: normal;
font-weight: 400;
font-display: swap;
src: url('https://fonts.gstatic.com/s/syncopate/v23/pe0sMIuPIYBCpEV5eFdCBfe_.woff2') format('woff2');
/* subset: latin (aus Google Fonts CSS v2) */
}
@font-face {
font-family: 'Ultra';
font-style: normal;
font-weight: 400;
font-display: swap;
src: url('https://fonts.gstatic.com/s/ultra/v25/zOLy4prXmrtY-uT9wrI.woff2') format('woff2');
/* subset: latin (aus Google Fonts CSS v2) */
}
@font-face {
font-family: 'Unica One';
font-style: normal;
font-weight: 400;
font-display: swap;
src: url('https://fonts.gstatic.com/s/unicaone/v19/DPEuYwWHyAYGVTSmalsRcd3e.woff2') format('woff2');
/* subset: latin (aus Google Fonts CSS v2) */
}
@font-face {
font-family: 'Work Sans';
font-style: normal;
font-weight: 400;
font-display: swap;
src: url('https://fonts.gstatic.com/s/worksans/v23/QGY_z_wNahGAdqQ43RhVcIgYT2Xz5u32K0nXBi8Jpg.woff2') format('woff2');
/* subset: latin (aus Google Fonts CSS v2) */
}
@font-face {
font-family: 'Yellowtail';
font-style: normal;
font-weight: 400;
font-display: swap;
src: url('https://fonts.gstatic.com/s/yellowtail/v24/OZpGg_pnoDtINPfRIlLohlvHwQ.woff2') format('woff2');
/* subset: latin (aus Google Fonts CSS v2) */
}

456
fonts.generated.css Normal file
View File

@ -0,0 +1,456 @@
@font-face {
font-family: "AbrilFatface";
font-style: normal;
font-weight: 400;
font-display: swap;
src: url("https://fonts.gstatic.com/s/abrilfatface/v24/zOL64pLDlL1D99S8g8PtiKchq-dmjQ.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: "Alegreya";
font-style: normal;
font-weight: 400;
font-display: swap;
src: url("https://fonts.gstatic.com/s/alegreya/v38/4UacrEBBsBhlBjvfkQjt71kZfyBzPgNG9hU4-6qj.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: "AlfaSlabOne";
font-style: normal;
font-weight: 400;
font-display: swap;
src: url("https://fonts.gstatic.com/s/alfaslabone/v20/6NUQ8FmMKwSEKjnm5-4v-4Jh2dJhew.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: "Almendra";
font-style: normal;
font-weight: 400;
font-display: swap;
src: url("https://fonts.gstatic.com/s/almendra/v27/H4ckBXKAlMnTn0CskxY9yL4.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: "AmaticSc";
font-style: normal;
font-weight: 400;
font-display: swap;
src: url("https://fonts.gstatic.com/s/amaticsc/v27/TUZyzwprpvBS1izr_vOECuSf.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: "Andika";
font-style: normal;
font-weight: 400;
font-display: swap;
src: url("https://fonts.gstatic.com/s/andika/v26/mem_Ya6iyW-LwqgwarYQ.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: "ArchitectsDaughter";
font-style: normal;
font-weight: 400;
font-display: swap;
src: url("https://fonts.gstatic.com/s/architectsdaughter/v19/KtkxAKiDZI_td1Lkx62xHZHDtgO_Y-bvTYlg4w.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: "Audiowide";
font-style: normal;
font-weight: 400;
font-display: swap;
src: url("https://fonts.gstatic.com/s/audiowide/v21/l7gdbjpo0cum0ckerWCdlg_O.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: "AveriaLibre";
font-style: normal;
font-weight: 400;
font-display: swap;
src: url("https://fonts.gstatic.com/s/averialibre/v16/2V0aKIcMGZEnV6xygz7eNjESBanI.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: "BebasNeue";
font-style: normal;
font-weight: 400;
font-display: swap;
src: url("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: "BlackOpsOne";
font-style: normal;
font-weight: 400;
font-display: swap;
src: url("https://fonts.gstatic.com/s/blackopsone/v20/qWcsB6-ypo7xBdr6Xshe96H3aDvbtw.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: "Caveat";
font-style: normal;
font-weight: 400;
font-display: swap;
src: url("https://fonts.gstatic.com/s/caveat/v22/WnznHAc5bAfYB2QRah7pcpNvOx-pjfJ9eIWpYQ.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: "CinzelDecorative";
font-style: normal;
font-weight: 400;
font-display: swap;
src: url("https://fonts.gstatic.com/s/cinzeldecorative/v18/daaCSScvJGqLYhG8nNt8KPPswUAPni7TTMw.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: "Courgette";
font-style: normal;
font-weight: 400;
font-display: swap;
src: url("https://fonts.gstatic.com/s/courgette/v18/wEO_EBrAnc9BLjLQAUk1VvoK.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: "DancingScript";
font-style: normal;
font-weight: 400;
font-display: swap;
src: url("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: "Exo";
font-style: normal;
font-weight: 400;
font-display: swap;
src: url("https://fonts.gstatic.com/s/exo/v24/4UaZrEtFpBI4f1ZSIK9d4LjJ4lM3OwRmOw.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: "FjallaOne";
font-style: normal;
font-weight: 400;
font-display: swap;
src: url("https://fonts.gstatic.com/s/fjallaone/v15/Yq6R-LCAWCX3-6Ky7FAFrOF6kg.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: "GermaniaOne";
font-style: normal;
font-weight: 400;
font-display: swap;
src: url("https://fonts.gstatic.com/s/germaniaone/v20/Fh4yPjrqIyv2ucM2qzBjeS3uywhP.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: "GlassAntiqua";
font-style: normal;
font-weight: 400;
font-display: swap;
src: url("https://fonts.gstatic.com/s/glassantiqua/v25/xfu30Wr0Wn3NOQM2piC0uXOjrLj6Ng.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: "GloriaHallelujah";
font-style: normal;
font-weight: 400;
font-display: swap;
src: url("https://fonts.gstatic.com/s/gloriahallelujah/v23/LYjYdHv3kUk9BMV96EIswT9DIbW-MIS11zM.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: "GreatVibes";
font-style: normal;
font-weight: 400;
font-display: swap;
src: url("https://fonts.gstatic.com/s/greatvibes/v20/RWmMoKWR9v4ksMfaWd_JN9XFiaQ.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: "HoltwoodOneSc";
font-style: normal;
font-weight: 400;
font-display: swap;
src: url("https://fonts.gstatic.com/s/holtwoodonesc/v22/yYLx0hLR0P-3vMFSk1TCq3Txg5BHdrz7.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: "IndieFlower";
font-style: normal;
font-weight: 400;
font-display: swap;
src: url("https://fonts.gstatic.com/s/indieflower/v23/m8JVjfNVeKWVnh3QMuKkFcZVaUuH.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: "Italiana";
font-style: normal;
font-weight: 400;
font-display: swap;
src: url("https://fonts.gstatic.com/s/italiana/v21/QldNNTtLsx4E__B0XQmWaXw.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: "Jost";
font-style: normal;
font-weight: 400;
font-display: swap;
src: url("https://fonts.gstatic.com/s/jost/v19/92zPtBhPNqw79Ij1E865zBUv7myjJTVBNIg.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: "KaushanScript";
font-style: normal;
font-weight: 400;
font-display: swap;
src: url("https://fonts.gstatic.com/s/kaushanscript/v18/vm8vdRfvXFLG3OLnsO15WYS5DG74wNI.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: "Lato";
font-style: normal;
font-weight: 400;
font-display: swap;
src: url("https://fonts.gstatic.com/s/lato/v24/S6uyw4BMUTPHjx4wXg.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: "MetalMania";
font-style: normal;
font-weight: 400;
font-display: swap;
src: url("https://fonts.gstatic.com/s/metalmania/v22/RWmMoKWb4e8kqMfBUdPFJdXFiaQ.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: 400;
font-display: swap;
src: url("https://fonts.gstatic.com/s/montserrat/v30/JTUHjIg1_i6t8kCHKm4532VJOt5-QNFgpCtr6Hw5aXo.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: "Neucha";
font-style: normal;
font-weight: 400;
font-display: swap;
src: url("https://fonts.gstatic.com/s/neucha/v17/q5uGsou0JOdh94bfvQlt.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: "NotoSans";
font-style: normal;
font-weight: 400;
font-display: swap;
src: url("https://fonts.gstatic.com/s/notosans/v39/o-0mIpQlx3QUlC5A4PNB6Ryti20_6n1iPHjcz6L1SoM-jCpoiyD9A-9a6VI.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: "OpenSans";
font-style: normal;
font-weight: 400;
font-display: swap;
src: url("https://fonts.gstatic.com/s/opensans/v43/memSYaGs126MiZpBA-UvWbX2vVnXBbObj2OVZyOOSr4dVJWUgsjZ0B4gaVI.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: url("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: "Oswald";
font-style: normal;
font-weight: 400;
font-display: swap;
src: url("https://fonts.gstatic.com/s/oswald/v56/TK3_WkUHHAIjg75cFRf3bXL8LICs1_FvsUZiZQ.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: url("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: "PermanentMarker";
font-style: normal;
font-weight: 400;
font-display: swap;
src: url("https://fonts.gstatic.com/s/permanentmarker/v16/Fh4uPib9Iyv2ucM6pGQMWimMp004La2Cfw.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: "Philosopher";
font-style: normal;
font-weight: 400;
font-display: swap;
src: url("https://fonts.gstatic.com/s/philosopher/v20/vEFV2_5QCwIS4_Dhez5jcWBuT00.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: "PlayfairDisplay";
font-style: normal;
font-weight: 400;
font-display: swap;
src: url("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: 400;
font-display: swap;
src: url("https://fonts.gstatic.com/s/poppins/v23/pxiEyp8kv8JHgFVrJJfecg.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: "PressStart2P";
font-style: normal;
font-weight: 400;
font-display: swap;
src: url("https://fonts.gstatic.com/s/pressstart2p/v15/e3t4euO8T-267oIAQAu6jDQyK3nVivM.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: "Questrial";
font-style: normal;
font-weight: 400;
font-display: swap;
src: url("https://fonts.gstatic.com/s/questrial/v18/QdVUSTchPBm7nuUeVf70viFl.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: "Quicksand";
font-style: normal;
font-weight: 400;
font-display: swap;
src: url("https://fonts.gstatic.com/s/quicksand/v36/6xK-dSZaM9iE8KbpRA_LJ3z8mH9BOJvgkP8o58a-wg.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: "Rajdhani";
font-style: normal;
font-weight: 400;
font-display: swap;
src: url("https://fonts.gstatic.com/s/rajdhani/v16/LDIxapCSOBg7S-QT7p4HM-Y.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: "Raleway";
font-style: normal;
font-weight: 400;
font-display: swap;
src: url("https://fonts.gstatic.com/s/raleway/v36/1Ptxg8zYS_SKggPN4iEgvnHyvveLxVvaorCIPrE.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: "Righteous";
font-style: normal;
font-weight: 400;
font-display: swap;
src: url("https://fonts.gstatic.com/s/righteous/v18/1cXxaUPXBpj2rGoU7C9WiHGF.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: "Roboto";
font-style: normal;
font-weight: 400;
font-display: swap;
src: url("https://fonts.gstatic.com/s/roboto/v48/KFOMCnqEu92Fr1ME7kSn66aGLdTylUAMQXC89YmC2DPNWubEbVmUiAo.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: "Sacramento";
font-style: normal;
font-weight: 400;
font-display: swap;
src: url("https://fonts.gstatic.com/s/sacramento/v16/buEzpo6gcdjy0EiZMBUG4C0f_Q.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: "Satisfy";
font-style: normal;
font-weight: 400;
font-display: swap;
src: url("https://fonts.gstatic.com/s/satisfy/v22/rP2Hp2yn6lkG50LoCZOIHQ.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: "SpaceMono";
font-style: normal;
font-weight: 400;
font-display: swap;
src: url("https://fonts.gstatic.com/s/spacemono/v17/i7dPIFZifjKcF5UAWdDRYEF8RQ.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: "Spectral";
font-style: normal;
font-weight: 400;
font-display: swap;
src: url("https://fonts.gstatic.com/s/spectral/v14/rnCr-xNNww_2s0amA9M5kng.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: "Staatliches";
font-style: normal;
font-weight: 400;
font-display: swap;
src: url("https://fonts.gstatic.com/s/staatliches/v14/HI_OiY8KO6hCsQSoAPmtMYebvpA.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: "StintUltraCondensed";
font-style: normal;
font-weight: 400;
font-display: swap;
src: url("https://fonts.gstatic.com/s/stintultracondensed/v24/-W_gXIrsVjjeyEnPC45qD2NoFPtBE0xCh2AOrR8P.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: "Syncopate";
font-style: normal;
font-weight: 400;
font-display: swap;
src: url("https://fonts.gstatic.com/s/syncopate/v23/pe0sMIuPIYBCpEV5eFdCBfe_.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: "Ultra";
font-style: normal;
font-weight: 400;
font-display: swap;
src: url("https://fonts.gstatic.com/s/ultra/v25/zOLy4prXmrtY-uT9wrI.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: "UnicaOne";
font-style: normal;
font-weight: 400;
font-display: swap;
src: url("https://fonts.gstatic.com/s/unicaone/v19/DPEuYwWHyAYGVTSmalsRcd3e.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: "WorkSans";
font-style: normal;
font-weight: 400;
font-display: swap;
src: url("https://fonts.gstatic.com/s/worksans/v23/QGY_z_wNahGAdqQ43RhVcIgYT2Xz5u32K0nXBi8Jpg.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: "Yellowtail";
font-style: normal;
font-weight: 400;
font-display: swap;
src: url("https://fonts.gstatic.com/s/yellowtail/v24/OZpGg_pnoDtINPfRIlLohlvHwQ.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;
}

24
instrumentation-client.js Normal file
View File

@ -0,0 +1,24 @@
// instrumentation-client.js
import posthog from "posthog-js";
// envs lesen
const key = process.env.NEXT_PUBLIC_POSTHOG_KEY;
const host = process.env.NEXT_PUBLIC_POSTHOG_HOST || "https://us.i.posthog.com";
// nur im Browser initialisieren + Doppel-Init verhindern
if (typeof window !== "undefined" && !window.__posthogInitialized) {
if (key) {
posthog.init(key, {
api_host: host,
capture_pageview: false, // Pageviews trackst du selbst
loaded: () => {
if (process.env.NODE_ENV === "development") posthog.debug();
},
});
window.__posthogInitialized = true;
} else {
console.warn("NEXT_PUBLIC_POSTHOG_KEY ist nicht gesetzt");
}
}
export default posthog;

View File

@ -1,73 +1,355 @@
// lib/fonts.js
import {
Montserrat,
Lato,
Raleway,
Poppins,
Open_Sans,
Roboto,
Work_Sans,
Noto_Sans,
Jost,
Quicksand,
Averia_Libre,
Philosopher,
Pacifico,
Sacramento,
Caveat,
Dancing_Script,
Indie_Flower,
Amatic_SC,
Kaushan_Script,
Architects_Daughter,
Neucha,
Great_Vibes,
Satisfy,
Yellowtail,
Gloria_Hallelujah,
Courgette,
Almendra,
Oswald,
Bebas_Neue,
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 fonts = {
// 🔤 Modern
montserrat: "font-montserrat",
lato: "font-lato",
raleway: "font-raleway",
poppins: "font-poppins",
opensans: "font-open-sans",
roboto: "font-roboto",
worksans: "font-work-sans",
notosans: "font-noto-sans",
jost: "font-jost",
quicksand: "font-quicksand",
averialibre: "font-averia-libre",
philosopher: "font-philosopher",
// Moderne Schriftarten
export const montserrat = Montserrat({
subsets: ["latin"],
weight: ["100", "200", "300", "400", "500", "600", "700", "800", "900"],
variable: "--font-montserrat",
});
export const lato = Lato({
subsets: ["latin"],
weight: ["100", "300", "400", "700", "900"],
variable: "--font-lato",
});
export const raleway = Raleway({
subsets: ["latin"],
weight: ["100", "200", "300", "400", "500", "600", "700", "800", "900"],
variable: "--font-raleway",
});
export const poppins = Poppins({
subsets: ["latin"],
weight: ["100", "200", "300", "400", "500", "600", "700", "800", "900"],
variable: "--font-poppins",
});
export const openSans = Open_Sans({
subsets: ["latin"],
weight: ["300", "400", "500", "600", "700", "800"],
variable: "--font-open-sans",
});
export const roboto = Roboto({
subsets: ["latin"],
weight: ["100", "300", "400", "500", "700", "900"],
variable: "--font-roboto",
});
export const workSans = Work_Sans({
subsets: ["latin"],
weight: ["100", "200", "300", "400", "500", "600", "700", "800", "900"],
variable: "--font-work-sans",
});
export const notoSans = Noto_Sans({
subsets: ["latin"],
weight: ["100", "200", "300", "400", "500", "600", "700", "800", "900"],
variable: "--font-noto-sans",
});
export const jost = Jost({
subsets: ["latin"],
weight: ["100", "200", "300", "400", "500", "600", "700", "800", "900"],
variable: "--font-jost",
});
export const quicksand = Quicksand({
subsets: ["latin"],
weight: ["300", "400", "500", "600", "700"],
variable: "--font-quicksand",
});
export const averiaLibre = Averia_Libre({
subsets: ["latin"],
weight: "400",
variable: "--font-averia-libre",
});
export const philosopher = Philosopher({
subsets: ["latin"],
weight: "400",
variable: "--font-philosopher",
});
// ✍️ Handwriting
pacifico: "font-pacifico",
sacramento: "font-sacramento",
caveat: "font-caveat",
dancingscript: "font-dancing-script",
indieflower: "font-indie-flower",
amatic: "font-amatic-sc",
kaushan: "font-kaushan-script",
architects: "font-architects-daughter",
neucha: "font-neucha",
greatvibes: "font-great-vibes",
satisfy: "font-satisfy",
yellowtail: "font-yellowtail",
gloria: "font-gloria-hallelujah",
courgette: "font-courgette",
almendra: "font-almendra",
// Handschriften
export const pacifico = Pacifico({
subsets: ["latin"],
weight: "400",
variable: "--font-pacifico",
});
export const sacramento = Sacramento({
subsets: ["latin"],
weight: "400",
variable: "--font-sacramento",
});
export const caveat = Caveat({
subsets: ["latin"],
weight: "400",
variable: "--font-caveat",
});
export const dancingScript = Dancing_Script({
subsets: ["latin"],
weight: ["400", "500", "600", "700"],
variable: "--font-dancing-script",
});
export const indieFlower = Indie_Flower({
subsets: ["latin"],
weight: "400",
variable: "--font-indie-flower",
});
export const amatic = Amatic_SC({
subsets: ["latin"],
weight: "400",
variable: "--font-amatic-sc",
});
export const kaushan = Kaushan_Script({
subsets: ["latin"],
weight: "400",
variable: "--font-kaushan-script",
});
export const architects = Architects_Daughter({
subsets: ["latin"],
weight: "400",
variable: "--font-architects-daughter",
});
export const neucha = Neucha({
subsets: ["latin"],
weight: "400",
variable: "--font-neucha",
});
export const greatVibes = Great_Vibes({
subsets: ["latin"],
weight: "400",
variable: "--font-great-vibes",
});
export const satisfy = Satisfy({
subsets: ["latin"],
weight: "400",
variable: "--font-satisfy",
});
export const yellowtail = Yellowtail({
subsets: ["latin"],
weight: "400",
variable: "--font-yellowtail",
});
export const gloria = Gloria_Hallelujah({
subsets: ["latin"],
weight: "400",
variable: "--font-gloria-hallelujah",
});
export const courgette = Courgette({
subsets: ["latin"],
weight: "400",
variable: "--font-courgette",
});
export const almendra = Almendra({
subsets: ["latin"],
weight: "400",
variable: "--font-almendra",
});
// 🧑‍🎤 Statement
oswald: "font-oswald",
bebasneue: "font-bebas-neue",
ultra: "font-ultra",
stint: "font-stint-ultra-condensed",
playfair: "font-playfair-display",
abril: "font-abril-fatface",
permanentmarker: "font-permanent-marker",
alfaslab: "font-alfa-slab-one",
blackops: "font-black-ops-one",
germania: "font-germania-one",
holtwood: "font-holtwood-one-sc",
// Statement-Schriftarten
export const oswald = Oswald({
subsets: ["latin"],
weight: ["200", "300", "400", "500", "600", "700"],
variable: "--font-oswald",
});
export const bebasNeue = Bebas_Neue({
subsets: ["latin"],
weight: "400",
variable: "--font-bebas-neue",
});
export const ultra = Ultra({
subsets: ["latin"],
weight: "400",
variable: "--font-ultra",
});
export const stint = Stint_Ultra_Condensed({
subsets: ["latin"],
weight: "400",
variable: "--font-stint-ultra-condensed",
});
export const playfair = Playfair_Display({
subsets: ["latin"],
weight: ["400", "500", "600", "700", "800", "900"],
variable: "--font-playfair-display",
});
export const abril = Abril_Fatface({
subsets: ["latin"],
weight: "400",
variable: "--font-abril-fatface",
});
export const permanentMarker = Permanent_Marker({
subsets: ["latin"],
weight: "400",
variable: "--font-permanent-marker",
});
export const alfaSlab = Alfa_Slab_One({
subsets: ["latin"],
weight: "400",
variable: "--font-alfa-slab-one",
});
export const blackOps = Black_Ops_One({
subsets: ["latin"],
weight: "400",
variable: "--font-black-ops-one",
});
export const germania = Germania_One({
subsets: ["latin"],
weight: "400",
variable: "--font-germania-one",
});
export const holtwood = Holtwood_One_SC({
subsets: ["latin"],
weight: "400",
variable: "--font-holtwood-one-sc",
});
// 🚀 Futuristic
exo: "font-exo",
orbitron: "font-orbitron",
audiowide: "font-audiowide",
rajdhani: "font-rajdhani",
spacemono: "font-space-mono",
questrial: "font-questrial",
syncopate: "font-syncopate",
unicaone: "font-unica-one",
italiana: "font-italiana",
staatliches: "font-staatliches",
// Futuristische Schriftarten
export const exo = Exo({
subsets: ["latin"],
weight: ["100", "200", "300", "400", "500", "600", "700", "800", "900"],
variable: "--font-exo",
});
export const orbitron = Orbitron({
subsets: ["latin"],
weight: ["400", "500", "600", "700", "800", "900"],
variable: "--font-orbitron",
});
export const audiowide = Audiowide({
subsets: ["latin"],
weight: "400",
variable: "--font-audiowide",
});
export const rajdhani = Rajdhani({
subsets: ["latin"],
weight: ["300", "400", "500", "600", "700"],
variable: "--font-rajdhani",
});
export const spaceMono = Space_Mono({
subsets: ["latin"],
weight: ["400", "700"],
variable: "--font-space-mono",
});
export const questrial = Questrial({
subsets: ["latin"],
weight: "400",
variable: "--font-questrial",
});
export const syncopate = Syncopate({
subsets: ["latin"],
weight: "400",
variable: "--font-syncopate",
});
export const unicaOne = Unica_One({
subsets: ["latin"],
weight: "400",
variable: "--font-unica-one",
});
export const italiana = Italiana({
subsets: ["latin"],
weight: "400",
variable: "--font-italiana",
});
export const staatliches = Staatliches({
subsets: ["latin"],
weight: "400",
variable: "--font-staatliches",
});
// 🧢 Aesthetic
pressstart2p: "font-press-start-2p",
righteous: "font-righteous",
metalmania: "font-metal-mania",
alegreya: "font-alegreya",
spectral: "font-spectral",
fjallaone: "font-fjalla-one",
glassantiqua: "font-glass-antiqua",
cinzeldecorative: "font-cinzel-decorative",
andika: "font-andika",
};
export const getFontData = (key) =>
fonts[key?.toLowerCase()] ?? fonts["montserrat"];
// Ästhetische Schriftarten
export const pressStart2p = Press_Start_2P({
subsets: ["latin"],
weight: "400",
variable: "--font-press-start-2p",
});
export const righteous = Righteous({
subsets: ["latin"],
weight: "400",
variable: "--font-righteous",
});
export const metalMania = Metal_Mania({
subsets: ["latin"],
weight: "400",
variable: "--font-metal-mania",
});
export const alegreya = Alegreya({
subsets: ["latin"],
weight: ["400", "500", "600", "700", "800", "900"],
variable: "--font-alegreya",
});
export const spectral = Spectral({
subsets: ["latin"],
weight: ["200", "300", "400", "500", "600", "700", "800"],
variable: "--font-spectral",
});
export const fjallaOne = Fjalla_One({
subsets: ["latin"],
weight: "400",
variable: "--font-fjalla-one",
});
export const glassAntiqua = Glass_Antiqua({
subsets: ["latin"],
weight: "400",
variable: "--font-glass-antiqua",
});
export const cinzelDecorative = Cinzel_Decorative({
subsets: ["latin"],
weight: "400",
variable: "--font-cinzel-decorative",
});
export const andika = Andika({
subsets: ["latin"],
weight: "400",
variable: "--font-andika",
});

21
lib/posthog.js Normal file
View File

@ -0,0 +1,21 @@
// lib/posthog.ts
import { PostHog } from "posthog-node";
export function PostHogClient() {
// Server-Keys verwenden (ohne NEXT_PUBLIC_)
const key = 'phc_1j3wKLzEVz6QGnAZ6jg1njZP8XsAPbNDchwLGvjjc0e'//process.env.POSTHOG_API_KEY;
const host = process.env.POSTHOG_HOST ?? "https://us.i.posthog.com";
if (!key) {
// Fail fast sonst sendest du stumm nichts
throw new Error("POSTHOG_API_KEY ist nicht gesetzt (serverseitige Env).");
}
const client = new PostHog(key, {
host,
flushAt: 1,
flushInterval: 0,
});
return client;
}

View File

@ -1,8 +1,12 @@
/** @type {import('next').NextConfig} */
const nextConfig = {
experimental: {
// hier können andere gültige experimentelle Optionen stehen, falls nötig
},
};
// next.config.js
const path = require('path');
const withFlowbiteReact = require('flowbite-react/plugin/nextjs');
module.exports = nextConfig;
const nextConfig = {
output: 'export',
images: { unoptimized: true },
webpack: (config) => {
config.resolve.alias['@'] = path.resolve(process.cwd());
return config;
},
};

View File

@ -3,6 +3,8 @@ import path from "path";
import withFlowbiteReact from "flowbite-react/plugin/nextjs";
const nextConfig = {
output: "export",
images: { unoptimized: true },
webpack: (config) => {
config.resolve.alias["@"] = path.resolve(process.cwd());
return config;

77
package-lock.json generated
View File

@ -15,6 +15,8 @@
"html2canvas": "^1.4.1",
"lucide-react": "^0.292.0",
"next": "^14.0.4",
"posthog-js": "^1.259.0",
"posthog-node": "^5.6.0",
"react": "^18.2.0",
"react-dom": "^18.2.0",
"react-helmet": "^6.1.0",
@ -578,6 +580,12 @@
"url": "https://opencollective.com/popperjs"
}
},
"node_modules/@posthog/core": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/@posthog/core/-/core-1.0.0.tgz",
"integrity": "sha512-gquQld+duT9DdzLIFoHZkUMW0DZOTSLCtSjuuC/zKFz65Qecbz9p37DHBJMkw0dCuB8Mgh2GtH8Ag3PznJrP3g==",
"license": "MIT"
},
"node_modules/@rollup/plugin-node-resolve": {
"version": "15.3.1",
"resolved": "https://registry.npmjs.org/@rollup/plugin-node-resolve/-/plugin-node-resolve-15.3.1.tgz",
@ -1906,6 +1914,17 @@
"dev": true,
"license": "MIT"
},
"node_modules/core-js": {
"version": "3.45.0",
"resolved": "https://registry.npmjs.org/core-js/-/core-js-3.45.0.tgz",
"integrity": "sha512-c2KZL9lP4DjkN3hk/an4pWn5b5ZefhRJnAc42n6LJ19kSnbeRbdQZE5dSeE2LBol1OwJD3X1BQvFTAsa8ReeDA==",
"hasInstallScript": true,
"license": "MIT",
"funding": {
"type": "opencollective",
"url": "https://opencollective.com/core-js"
}
},
"node_modules/core-util-is": {
"version": "1.0.3",
"resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.3.tgz",
@ -2903,6 +2922,12 @@
}
}
},
"node_modules/fflate": {
"version": "0.4.8",
"resolved": "https://registry.npmjs.org/fflate/-/fflate-0.4.8.tgz",
"integrity": "sha512-FJqqoDBR00Mdj9ppamLa/Y7vxm+PRmNWA67N846RvsoYVMKB4q3y/de5PA7gUmRMYK/8CMz2GDZQmCRN1wBcWA==",
"license": "MIT"
},
"node_modules/file-entry-cache": {
"version": "6.0.1",
"resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-6.0.1.tgz",
@ -4985,6 +5010,52 @@
"integrity": "sha512-1NNCs6uurfkVbeXG4S8JFT9t19m45ICnif8zWLd5oPSZ50QnwMfK+H3jv408d4jw/7Bttv5axS5IiHoLaVNHeQ==",
"license": "MIT"
},
"node_modules/posthog-js": {
"version": "1.260.1",
"resolved": "https://registry.npmjs.org/posthog-js/-/posthog-js-1.260.1.tgz",
"integrity": "sha512-DD8ZSRpdScacMqtqUIvMFme8lmOWkOvExG8VvjONE7Cm3xpRH5xXpfrwMJE4bayTGWKMx4ij6SfphK6dm/o2ug==",
"license": "SEE LICENSE IN LICENSE",
"dependencies": {
"core-js": "^3.38.1",
"fflate": "^0.4.8",
"preact": "^10.19.3",
"web-vitals": "^4.2.4"
},
"peerDependencies": {
"@rrweb/types": "2.0.0-alpha.17",
"rrweb-snapshot": "2.0.0-alpha.17"
},
"peerDependenciesMeta": {
"@rrweb/types": {
"optional": true
},
"rrweb-snapshot": {
"optional": true
}
}
},
"node_modules/posthog-node": {
"version": "5.7.0",
"resolved": "https://registry.npmjs.org/posthog-node/-/posthog-node-5.7.0.tgz",
"integrity": "sha512-6J1AIZWtbr2lEbZOO2AzO/h1FPJjUZM4KWcdaL2UQw7FY8J7VNaH3NiaRockASFmglpID7zEY25gV/YwCtuXjg==",
"license": "MIT",
"dependencies": {
"@posthog/core": "1.0.0"
},
"engines": {
"node": ">=20"
}
},
"node_modules/preact": {
"version": "10.27.0",
"resolved": "https://registry.npmjs.org/preact/-/preact-10.27.0.tgz",
"integrity": "sha512-/DTYoB6mwwgPytiqQTh/7SFRL98ZdiD8Sk8zIUVOxtwq4oWcwrcd1uno9fE/zZmUaUrFNYzbH14CPebOz9tZQw==",
"license": "MIT",
"funding": {
"type": "opencollective",
"url": "https://opencollective.com/preact"
}
},
"node_modules/prelude-ls": {
"version": "1.2.1",
"resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.2.1.tgz",
@ -6402,6 +6473,12 @@
"base64-arraybuffer": "^1.0.2"
}
},
"node_modules/web-vitals": {
"version": "4.2.4",
"resolved": "https://registry.npmjs.org/web-vitals/-/web-vitals-4.2.4.tgz",
"integrity": "sha512-r4DIlprAGwJ7YM11VZp4R884m0Vmgr6EAKe3P+kO0PPj3Unqyvv59rczf6UiGcb9Z8QxZVcqKNwv/g0WNdWwsw==",
"license": "Apache-2.0"
},
"node_modules/webfontloader": {
"version": "1.6.28",
"resolved": "https://registry.npmjs.org/webfontloader/-/webfontloader-1.6.28.tgz",

View File

@ -20,6 +20,8 @@
"html2canvas": "^1.4.1",
"lucide-react": "^0.292.0",
"next": "^14.0.4",
"posthog-js": "^1.259.0",
"posthog-node": "^5.6.0",
"react": "^18.2.0",
"react-dom": "^18.2.0",
"react-helmet": "^6.1.0",

View File

@ -1,18 +1,75 @@
// pages/_app.jsx
import "@/styles/tailwind.build.css"; // dein TailwindBuild
import { fonts } from "@/lib/fonts";
import "../styles/local-fonts.css";
// pages/app.js
import "@/styles/tailwind.build.css";
import "../styles/globals.css";
// CSS-Variablen für alle Fonts aus next/font/google
const allFontVars = Object.values(fonts)
.filter((f) => f?.variable)
.map((f) => f.variable)
.join(" ");
// Alle exportierten Schriftarten aus lib/fonts.js importieren
import {
montserrat,
lato,
raleway,
poppins,
openSans,
roboto,
workSans,
notoSans,
jost,
quicksand,
averiaLibre,
philosopher,
pacifico,
sacramento,
caveat,
dancingScript,
indieFlower,
amatic,
kaushan,
architects,
neucha,
greatVibes,
satisfy,
yellowtail,
gloria,
courgette,
almendra,
oswald,
bebasNeue,
ultra,
stint,
playfair,
abril,
permanentMarker,
alfaSlab,
blackOps,
germania,
holtwood,
exo,
orbitron,
audiowide,
rajdhani,
spaceMono,
questrial,
syncopate,
unicaOne,
italiana,
staatliches,
pressStart2p,
righteous,
metalMania,
alegreya,
spectral,
fjallaOne,
glassAntiqua,
cinzelDecorative,
andika,
} from "@/lib/fonts";
export default function MyApp({ Component, pageProps }) {
// Die Variablennamen aller Schriftarten in einer Klasse zusammenfassen
const fontVariables = `${montserrat.variable} ${lato.variable} ${raleway.variable} ${poppins.variable} ${openSans.variable} ${roboto.variable} ${workSans.variable} ${notoSans.variable} ${jost.variable} ${quicksand.variable} ${averiaLibre.variable} ${philosopher.variable} ${pacifico.variable} ${sacramento.variable} ${caveat.variable} ${dancingScript.variable} ${indieFlower.variable} ${amatic.variable} ${kaushan.variable} ${architects.variable} ${neucha.variable} ${greatVibes.variable} ${satisfy.variable} ${yellowtail.variable} ${gloria.variable} ${courgette.variable} ${almendra.variable} ${oswald.variable} ${bebasNeue.variable} ${ultra.variable} ${stint.variable} ${playfair.variable} ${abril.variable} ${permanentMarker.variable} ${alfaSlab.variable} ${blackOps.variable} ${germania.variable} ${holtwood.variable} ${exo.variable} ${orbitron.variable} ${audiowide.variable} ${rajdhani.variable} ${spaceMono.variable} ${questrial.variable} ${syncopate.variable} ${unicaOne.variable} ${italiana.variable} ${staatliches.variable} ${pressStart2p.variable} ${righteous.variable} ${metalMania.variable} ${alegreya.variable} ${spectral.variable} ${fjallaOne.variable} ${glassAntiqua.variable} ${cinzelDecorative.variable} ${andika.variable}`;
return (
<main className={allFontVars}>
<div className={fontVariables}>
<Component {...pageProps} />
</main>
</div>
);
}

23
pages/api/track.js Normal file
View File

@ -0,0 +1,23 @@
// pages/api/track.js
import { PostHogClient } from "@/lib/posthog";
export default async function handler(req, res) {
const posthog = PostHogClient();
try {
const { event, properties, distinctId } = req.body;
await posthog.capture({
distinctId: distinctId || "server_event",
event: event || "default_event",
properties: properties || {},
});
await posthog.shutdown();
return res.status(200).json({ success: true });
} catch (error) {
console.error("PostHog error:", error);
return res.status(500).json({ success: false, error: error.message });
}
}

Some files were not shown because too many files have changed in this diff Show More