perf: cut CI time, fix CSS chain, fix iPad hero layout, fix contrast
CI: - Replace `npm run build` with `tsc --noEmit` in test-build job → eliminates duplicate Next.js build (~5 min saved per push) → Docker deploy job already does the full build PageSpeed: - Add `cssChunking: 'loose'` to merge CSS into one chunk and break the 84dc7384→3aefc04b render-blocking CSS waterfall chain (450ms mobile) - Remove @shadergradient/react, @react-three/fiber, three from package.json — packages were already unused in code, removes any residual bundling risk for chunk 7001 Hero: - Change lg:flex-row → xl:flex-row so iPad (1024px) stays in column layout; the 9.5rem heading overflowed into the image at lg causing the photo to be clipped by overflow-hidden on the section - Update image sizes attribute to match new xl breakpoint - Fix contrast: "GET IN TOUCH" link text-stone-500 → text-stone-700 (contrast 3.7:1 → 7:1, now WCAG AA compliant) - Change text-center/justify-center to xl: variants to match layout Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -33,8 +33,8 @@ jobs:
|
||||
- name: Test
|
||||
run: npm run test
|
||||
|
||||
- name: Build
|
||||
run: npm run build
|
||||
- name: Type check
|
||||
run: npx tsc --noEmit
|
||||
|
||||
# ── Job 2: Deploy to dev (only on dev branch, after tests pass) ──
|
||||
deploy-dev:
|
||||
|
||||
@@ -23,10 +23,10 @@ export default async function Hero({ locale }: HeroProps) {
|
||||
</div>
|
||||
|
||||
<div className="relative z-10 max-w-7xl mx-auto w-full pt-12 sm:pt-16 md:pt-20">
|
||||
<div className="flex flex-col lg:flex-row items-center gap-8 sm:gap-10 lg:gap-24">
|
||||
<div className="flex flex-col xl:flex-row items-center gap-8 sm:gap-10 xl:gap-24">
|
||||
|
||||
{/* Left: Text Content */}
|
||||
<div className="flex-1 text-center lg:text-left space-y-6 sm:space-y-8 md:space-y-10">
|
||||
<div className="flex-1 text-center xl:text-left space-y-6 sm:space-y-8 md:space-y-10">
|
||||
<div className="inline-flex items-center gap-2 sm:gap-3 px-4 sm:px-5 py-2 sm:py-2.5 rounded-full bg-white dark:bg-stone-900 border border-stone-200 dark:border-stone-800 shadow-sm animate-[fadeIn_0.5s_ease-out]">
|
||||
<span className="w-2 h-2 sm:w-2.5 sm:h-2.5 bg-emerald-500 rounded-full animate-pulse" />
|
||||
<span className="font-mono text-[10px] sm:text-[11px] font-black uppercase tracking-[0.2em] sm:tracking-[0.3em] text-stone-500">{getLabel("hero.badge", "Student & Self-Hoster")}</span>
|
||||
@@ -41,26 +41,26 @@ export default async function Hero({ locale }: HeroProps) {
|
||||
</span>
|
||||
</h1>
|
||||
|
||||
<p className="text-base sm:text-lg md:text-xl lg:text-2xl text-stone-600 dark:text-stone-400 max-w-xl mx-auto lg:mx-0 font-light leading-relaxed tracking-tight">
|
||||
<p className="text-base sm:text-lg md:text-xl lg:text-2xl text-stone-600 dark:text-stone-400 max-w-xl mx-auto xl:mx-0 font-light leading-relaxed tracking-tight">
|
||||
{t("description")}
|
||||
</p>
|
||||
|
||||
<div className="flex flex-col sm:flex-row items-center gap-4 sm:gap-8 justify-center lg:justify-start pt-2 sm:pt-4 animate-[fadeIn_0.6s_ease-out_0.3s_both]">
|
||||
<div className="flex flex-col sm:flex-row items-center gap-4 sm:gap-8 justify-center xl:justify-start pt-2 sm:pt-4 animate-[fadeIn_0.6s_ease-out_0.3s_both]">
|
||||
<a href="#projects" className="group relative px-8 sm:px-12 py-4 sm:py-5 bg-stone-900 dark:bg-stone-50 text-white dark:text-stone-900 rounded-2xl sm:rounded-3xl font-black text-xs uppercase tracking-[0.2em] hover:scale-105 active:scale-95 transition-all shadow-2xl">
|
||||
<div className="absolute inset-0 bg-white/10 -translate-x-full group-hover:translate-x-full transition-transform duration-1000" />
|
||||
{t("ctaWork")}
|
||||
</a>
|
||||
<a href="#contact" className="font-black text-xs uppercase tracking-[0.2em] text-stone-500 hover:text-stone-900 dark:hover:text-white transition-colors">
|
||||
<a href="#contact" className="font-black text-xs uppercase tracking-[0.2em] text-stone-700 dark:text-stone-300 hover:text-stone-900 dark:hover:text-white transition-colors">
|
||||
{t("ctaContact")}
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{/* Right: The Photo */}
|
||||
<div className="relative w-52 h-52 sm:w-64 sm:h-64 md:w-80 md:h-80 lg:w-[500px] lg:h-[500px] shrink-0 mt-4 sm:mt-8 lg:mt-0 animate-[fadeIn_1s_ease-out]">
|
||||
<div className="relative w-52 h-52 sm:w-64 sm:h-64 md:w-80 md:h-80 xl:w-[500px] xl:h-[500px] shrink-0 mt-4 sm:mt-8 xl:mt-0 animate-[fadeIn_1s_ease-out]">
|
||||
<div className="absolute inset-0 bg-gradient-to-tr from-liquid-mint to-liquid-purple rounded-[3rem] sm:rounded-[4rem] lg:rounded-[5rem] rotate-12 scale-90 opacity-20 blur-3xl" />
|
||||
<div className="relative w-full h-full rounded-[2.5rem] sm:rounded-[3rem] lg:rounded-[4rem] overflow-hidden border-[12px] sm:border-[16px] lg:border-[24px] border-white dark:border-stone-900 shadow-[0_30px_60px_-15px_rgba(0,0,0,0.3)] sm:shadow-[0_50px_100px_-20px_rgba(0,0,0,0.4)]">
|
||||
<Image src="/images/me.jpg" alt="Dennis Konkol" fill className="object-cover" priority sizes="(max-width: 640px) 208px, (max-width: 768px) 256px, (max-width: 1024px) 320px, 500px" />
|
||||
<Image src="/images/me.jpg" alt="Dennis Konkol" fill className="object-cover" priority sizes="(max-width: 640px) 208px, (max-width: 768px) 256px, (max-width: 1280px) 320px, 500px" />
|
||||
</div>
|
||||
|
||||
<div className="absolute -bottom-4 -left-4 sm:-bottom-6 sm:-left-6 bg-white dark:bg-stone-800 px-5 py-3 sm:px-8 sm:py-4 rounded-xl sm:rounded-[2rem] shadow-2xl border border-stone-100 dark:border-stone-700">
|
||||
|
||||
@@ -34,10 +34,12 @@ const nextConfig: NextConfig = {
|
||||
experimental: {
|
||||
// Tree-shake barrel-file packages in both dev and production
|
||||
optimizePackageImports: ["lucide-react", "framer-motion", "react-icons", "@tiptap/react"],
|
||||
// Merge all CSS into a single chunk to eliminate the render-blocking CSS chain
|
||||
// (84dc7384.css → 3aefc04b.css sequential dependency reported by PageSpeed).
|
||||
cssChunking: "loose",
|
||||
// Note: optimizeCss (critters) is intentionally disabled — it converts the main
|
||||
// <link rel="stylesheet"> to a JS-deferred preload, which PageSpeed reads as a
|
||||
// sequential CSS chain and reports 410ms of render-blocking. Without it both CSS
|
||||
// files load as parallel <link> tags discovered from the initial HTML (~150ms total).
|
||||
// sequential CSS chain and reports 410ms of render-blocking.
|
||||
...(process.env.NODE_ENV !== "production" ? { webpackBuildWorker: true } : {}),
|
||||
},
|
||||
|
||||
|
||||
214
package-lock.json
generated
214
package-lock.json
generated
@@ -10,8 +10,6 @@
|
||||
"dependencies": {
|
||||
"@next/bundle-analyzer": "^15.1.7",
|
||||
"@prisma/client": "^5.22.0",
|
||||
"@react-three/fiber": "^9.5.0",
|
||||
"@shadergradient/react": "^2.4.20",
|
||||
"@swc/helpers": "^0.5.19",
|
||||
"@tiptap/extension-color": "^3.15.3",
|
||||
"@tiptap/extension-highlight": "^3.15.3",
|
||||
@@ -38,8 +36,7 @@
|
||||
"react-markdown": "^10.1.0",
|
||||
"redis": "^5.8.2",
|
||||
"sanitize-html": "^2.17.0",
|
||||
"tailwind-merge": "^2.6.0",
|
||||
"three": "^0.183.1"
|
||||
"tailwind-merge": "^2.6.0"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@eslint/eslintrc": "^3",
|
||||
@@ -538,6 +535,7 @@
|
||||
"version": "7.28.6",
|
||||
"resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.28.6.tgz",
|
||||
"integrity": "sha512-05WQkdpL9COIMz4LjTxGpPNCdlpyimKppYNoJ5Di5EUObifl8t4tuLuUBBZEpoLYOmfvIWrsp9fCl0HoPRVTdA==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"engines": {
|
||||
"node": ">=6.9.0"
|
||||
@@ -2998,54 +2996,6 @@
|
||||
"@prisma/debug": "5.22.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@react-three/fiber": {
|
||||
"version": "9.5.0",
|
||||
"resolved": "https://registry.npmjs.org/@react-three/fiber/-/fiber-9.5.0.tgz",
|
||||
"integrity": "sha512-FiUzfYW4wB1+PpmsE47UM+mCads7j2+giRBltfwH7SNhah95rqJs3ltEs9V3pP8rYdS0QlNne+9Aj8dS/SiaIA==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@babel/runtime": "^7.17.8",
|
||||
"@types/webxr": "*",
|
||||
"base64-js": "^1.5.1",
|
||||
"buffer": "^6.0.3",
|
||||
"its-fine": "^2.0.0",
|
||||
"react-use-measure": "^2.1.7",
|
||||
"scheduler": "^0.27.0",
|
||||
"suspend-react": "^0.1.3",
|
||||
"use-sync-external-store": "^1.4.0",
|
||||
"zustand": "^5.0.3"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"expo": ">=43.0",
|
||||
"expo-asset": ">=8.4",
|
||||
"expo-file-system": ">=11.0",
|
||||
"expo-gl": ">=11.0",
|
||||
"react": ">=19 <19.3",
|
||||
"react-dom": ">=19 <19.3",
|
||||
"react-native": ">=0.78",
|
||||
"three": ">=0.156"
|
||||
},
|
||||
"peerDependenciesMeta": {
|
||||
"expo": {
|
||||
"optional": true
|
||||
},
|
||||
"expo-asset": {
|
||||
"optional": true
|
||||
},
|
||||
"expo-file-system": {
|
||||
"optional": true
|
||||
},
|
||||
"expo-gl": {
|
||||
"optional": true
|
||||
},
|
||||
"react-dom": {
|
||||
"optional": true
|
||||
},
|
||||
"react-native": {
|
||||
"optional": true
|
||||
}
|
||||
}
|
||||
},
|
||||
"node_modules/@redis/bloom": {
|
||||
"version": "5.10.0",
|
||||
"resolved": "https://registry.npmjs.org/@redis/bloom/-/bloom-5.10.0.tgz",
|
||||
@@ -3141,16 +3091,6 @@
|
||||
"integrity": "sha512-bXHSaW5jRTmke9Vd0h5P7BtWZG9Znqb8gSDxZnxaGSJnGwPLDPfS+3g0BKzeWqzgZPsIVZkM7m2tbo18cm5HBw==",
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/@shadergradient/react": {
|
||||
"version": "2.4.20",
|
||||
"resolved": "https://registry.npmjs.org/@shadergradient/react/-/react-2.4.20.tgz",
|
||||
"integrity": "sha512-MVYvYgTHK3d36C2jNKzt4OzWeyNyc/bWI0zKRyv5EgI2hmUee8nD0cmuNX9X1lw1RCcuof6n1Rnj63jWepZHJA==",
|
||||
"license": "MIT",
|
||||
"peerDependencies": {
|
||||
"react": "^18.2.0 || ^19.0.0",
|
||||
"react-dom": "^18.2.0 || ^19.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@shuding/opentype.js": {
|
||||
"version": "1.4.0-beta.0",
|
||||
"resolved": "https://registry.npmjs.org/@shuding/opentype.js/-/opentype.js-1.4.0-beta.0.tgz",
|
||||
@@ -4275,15 +4215,6 @@
|
||||
"@types/react": "^19.2.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@types/react-reconciler": {
|
||||
"version": "0.28.9",
|
||||
"resolved": "https://registry.npmjs.org/@types/react-reconciler/-/react-reconciler-0.28.9.tgz",
|
||||
"integrity": "sha512-HHM3nxyUZ3zAylX8ZEyrDNd2XZOnQ0D5XfunJF5FLQnZbHHYq4UWvW1QfelQNXv1ICNkwYhfxjwfnqivYB6bFg==",
|
||||
"license": "MIT",
|
||||
"peerDependencies": {
|
||||
"@types/react": "*"
|
||||
}
|
||||
},
|
||||
"node_modules/@types/sanitize-html": {
|
||||
"version": "2.16.0",
|
||||
"resolved": "https://registry.npmjs.org/@types/sanitize-html/-/sanitize-html-2.16.0.tgz",
|
||||
@@ -4320,12 +4251,6 @@
|
||||
"integrity": "sha512-zFDAD+tlpf2r4asuHEj0XH6pY6i0g5NeAHPn+15wk3BV6JA69eERFXC1gyGThDkVa1zCyKr5jox1+2LbV/AMLg==",
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/@types/webxr": {
|
||||
"version": "0.5.24",
|
||||
"resolved": "https://registry.npmjs.org/@types/webxr/-/webxr-0.5.24.tgz",
|
||||
"integrity": "sha512-h8fgEd/DpoS9CBrjEQXR+dIDraopAEfu4wYVNY2tEPwk60stPWhvZMf4Foo5FakuQ7HFZoa8WceaWFervK2Ovg==",
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/@types/whatwg-mimetype": {
|
||||
"version": "3.0.2",
|
||||
"resolved": "https://registry.npmjs.org/@types/whatwg-mimetype/-/whatwg-mimetype-3.0.2.tgz",
|
||||
@@ -5490,26 +5415,6 @@
|
||||
"dev": true,
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/base64-js": {
|
||||
"version": "1.5.1",
|
||||
"resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.5.1.tgz",
|
||||
"integrity": "sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==",
|
||||
"funding": [
|
||||
{
|
||||
"type": "github",
|
||||
"url": "https://github.com/sponsors/feross"
|
||||
},
|
||||
{
|
||||
"type": "patreon",
|
||||
"url": "https://www.patreon.com/feross"
|
||||
},
|
||||
{
|
||||
"type": "consulting",
|
||||
"url": "https://feross.org/support"
|
||||
}
|
||||
],
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/baseline-browser-mapping": {
|
||||
"version": "2.9.19",
|
||||
"resolved": "https://registry.npmjs.org/baseline-browser-mapping/-/baseline-browser-mapping-2.9.19.tgz",
|
||||
@@ -5621,30 +5526,6 @@
|
||||
"node-int64": "^0.4.0"
|
||||
}
|
||||
},
|
||||
"node_modules/buffer": {
|
||||
"version": "6.0.3",
|
||||
"resolved": "https://registry.npmjs.org/buffer/-/buffer-6.0.3.tgz",
|
||||
"integrity": "sha512-FTiCpNxtwiZZHEZbcbTIcZjERVICn9yq/pDFkTl95/AxzD1naBctN7YO68riM/gLSDY7sdrMby8hofADYuuqOA==",
|
||||
"funding": [
|
||||
{
|
||||
"type": "github",
|
||||
"url": "https://github.com/sponsors/feross"
|
||||
},
|
||||
{
|
||||
"type": "patreon",
|
||||
"url": "https://www.patreon.com/feross"
|
||||
},
|
||||
{
|
||||
"type": "consulting",
|
||||
"url": "https://feross.org/support"
|
||||
}
|
||||
],
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"base64-js": "^1.3.1",
|
||||
"ieee754": "^1.2.1"
|
||||
}
|
||||
},
|
||||
"node_modules/buffer-from": {
|
||||
"version": "1.1.2",
|
||||
"resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.2.tgz",
|
||||
@@ -8322,26 +8203,6 @@
|
||||
"@formatjs/icu-messageformat-parser": "^3.4.0"
|
||||
}
|
||||
},
|
||||
"node_modules/ieee754": {
|
||||
"version": "1.2.1",
|
||||
"resolved": "https://registry.npmjs.org/ieee754/-/ieee754-1.2.1.tgz",
|
||||
"integrity": "sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA==",
|
||||
"funding": [
|
||||
{
|
||||
"type": "github",
|
||||
"url": "https://github.com/sponsors/feross"
|
||||
},
|
||||
{
|
||||
"type": "patreon",
|
||||
"url": "https://www.patreon.com/feross"
|
||||
},
|
||||
{
|
||||
"type": "consulting",
|
||||
"url": "https://feross.org/support"
|
||||
}
|
||||
],
|
||||
"license": "BSD-3-Clause"
|
||||
},
|
||||
"node_modules/ignore": {
|
||||
"version": "5.3.2",
|
||||
"resolved": "https://registry.npmjs.org/ignore/-/ignore-5.3.2.tgz",
|
||||
@@ -9115,18 +8976,6 @@
|
||||
"node": ">= 0.4"
|
||||
}
|
||||
},
|
||||
"node_modules/its-fine": {
|
||||
"version": "2.0.0",
|
||||
"resolved": "https://registry.npmjs.org/its-fine/-/its-fine-2.0.0.tgz",
|
||||
"integrity": "sha512-KLViCmWx94zOvpLwSlsx6yOCeMhZYaxrJV87Po5k/FoZzcPSahvK5qJ7fYhS61sZi5ikmh2S3Hz55A2l3U69ng==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@types/react-reconciler": "^0.28.9"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"react": "^19.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/jest": {
|
||||
"version": "29.7.0",
|
||||
"resolved": "https://registry.npmjs.org/jest/-/jest-29.7.0.tgz",
|
||||
@@ -12833,21 +12682,6 @@
|
||||
"react": ">=18"
|
||||
}
|
||||
},
|
||||
"node_modules/react-use-measure": {
|
||||
"version": "2.1.7",
|
||||
"resolved": "https://registry.npmjs.org/react-use-measure/-/react-use-measure-2.1.7.tgz",
|
||||
"integrity": "sha512-KrvcAo13I/60HpwGO5jpW7E9DfusKyLPLvuHlUyP5zqnmAPhNc6qTRjUQrdTADl0lpPpDVU2/Gg51UlOGHXbdg==",
|
||||
"license": "MIT",
|
||||
"peerDependencies": {
|
||||
"react": ">=16.13",
|
||||
"react-dom": ">=16.13"
|
||||
},
|
||||
"peerDependenciesMeta": {
|
||||
"react-dom": {
|
||||
"optional": true
|
||||
}
|
||||
}
|
||||
},
|
||||
"node_modules/read-cache": {
|
||||
"version": "1.0.0",
|
||||
"resolved": "https://registry.npmjs.org/read-cache/-/read-cache-1.0.0.tgz",
|
||||
@@ -13880,15 +13714,6 @@
|
||||
"url": "https://github.com/sponsors/ljharb"
|
||||
}
|
||||
},
|
||||
"node_modules/suspend-react": {
|
||||
"version": "0.1.3",
|
||||
"resolved": "https://registry.npmjs.org/suspend-react/-/suspend-react-0.1.3.tgz",
|
||||
"integrity": "sha512-aqldKgX9aZqpoDp3e8/BZ8Dm7x1pJl+qI3ZKxDN0i/IQTWUwBx/ManmlVJ3wowqbno6c2bmiIfs+Um6LbsjJyQ==",
|
||||
"license": "MIT",
|
||||
"peerDependencies": {
|
||||
"react": ">=17.0"
|
||||
}
|
||||
},
|
||||
"node_modules/symbol-tree": {
|
||||
"version": "3.2.4",
|
||||
"resolved": "https://registry.npmjs.org/symbol-tree/-/symbol-tree-3.2.4.tgz",
|
||||
@@ -14041,12 +13866,6 @@
|
||||
"node": ">=0.8"
|
||||
}
|
||||
},
|
||||
"node_modules/three": {
|
||||
"version": "0.183.1",
|
||||
"resolved": "https://registry.npmjs.org/three/-/three-0.183.1.tgz",
|
||||
"integrity": "sha512-Psv6bbd3d/M/01MT2zZ+VmD0Vj2dbWTNhfe4CuSg7w5TuW96M3NOyCVuh9SZQ05CpGmD7NEcJhZw4GVjhCYxfQ==",
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/tiny-inflate": {
|
||||
"version": "1.0.3",
|
||||
"resolved": "https://registry.npmjs.org/tiny-inflate/-/tiny-inflate-1.0.3.tgz",
|
||||
@@ -15261,35 +15080,6 @@
|
||||
"integrity": "sha512-N+d4UJSJbt/R3wqY7Coqs5pcV0aUj2j9IaQ3rNj9bVCLld8tTGKRa2USARjnvZJWVx1NDmQev8EknoczaOQDOA==",
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/zustand": {
|
||||
"version": "5.0.11",
|
||||
"resolved": "https://registry.npmjs.org/zustand/-/zustand-5.0.11.tgz",
|
||||
"integrity": "sha512-fdZY+dk7zn/vbWNCYmzZULHRrss0jx5pPFiOuMZ/5HJN6Yv3u+1Wswy/4MpZEkEGhtNH+pwxZB8OKgUBPzYAGg==",
|
||||
"license": "MIT",
|
||||
"engines": {
|
||||
"node": ">=12.20.0"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"@types/react": ">=18.0.0",
|
||||
"immer": ">=9.0.6",
|
||||
"react": ">=18.0.0",
|
||||
"use-sync-external-store": ">=1.2.0"
|
||||
},
|
||||
"peerDependenciesMeta": {
|
||||
"@types/react": {
|
||||
"optional": true
|
||||
},
|
||||
"immer": {
|
||||
"optional": true
|
||||
},
|
||||
"react": {
|
||||
"optional": true
|
||||
},
|
||||
"use-sync-external-store": {
|
||||
"optional": true
|
||||
}
|
||||
}
|
||||
},
|
||||
"node_modules/zwitch": {
|
||||
"version": "2.0.4",
|
||||
"resolved": "https://registry.npmjs.org/zwitch/-/zwitch-2.0.4.tgz",
|
||||
|
||||
@@ -54,8 +54,6 @@
|
||||
"dependencies": {
|
||||
"@next/bundle-analyzer": "^15.1.7",
|
||||
"@prisma/client": "^5.22.0",
|
||||
"@react-three/fiber": "^9.5.0",
|
||||
"@shadergradient/react": "^2.4.20",
|
||||
"@swc/helpers": "^0.5.19",
|
||||
"@tiptap/extension-color": "^3.15.3",
|
||||
"@tiptap/extension-highlight": "^3.15.3",
|
||||
@@ -82,8 +80,7 @@
|
||||
"react-markdown": "^10.1.0",
|
||||
"redis": "^5.8.2",
|
||||
"sanitize-html": "^2.17.0",
|
||||
"tailwind-merge": "^2.6.0",
|
||||
"three": "^0.183.1"
|
||||
"tailwind-merge": "^2.6.0"
|
||||
},
|
||||
"browserslist": [
|
||||
"chrome >= 100",
|
||||
|
||||
Reference in New Issue
Block a user