288fa63
commit 288fa63
5 files changed
+233 -223
Showing 5 changed files+233-223
▼Dockerfile
+10-3
| @@ -6,16 +6,23 @@ LABEL org.opencontainers.image.title="OpenCodeHub" \ | ||
6 | 6 | org.opencontainers.image.source="https://github.com/swadhinbiswas/OpencodeHub" \ |
7 | 7 | org.opencontainers.image.licenses="MIT" |
8 | 8 | |
9 | -# Install dependencies | |
9 | +# Install ALL dependencies (needed for build including CSS tooling) | |
10 | 10 | FROM base AS deps |
11 | 11 | RUN apt-get update && apt-get install -y python3 make g++ gcc libc6-dev && rm -rf /var/lib/apt/lists/* |
12 | 12 | COPY package.json bun.lock ./ |
13 | 13 | COPY cli/package.json ./cli/package.json |
14 | 14 | RUN for i in 1 2 3; do \ |
15 | - bun install --frozen-lockfile --production && break || \ | |
15 | + bun install --frozen-lockfile && break || \ | |
16 | 16 | (echo "bun install attempt $i failed, retrying in 10s..." && sleep 10); \ |
17 | 17 | done |
18 | 18 | |
19 | +# Install production dependencies only (for runtime image) | |
20 | +FROM base AS prod-deps | |
21 | +RUN apt-get update && apt-get install -y python3 make g++ gcc libc6-dev && rm -rf /var/lib/apt/lists/* | |
22 | +COPY package.json bun.lock ./ | |
23 | +COPY cli/package.json ./cli/package.json | |
24 | +RUN bun install --frozen-lockfile --production | |
25 | + | |
19 | 26 | # Build the application |
20 | 27 | FROM base AS builder |
21 | 28 | COPY --from=deps /app/node_modules ./node_modules |
| @@ -37,7 +44,7 @@ RUN mkdir -p /data/repositories /data/storage /data/cache /data/ssh && \ | ||
37 | 44 | |
38 | 45 | # Copy only what's needed for runtime |
39 | 46 | COPY --from=builder --chown=bun:bun /app/dist ./dist |
40 | -COPY --from=deps --chown=bun:bun /app/node_modules ./node_modules | |
47 | +COPY --from=prod-deps --chown=bun:bun /app/node_modules ./node_modules | |
41 | 48 | COPY --from=builder --chown=bun:bun /app/package.json ./ |
42 | 49 | |
43 | 50 | # Copy drizzle config and schema for migrations |
44 | 51 | |
▼astro.config.mjs
+0-4
| @@ -1,6 +1,5 @@ | ||
1 | 1 | import node from "@astrojs/node"; |
2 | 2 | import react from "@astrojs/react"; |
3 | -import tailwind from "@astrojs/tailwind"; | |
4 | 3 | import { defineConfig } from "astro/config"; |
5 | 4 | import icon from "astro-icon"; |
6 | 5 | |
| @@ -8,9 +7,6 @@ export default defineConfig({ | ||
8 | 7 | integrations: [ |
9 | 8 | react(), |
10 | 9 | icon(), |
11 | - tailwind({ | |
12 | - applyBaseStyles: false, | |
13 | - }), | |
14 | 10 | ], |
15 | 11 | output: "server", |
16 | 12 | adapter: node({ |
17 | 13 | |
▼bun.lock
+11-14
| @@ -8,7 +8,6 @@ | ||
8 | 8 | "@astrojs/check": "^0.9.6", |
9 | 9 | "@astrojs/node": "^8.3.0", |
10 | 10 | "@astrojs/react": "^3.6.0", |
11 | - "@astrojs/tailwind": "^5.1.0", | |
12 | 11 | "@astrojs/vercel": "^7.7.0", |
13 | 12 | "@aws-sdk/client-s3": "^3.948.0", |
14 | 13 | "@aws-sdk/lib-storage": "^3.972.0", |
| @@ -56,6 +55,7 @@ | ||
56 | 55 | "arctic": "^3.7.0", |
57 | 56 | "astro": "^4.11.0", |
58 | 57 | "astro-icon": "^1.1.5", |
58 | + "autoprefixer": "^10.4.19", | |
59 | 59 | "bcryptjs": "^2.4.3", |
60 | 60 | "better-sqlite3": "^11.1.2", |
61 | 61 | "bullmq": "^5.65.1", |
| @@ -93,6 +93,7 @@ | ||
93 | 93 | "pg": "^8.16.3", |
94 | 94 | "pino": "^10.1.0", |
95 | 95 | "pino-loki": "^3.0.0", |
96 | + "postcss": "~8.4.49", | |
96 | 97 | "postgres": "^3.4.7", |
97 | 98 | "prom-client": "^15.1.3", |
98 | 99 | "qrcode": "^1.5.4", |
| @@ -111,6 +112,7 @@ | ||
111 | 112 | "sonner": "^2.0.7", |
112 | 113 | "ssh2": "^1.15.0", |
113 | 114 | "tailwind-merge": "^2.6.0", |
115 | + "tailwindcss": "^3.4.4", | |
114 | 116 | "tailwindcss-animate": "^1.0.7", |
115 | 117 | "three": "^0.182.0", |
116 | 118 | "unified": "^11.0.5", |
| @@ -137,11 +139,8 @@ | ||
137 | 139 | "@types/ssh2": "^1.15.0", |
138 | 140 | "@types/three": "^0.182.0", |
139 | 141 | "@vitest/coverage-v8": "^4.1.5", |
140 | - "autoprefixer": "^10.4.19", | |
141 | 142 | "drizzle-kit": "^0.31.8", |
142 | 143 | "pino-pretty": "^13.1.3", |
143 | - "postcss": "~8.4.49", | |
144 | - "tailwindcss": "^3.4.4", | |
145 | 144 | "typescript": "^5.9.3", |
146 | 145 | "vitest": "^4.1.5", |
147 | 146 | }, |
| @@ -231,8 +230,6 @@ | ||
231 | 230 | |
232 | 231 | "@astrojs/react": ["@astrojs/[email protected]", "https://registry.npmmirror.com/@astrojs/react/-/react-3.6.3.tgz", { "dependencies": { "@vitejs/plugin-react": "^4.3.3", "ultrahtml": "^1.5.3", "vite": "^5.4.10" }, "peerDependencies": { "@types/react": "^17.0.50 || ^18.0.21", "@types/react-dom": "^17.0.17 || ^18.0.6", "react": "^17.0.2 || ^18.0.0 || ^19.0.0-beta", "react-dom": "^17.0.2 || ^18.0.0 || ^19.0.0-beta" } }, "sha512-5ihLQDH5Runddug5AZYlnp/Q5T81QxhwnWJXA9rchBAdh11c6UhBbv9Kdk7b2PkXoEU70CGWBP9hSh0VCR58eA=="], |
233 | 232 | |
234 | - "@astrojs/tailwind": ["@astrojs/[email protected]", "https://registry.npmmirror.com/@astrojs/tailwind/-/tailwind-5.1.5.tgz", { "dependencies": { "autoprefixer": "^10.4.20", "postcss": "^8.5.1", "postcss-load-config": "^4.0.2" }, "peerDependencies": { "astro": "^3.0.0 || ^4.0.0 || ^5.0.0", "tailwindcss": "^3.0.24" } }, "sha512-1diguZEau7FZ9vIjzE4BwavGdhD3+JkdS8zmibl1ene+EHgIU5hI0NMgRYG3yea+Niaf7cyMwjeWeLvzq/maxg=="], | |
235 | - | |
236 | 233 | "@astrojs/telemetry": ["@astrojs/[email protected]", "https://registry.npmmirror.com/@astrojs/telemetry/-/telemetry-3.1.0.tgz", { "dependencies": { "ci-info": "^4.0.0", "debug": "^4.3.4", "dlv": "^1.1.3", "dset": "^3.1.3", "is-docker": "^3.0.0", "is-wsl": "^3.0.0", "which-pm-runs": "^1.1.0" } }, "sha512-/ca/+D8MIKEC8/A9cSaPUqQNZm+Es/ZinRv0ZAzvu2ios7POQSsVD+VOj7/hypWNsNM3T7RpfgNq7H2TU1KEHA=="], |
237 | 234 | |
238 | 235 | "@astrojs/vercel": ["@astrojs/[email protected]", "https://registry.npmmirror.com/@astrojs/vercel/-/vercel-7.8.2.tgz", { "dependencies": { "@astrojs/internal-helpers": "^0.4.1", "@vercel/analytics": "^1.3.1", "@vercel/edge": "^1.1.2", "@vercel/nft": "^0.27.4", "esbuild": "^0.21.5", "fast-glob": "^3.3.2", "web-vitals": "^3.5.2" }, "peerDependencies": { "astro": "^4.2.0" } }, "sha512-U2JsfN0LzFMX5CPrcb+5bAAyqyYURP6Dk/mUIXX87r5x4baQy+juU+ntvf926YA0tR7u6jPRXHymE2axQ/l3NQ=="], |
| @@ -1451,7 +1448,7 @@ | ||
1451 | 1448 | |
1452 | 1449 | "cheerio-select": ["[email protected]", "https://registry.npmmirror.com/cheerio-select/-/cheerio-select-2.1.0.tgz", { "dependencies": { "boolbase": "^1.0.0", "css-select": "^5.1.0", "css-what": "^6.1.0", "domelementtype": "^2.3.0", "domhandler": "^5.0.3", "domutils": "^3.0.1" } }, "sha512-9v9kG0LvzrlcungtnJtpGNxY+fzECQKhK4EGJX2vByejiMX84MFNQw4UxPJl3bFbTMw+Dfs37XaIkCwTZfLh4g=="], |
1453 | 1450 | |
1454 | - "chokidar": ["[email protected]", "https://registry.npmmirror.com/chokidar/-/chokidar-3.6.0.tgz", { "dependencies": { "anymatch": "~3.1.2", "braces": "~3.0.2", "glob-parent": "~5.1.2", "is-binary-path": "~2.1.0", "is-glob": "~4.0.1", "normalize-path": "~3.0.0", "readdirp": "~3.6.0" }, "optionalDependencies": { "fsevents": "~2.3.2" } }, "sha512-7VT13fmjotKpGipCW9JEQAusEPE+Ei8nl6/g4FBAmIm0GOOLMua9NDDo/DWp0ZAxCr3cPq5ZpBqmPAQgDda2Pw=="], | |
1451 | + "chokidar": ["[email protected]", "https://registry.npmmirror.com/chokidar/-/chokidar-4.0.3.tgz", { "dependencies": { "readdirp": "^4.0.1" } }, "sha512-Qgzu8kfBvo+cA4962jnP1KkS6Dop5NS6g7R5LFYJr4b8Ub94PPQXUksCw9PvXoeXPRRddRNC5C1JQUR2SMGtnA=="], | |
1455 | 1452 | |
1456 | 1453 | "chownr": ["[email protected]", "https://registry.npmmirror.com/chownr/-/chownr-1.1.4.tgz", {}, "sha512-jJ0bqzaylmJtVnNgzTeSOs8DPavpbYgEr/b0YL8/2GO3xJEhInFmhKMUnEJQjZumK7KXGFhUy89PrsJWlakBVg=="], |
1457 | 1454 | |
| @@ -2539,7 +2536,7 @@ | ||
2539 | 2536 | |
2540 | 2537 | "readable-stream": ["[email protected]", "https://registry.npmmirror.com/readable-stream/-/readable-stream-4.7.0.tgz", { "dependencies": { "abort-controller": "^3.0.0", "buffer": "^6.0.3", "events": "^3.3.0", "process": "^0.11.10", "string_decoder": "^1.3.0" } }, "sha512-oIGGmcpTLwPga8Bn6/Z75SVaH1z5dUut2ibSyAMVhmUggWpmDn2dapB0n7f8nwaSiRtepAsfJyfXIO5DCVAODg=="], |
2541 | 2538 | |
2542 | - "readdirp": ["[email protected]", "https://registry.npmmirror.com/readdirp/-/readdirp-3.6.0.tgz", { "dependencies": { "picomatch": "^2.2.1" } }, "sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA=="], | |
2539 | + "readdirp": ["[email protected]", "https://registry.npmmirror.com/readdirp/-/readdirp-4.1.2.tgz", {}, "sha512-GDhwkLfywWL2s6vEjyhri+eXmfH6j1L7JE27WhqLeYzoh/A3DBaYGEj2H/HFZCn/kMfim73FXxEJTw06WtxQwg=="], | |
2543 | 2540 | |
2544 | 2541 | "real-require": ["[email protected]", "https://registry.npmmirror.com/real-require/-/real-require-0.2.0.tgz", {}, "sha512-57frrGM/OCTLqLOAh0mhVA9VBMHd+9U7Zb2THMGdBUoZVOtGbJzjxsYGDJ3A9AYYCP4hn6y1TVbaOfzWtm5GFg=="], |
2545 | 2542 | |
| @@ -3037,8 +3034,6 @@ | ||
3037 | 3034 | |
3038 | 3035 | "@asamuzakjp/dom-selector/lru-cache": ["[email protected]", "https://registry.npmmirror.com/lru-cache/-/lru-cache-11.5.1.tgz", {}, "sha512-RPimw/7aMdv2oqRrxKwvZXcPfwBrn/JZ2xYcY9Hus/6LaS3VOAKVWKWgNLCFSiOm1ESXinjsDlidVU7JlnCN2A=="], |
3039 | 3036 | |
3040 | - "@astrojs/check/chokidar": ["[email protected]", "https://registry.npmmirror.com/chokidar/-/chokidar-4.0.3.tgz", { "dependencies": { "readdirp": "^4.0.1" } }, "sha512-Qgzu8kfBvo+cA4962jnP1KkS6Dop5NS6g7R5LFYJr4b8Ub94PPQXUksCw9PvXoeXPRRddRNC5C1JQUR2SMGtnA=="], | |
3041 | - | |
3042 | 3037 | "@astrojs/react/vite": ["[email protected]", "https://registry.npmmirror.com/vite/-/vite-5.4.21.tgz", { "dependencies": { "esbuild": "^0.21.3", "postcss": "^8.4.43", "rollup": "^4.20.0" }, "optionalDependencies": { "fsevents": "~2.3.3" }, "peerDependencies": { "@types/node": "^18.0.0 || >=20.0.0", "less": "*", "lightningcss": "^1.21.0", "sass": "*", "sass-embedded": "*", "stylus": "*", "sugarss": "*", "terser": "^5.4.0" }, "optionalPeers": ["@types/node", "less", "lightningcss", "sass", "sass-embedded", "stylus", "sugarss", "terser"], "bin": { "vite": "bin/vite.js" } }, "sha512-o5a9xKjbtuhY6Bi5S3+HvbRERmouabWbyUcpXXUA1u+GNUKoROi9byOJ8M0nHbHYHkYICiMlqxkg1KkYmm25Sw=="], |
3043 | 3038 | |
3044 | 3039 | "@astrojs/vercel/esbuild": ["[email protected]", "https://registry.npmmirror.com/esbuild/-/esbuild-0.21.5.tgz", { "optionalDependencies": { "@esbuild/aix-ppc64": "0.21.5", "@esbuild/android-arm": "0.21.5", "@esbuild/android-arm64": "0.21.5", "@esbuild/android-x64": "0.21.5", "@esbuild/darwin-arm64": "0.21.5", "@esbuild/darwin-x64": "0.21.5", "@esbuild/freebsd-arm64": "0.21.5", "@esbuild/freebsd-x64": "0.21.5", "@esbuild/linux-arm": "0.21.5", "@esbuild/linux-arm64": "0.21.5", "@esbuild/linux-ia32": "0.21.5", "@esbuild/linux-loong64": "0.21.5", "@esbuild/linux-mips64el": "0.21.5", "@esbuild/linux-ppc64": "0.21.5", "@esbuild/linux-riscv64": "0.21.5", "@esbuild/linux-s390x": "0.21.5", "@esbuild/linux-x64": "0.21.5", "@esbuild/netbsd-x64": "0.21.5", "@esbuild/openbsd-x64": "0.21.5", "@esbuild/sunos-x64": "0.21.5", "@esbuild/win32-arm64": "0.21.5", "@esbuild/win32-ia32": "0.21.5", "@esbuild/win32-x64": "0.21.5" }, "bin": { "esbuild": "bin/esbuild" } }, "sha512-mg3OPMV4hXywwpoDxu3Qda5xCKQi+vCTZq8S9J/EpkhB2HzKXq4SNFZE3+NK93JYxc8VMSep+lOUSC/RVKaBqw=="], |
| @@ -3153,8 +3148,6 @@ | ||
3153 | 3148 | |
3154 | 3149 | "cheerio/whatwg-mimetype": ["[email protected]", "https://registry.npmmirror.com/whatwg-mimetype/-/whatwg-mimetype-4.0.0.tgz", {}, "sha512-QaKxh0eNIi2mE9p2vEdzfagOKHCcj1pJ56EEHGQOVxp8r9/iszLUUV7v89x9O1p/T+NlTM5W7jW6+cz4Fq1YVg=="], |
3155 | 3150 | |
3156 | - "chokidar/glob-parent": ["[email protected]", "https://registry.npmmirror.com/glob-parent/-/glob-parent-5.1.2.tgz", { "dependencies": { "is-glob": "^4.0.1" } }, "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow=="], | |
3157 | - | |
3158 | 3151 | "cli-progress/string-width": ["[email protected]", "https://registry.npmmirror.com/string-width/-/string-width-4.2.3.tgz", { "dependencies": { "emoji-regex": "^8.0.0", "is-fullwidth-code-point": "^3.0.0", "strip-ansi": "^6.0.1" } }, "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g=="], |
3159 | 3152 | |
3160 | 3153 | "cli-table3/string-width": ["[email protected]", "https://registry.npmmirror.com/string-width/-/string-width-4.2.3.tgz", { "dependencies": { "emoji-regex": "^8.0.0", "is-fullwidth-code-point": "^3.0.0", "strip-ansi": "^6.0.1" } }, "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g=="], |
| @@ -3285,6 +3278,8 @@ | ||
3285 | 3278 | |
3286 | 3279 | "svgo/css-tree": ["[email protected]", "https://registry.npmmirror.com/css-tree/-/css-tree-2.3.1.tgz", { "dependencies": { "mdn-data": "2.0.30", "source-map-js": "^1.0.1" } }, "sha512-6Fv1DV/TYw//QF5IzQdqsNDjx/wc8TrMBZsqjL9eW01tWb7R7k/mq+/VXfJCl7SoD5emsJop9cOByJZfs8hYIw=="], |
3287 | 3280 | |
3281 | + "tailwindcss/chokidar": ["[email protected]", "https://registry.npmmirror.com/chokidar/-/chokidar-3.6.0.tgz", { "dependencies": { "anymatch": "~3.1.2", "braces": "~3.0.2", "glob-parent": "~5.1.2", "is-binary-path": "~2.1.0", "is-glob": "~4.0.1", "normalize-path": "~3.0.0", "readdirp": "~3.6.0" }, "optionalDependencies": { "fsevents": "~2.3.2" } }, "sha512-7VT13fmjotKpGipCW9JEQAusEPE+Ei8nl6/g4FBAmIm0GOOLMua9NDDo/DWp0ZAxCr3cPq5ZpBqmPAQgDda2Pw=="], | |
3282 | + | |
3288 | 3283 | "tailwindcss/postcss-selector-parser": ["[email protected]", "https://registry.npmmirror.com/postcss-selector-parser/-/postcss-selector-parser-6.1.2.tgz", { "dependencies": { "cssesc": "^3.0.0", "util-deprecate": "^1.0.2" } }, "sha512-Q8qQfPiZ+THO/3ZrOrO0cJJKfpYCagtMUkXbnEfmgUjwXg6z/WBeOyS9APBBPCTSiDV+s4SwQGu8yFsiMRIudg=="], |
3289 | 3284 | |
3290 | 3285 | "tar/chownr": ["[email protected]", "https://registry.npmmirror.com/chownr/-/chownr-3.0.0.tgz", {}, "sha512-+IxzY9BZOQd/XuYPRmrvEVjF/nqj5kgT4kEq7VofrDoM1MxoRjEWkrCC3EtLi59TVawxTAn+orJwFQcrqEN1+g=="], |
| @@ -3313,8 +3308,6 @@ | ||
3313 | 3308 | |
3314 | 3309 | "yargs/string-width": ["[email protected]", "https://registry.npmmirror.com/string-width/-/string-width-4.2.3.tgz", { "dependencies": { "emoji-regex": "^8.0.0", "is-fullwidth-code-point": "^3.0.0", "strip-ansi": "^6.0.1" } }, "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g=="], |
3315 | 3310 | |
3316 | - "@astrojs/check/chokidar/readdirp": ["[email protected]", "https://registry.npmmirror.com/readdirp/-/readdirp-4.1.2.tgz", {}, "sha512-GDhwkLfywWL2s6vEjyhri+eXmfH6j1L7JE27WhqLeYzoh/A3DBaYGEj2H/HFZCn/kMfim73FXxEJTw06WtxQwg=="], | |
3317 | - | |
3318 | 3311 | "@astrojs/react/vite/esbuild": ["[email protected]", "https://registry.npmmirror.com/esbuild/-/esbuild-0.21.5.tgz", { "optionalDependencies": { "@esbuild/aix-ppc64": "0.21.5", "@esbuild/android-arm": "0.21.5", "@esbuild/android-arm64": "0.21.5", "@esbuild/android-x64": "0.21.5", "@esbuild/darwin-arm64": "0.21.5", "@esbuild/darwin-x64": "0.21.5", "@esbuild/freebsd-arm64": "0.21.5", "@esbuild/freebsd-x64": "0.21.5", "@esbuild/linux-arm": "0.21.5", "@esbuild/linux-arm64": "0.21.5", "@esbuild/linux-ia32": "0.21.5", "@esbuild/linux-loong64": "0.21.5", "@esbuild/linux-mips64el": "0.21.5", "@esbuild/linux-ppc64": "0.21.5", "@esbuild/linux-riscv64": "0.21.5", "@esbuild/linux-s390x": "0.21.5", "@esbuild/linux-x64": "0.21.5", "@esbuild/netbsd-x64": "0.21.5", "@esbuild/openbsd-x64": "0.21.5", "@esbuild/sunos-x64": "0.21.5", "@esbuild/win32-arm64": "0.21.5", "@esbuild/win32-ia32": "0.21.5", "@esbuild/win32-x64": "0.21.5" }, "bin": { "esbuild": "bin/esbuild" } }, "sha512-mg3OPMV4hXywwpoDxu3Qda5xCKQi+vCTZq8S9J/EpkhB2HzKXq4SNFZE3+NK93JYxc8VMSep+lOUSC/RVKaBqw=="], |
3319 | 3312 | |
3320 | 3313 | "@astrojs/vercel/esbuild/@esbuild/aix-ppc64": ["@esbuild/[email protected]", "https://registry.npmmirror.com/@esbuild/aix-ppc64/-/aix-ppc64-0.21.5.tgz", { "os": "aix", "cpu": "ppc64" }, "sha512-1SDgH6ZSPTlggy1yI6+Dbkiz8xzpHJEVAlF/AM1tHPLsf5STom9rwtjE4hKAF20FfXXNTFqEYXyJNWh1GiZedQ=="], |
| @@ -3549,6 +3542,10 @@ | ||
3549 | 3542 | |
3550 | 3543 | "svgo/css-tree/mdn-data": ["[email protected]", "https://registry.npmmirror.com/mdn-data/-/mdn-data-2.0.30.tgz", {}, "sha512-GaqWWShW4kv/G9IEucWScBx9G1/vsFZZJUO+tD26M8J8z3Kw5RDQjaoZe03YAClgeS/SWPOcb4nkFBTEi5DUEA=="], |
3551 | 3544 | |
3545 | + "tailwindcss/chokidar/glob-parent": ["[email protected]", "https://registry.npmmirror.com/glob-parent/-/glob-parent-5.1.2.tgz", { "dependencies": { "is-glob": "^4.0.1" } }, "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow=="], | |
3546 | + | |
3547 | + "tailwindcss/chokidar/readdirp": ["[email protected]", "https://registry.npmmirror.com/readdirp/-/readdirp-3.6.0.tgz", { "dependencies": { "picomatch": "^2.2.1" } }, "sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA=="], | |
3548 | + | |
3552 | 3549 | "tsx/esbuild/@esbuild/aix-ppc64": ["@esbuild/[email protected]", "https://registry.npmmirror.com/@esbuild/aix-ppc64/-/aix-ppc64-0.28.0.tgz", { "os": "aix", "cpu": "ppc64" }, "sha512-lhRUCeuOyJQURhTxl4WkpFTjIsbDayJHih5kZC1giwE+MhIzAb7mEsQMqMf18rHLsrb5qI1tafG20mLxEWcWlA=="], |
3553 | 3550 | |
3554 | 3551 | "tsx/esbuild/@esbuild/android-arm": ["@esbuild/[email protected]", "https://registry.npmmirror.com/@esbuild/android-arm/-/android-arm-0.28.0.tgz", { "os": "android", "cpu": "arm" }, "sha512-wqh0ByljabXLKHeWXYLqoJ5jKC4XBaw6Hk08OfMrCRd2nP2ZQ5eleDZC41XHyCNgktBGYMbqnrJKq/K/lzPMSQ=="], |
3555 | 3552 | |
▼package.json
+4-5
| @@ -47,7 +47,6 @@ | ||
47 | 47 | "@astrojs/check": "^0.9.6", |
48 | 48 | "@astrojs/node": "^8.3.0", |
49 | 49 | "@astrojs/react": "^3.6.0", |
50 | - "@astrojs/tailwind": "^5.1.0", | |
51 | 50 | "@astrojs/vercel": "^7.7.0", |
52 | 51 | "@aws-sdk/client-s3": "^3.948.0", |
53 | 52 | "@aws-sdk/lib-storage": "^3.972.0", |
| @@ -156,7 +155,10 @@ | ||
156 | 155 | "unist-util-visit": "^5.1.0", |
157 | 156 | "yaml": "^2.8.0", |
158 | 157 | "zod": "^3.23.8", |
159 | - "zustand": "^4.5.4" | |
158 | + "zustand": "^4.5.4", | |
159 | + "autoprefixer": "^10.4.19", | |
160 | + "postcss": "~8.4.49", | |
161 | + "tailwindcss": "^3.4.4" | |
160 | 162 | }, |
161 | 163 | "devDependencies": { |
162 | 164 | "@axe-core/playwright": "^4.10.0", |
| @@ -176,11 +178,8 @@ | ||
176 | 178 | "@types/ssh2": "^1.15.0", |
177 | 179 | "@types/three": "^0.182.0", |
178 | 180 | "@vitest/coverage-v8": "^4.1.5", |
179 | - "autoprefixer": "^10.4.19", | |
180 | 181 | "drizzle-kit": "^0.31.8", |
181 | 182 | "pino-pretty": "^13.1.3", |
182 | - "postcss": "~8.4.49", | |
183 | - "tailwindcss": "^3.4.4", | |
184 | 183 | "typescript": "^5.9.3", |
185 | 184 | "vitest": "^4.1.5" |
186 | 185 | }, |
187 | 186 | |
▼src/styles/globals.css
+208-197
| @@ -4,26 +4,44 @@ | ||
4 | 4 | |
5 | 5 | @layer base { |
6 | 6 | :root { |
7 | + /* Premium Design System - OpenCodeHub Light Theme */ | |
7 | 8 | --background: 0 0% 100%; |
8 | - --foreground: 222.2 84% 4.9%; | |
9 | + --foreground: 210 11% 15%; | |
9 | 10 | --card: 0 0% 100%; |
10 | - --card-foreground: 222.2 84% 4.9%; | |
11 | + --card-foreground: 210 11% 15%; | |
11 | 12 | --popover: 0 0% 100%; |
12 | - --popover-foreground: 222.2 84% 4.9%; | |
13 | - --primary: 222.2 47.4% 11.2%; | |
14 | - --primary-foreground: 210 40% 98%; | |
15 | - --secondary: 210 40% 96.1%; | |
16 | - --secondary-foreground: 222.2 47.4% 11.2%; | |
17 | - --muted: 210 40% 96.1%; | |
18 | - --muted-foreground: 215.4 16.3% 46.9%; | |
19 | - --accent: 210 40% 96.1%; | |
20 | - --accent-foreground: 222.2 47.4% 11.2%; | |
21 | - --destructive: 0 84.2% 60.2%; | |
22 | - --destructive-foreground: 210 40% 98%; | |
23 | - --border: 214.3 31.8% 91.4%; | |
24 | - --input: 214.3 31.8% 91.4%; | |
25 | - --ring: 222.2 84% 4.9%; | |
13 | + --popover-foreground: 210 11% 15%; | |
14 | + --primary: 212 100% 48%; | |
15 | + --primary-foreground: 0 0% 100%; | |
16 | + --secondary: 210 14% 95%; | |
17 | + --secondary-foreground: 210 11% 15%; | |
18 | + --muted: 210 20% 98%; | |
19 | + --muted-foreground: 210 11% 40%; | |
20 | + --accent: 210 20% 96%; | |
21 | + --accent-foreground: 210 11% 15%; | |
22 | + --destructive: 354 70% 54%; | |
23 | + --destructive-foreground: 0 0% 100%; | |
24 | + --border: 210 18% 87%; | |
25 | + --input: 210 18% 87%; | |
26 | + --ring: 212 100% 48%; | |
26 | 27 | --radius: 0.5rem; |
28 | + | |
29 | + --success: 142 70% 45%; | |
30 | + --hero-gradient: radial-gradient(ellipse at top center, hsl(210 20% 98%) 0%, hsl(0 0% 100%) 60%); | |
31 | + --glass-blur: 20px; | |
32 | + --glass-bg: rgba(255, 255, 255, 0.7); | |
33 | + | |
34 | + /* Sidebar Tokens */ | |
35 | + --sidebar-background: 0 0% 98%; | |
36 | + --sidebar-foreground: 240 5.3% 26.1%; | |
37 | + --sidebar-primary: 240 5.9% 10%; | |
38 | + --sidebar-primary-foreground: 0 0% 98%; | |
39 | + --sidebar-accent: 240 4.8% 95.9%; | |
40 | + --sidebar-accent-foreground: 240 5.9% 10%; | |
41 | + --sidebar-border: 220 13% 91%; | |
42 | + --sidebar-ring: 217.2 91.2% 59.8%; | |
43 | + | |
44 | + /* Chart Tokens */ | |
27 | 45 | --chart-1: 12 76% 61%; |
28 | 46 | --chart-2: 173 58% 39%; |
29 | 47 | --chart-3: 197 37% 24%; |
| @@ -56,6 +74,16 @@ | ||
56 | 74 | --hero-gradient: radial-gradient(ellipse at top center, hsl(229 40% 18%) 0%, hsl(227 45% 5%) 60%); |
57 | 75 | --glass-blur: 20px; |
58 | 76 | --glass-bg: rgba(18, 23, 42, 0.6); |
77 | + | |
78 | + /* Sidebar Tokens */ | |
79 | + --sidebar-background: 229 40% 12%; | |
80 | + --sidebar-foreground: 228 33% 92%; | |
81 | + --sidebar-primary: 233 100% 74%; | |
82 | + --sidebar-primary-foreground: 227 45% 5%; | |
83 | + --sidebar-accent: 229 40% 16%; | |
84 | + --sidebar-accent-foreground: 228 33% 92%; | |
85 | + --sidebar-border: 0 0% 100% / 0.06; | |
86 | + --sidebar-ring: 233 100% 74%; | |
59 | 87 | } |
60 | 88 | |
61 | 89 | /* GitHub Dark Theme */ |
| @@ -81,6 +109,16 @@ | ||
81 | 109 | --ring: 212 92% 63%; |
82 | 110 | --hero-gradient: radial-gradient(ellipse at top center, hsl(215 22% 14%) 0%, hsl(216 28% 7%) 60%); |
83 | 111 | --glass-bg: rgba(13, 17, 23, 0.6); |
112 | + | |
113 | + /* Sidebar Tokens */ | |
114 | + --sidebar-background: 215 22% 10%; | |
115 | + --sidebar-foreground: 210 17% 82%; | |
116 | + --sidebar-primary: 212 92% 63%; | |
117 | + --sidebar-primary-foreground: 0 0% 100%; | |
118 | + --sidebar-accent: 215 22% 14%; | |
119 | + --sidebar-accent-foreground: 210 17% 82%; | |
120 | + --sidebar-border: 215 14% 34%; | |
121 | + --sidebar-ring: 212 92% 63%; | |
84 | 122 | } |
85 | 123 | |
86 | 124 | /* Dracula Theme */ |
| @@ -106,6 +144,16 @@ | ||
106 | 144 | --ring: 326 100% 74%; |
107 | 145 | --hero-gradient: radial-gradient(ellipse at top center, hsl(231 15% 25%) 0%, hsl(231 15% 18%) 60%); |
108 | 146 | --glass-bg: rgba(40, 42, 54, 0.6); |
147 | + | |
148 | + /* Sidebar Tokens */ | |
149 | + --sidebar-background: 231 15% 20%; | |
150 | + --sidebar-foreground: 60 30% 96%; | |
151 | + --sidebar-primary: 326 100% 74%; | |
152 | + --sidebar-primary-foreground: 231 15% 18%; | |
153 | + --sidebar-accent: 231 15% 25%; | |
154 | + --sidebar-accent-foreground: 60 30% 96%; | |
155 | + --sidebar-border: 231 15% 25%; | |
156 | + --sidebar-ring: 326 100% 74%; | |
109 | 157 | } |
110 | 158 | |
111 | 159 | /* Rose Pine Theme */ |
| @@ -131,6 +179,16 @@ | ||
131 | 179 | --ring: 343 35% 65%; |
132 | 180 | --hero-gradient: radial-gradient(ellipse at top center, hsl(247 23% 15%) 0%, hsl(249 22% 12%) 60%); |
133 | 181 | --glass-bg: rgba(25, 23, 36, 0.6); |
182 | + | |
183 | + /* Sidebar Tokens */ | |
184 | + --sidebar-background: 247 23% 15%; | |
185 | + --sidebar-foreground: 248 19% 89%; | |
186 | + --sidebar-primary: 343 35% 65%; | |
187 | + --sidebar-primary-foreground: 249 22% 12%; | |
188 | + --sidebar-accent: 248 25% 18%; | |
189 | + --sidebar-accent-foreground: 248 19% 89%; | |
190 | + --sidebar-border: 248 25% 18%; | |
191 | + --sidebar-ring: 343 35% 65%; | |
134 | 192 | } |
135 | 193 | |
136 | 194 | /* Tokyo Night Theme */ |
| @@ -156,6 +214,16 @@ | ||
156 | 214 | --ring: 263 70% 74%; |
157 | 215 | --hero-gradient: radial-gradient(ellipse at top center, hsl(235 18% 20%) 0%, hsl(235 18% 14%) 60%); |
158 | 216 | --glass-bg: rgba(26, 27, 38, 0.6); |
217 | + | |
218 | + /* Sidebar Tokens */ | |
219 | + --sidebar-background: 235 18% 16%; | |
220 | + --sidebar-foreground: 227 70% 87%; | |
221 | + --sidebar-primary: 263 70% 74%; | |
222 | + --sidebar-primary-foreground: 235 18% 14%; | |
223 | + --sidebar-accent: 235 18% 20%; | |
224 | + --sidebar-accent-foreground: 227 70% 87%; | |
225 | + --sidebar-border: 235 18% 20%; | |
226 | + --sidebar-ring: 263 70% 74%; | |
159 | 227 | } |
160 | 228 | } |
161 | 229 | |
| @@ -165,18 +233,38 @@ | ||
165 | 233 | } |
166 | 234 | |
167 | 235 | body { |
168 | - @apply bg-background text-foreground; | |
236 | + @apply bg-background text-foreground transition-colors duration-300; | |
237 | + font-family: "Inter", system-ui, sans-serif; | |
238 | + } | |
239 | + | |
240 | + code, | |
241 | + pre, | |
242 | + .font-mono { | |
243 | + font-family: "JetBrains Mono", monospace; | |
244 | + } | |
245 | + | |
246 | + html { | |
247 | + scroll-behavior: smooth; | |
169 | 248 | } |
170 | 249 | } |
171 | 250 | |
172 | -/* Custom scrollbar */ | |
251 | +/* ========================================================================== | |
252 | + Base Elements & Globals | |
253 | + ========================================================================== */ | |
254 | + | |
255 | +/* Modern Custom scrollbar */ | |
256 | +* { | |
257 | + scrollbar-width: thin; | |
258 | + scrollbar-color: hsl(var(--border)) transparent; | |
259 | +} | |
260 | + | |
173 | 261 | ::-webkit-scrollbar { |
174 | 262 | width: 8px; |
175 | 263 | height: 8px; |
176 | 264 | } |
177 | 265 | |
178 | 266 | ::-webkit-scrollbar-track { |
179 | - background: hsl(var(--muted)); | |
267 | + background: transparent; | |
180 | 268 | border-radius: 4px; |
181 | 269 | } |
182 | 270 | |
| @@ -213,11 +301,11 @@ | ||
213 | 301 | } |
214 | 302 | |
215 | 303 | .diff-add-line { |
216 | - @apply bg-green-50 dark:bg-green-900/20 border-l-4 border-green-500; | |
304 | + @apply bg-green-50/50 dark:bg-green-900/20 border-l-4 border-green-500; | |
217 | 305 | } |
218 | 306 | |
219 | 307 | .diff-remove-line { |
220 | - @apply bg-red-50 dark:bg-red-900/20 border-l-4 border-red-500; | |
308 | + @apply bg-red-50/50 dark:bg-red-900/20 border-l-4 border-red-500; | |
221 | 309 | } |
222 | 310 | |
223 | 311 | .diff-context-line { |
| @@ -226,11 +314,11 @@ | ||
226 | 314 | |
227 | 315 | /* File tree styles */ |
228 | 316 | .file-tree-item { |
229 | - @apply flex items-center gap-2 px-2 py-1 rounded cursor-pointer hover:bg-accent transition-colors; | |
317 | + @apply flex items-center gap-2 px-2 py-1 rounded cursor-pointer hover:bg-accent hover:text-accent-foreground transition-colors; | |
230 | 318 | } |
231 | 319 | |
232 | 320 | .file-tree-item.selected { |
233 | - @apply bg-accent text-accent-foreground; | |
321 | + @apply bg-accent text-accent-foreground font-medium; | |
234 | 322 | } |
235 | 323 | |
236 | 324 | /* Commit graph styles */ |
| @@ -260,17 +348,13 @@ | ||
260 | 348 | @apply text-blue-600 dark:text-blue-400; |
261 | 349 | } |
262 | 350 | |
263 | -/* Animation keyframes */ | |
264 | -@keyframes pulse-slow { | |
265 | - | |
266 | - 0%, | |
267 | - 100% { | |
268 | - opacity: 1; | |
269 | - } | |
351 | +/* ========================================================================== | |
352 | + Animations | |
353 | + ========================================================================== */ | |
270 | 354 | |
271 | - 50% { | |
272 | - opacity: 0.5; | |
273 | - } | |
355 | +@keyframes pulse-slow { | |
356 | + 0%, 100% { opacity: 1; } | |
357 | + 50% { opacity: 0.5; } | |
274 | 358 | } |
275 | 359 | |
276 | 360 | .animate-pulse-slow { |
| @@ -278,20 +362,18 @@ | ||
278 | 362 | } |
279 | 363 | |
280 | 364 | @keyframes spin-slow { |
281 | - from { | |
282 | - transform: rotate(0deg); | |
283 | - } | |
284 | - | |
285 | - to { | |
286 | - transform: rotate(360deg); | |
287 | - } | |
365 | + from { transform: rotate(0deg); } | |
366 | + to { transform: rotate(360deg); } | |
288 | 367 | } |
289 | 368 | |
290 | 369 | .animate-spin-slow { |
291 | 370 | animation: spin-slow 3s linear infinite; |
292 | 371 | } |
293 | 372 | |
294 | -/* Markdown preview styles */ | |
373 | +/* ========================================================================== | |
374 | + Markdown Elements | |
375 | + ========================================================================== */ | |
376 | + | |
295 | 377 | .markdown-body { |
296 | 378 | @apply text-foreground; |
297 | 379 | } |
| @@ -321,19 +403,19 @@ | ||
321 | 403 | } |
322 | 404 | |
323 | 405 | .markdown-body code { |
324 | - @apply bg-muted px-1.5 py-0.5 rounded text-sm font-mono; | |
406 | + @apply bg-muted px-1.5 py-0.5 rounded text-sm font-mono border border-border; | |
325 | 407 | } |
326 | 408 | |
327 | 409 | .markdown-body pre { |
328 | - @apply bg-muted p-4 rounded-lg overflow-x-auto mb-4; | |
410 | + @apply bg-muted p-4 rounded-lg overflow-x-auto mb-4 border border-border; | |
329 | 411 | } |
330 | 412 | |
331 | 413 | .markdown-body pre code { |
332 | - @apply bg-transparent p-0; | |
414 | + @apply bg-transparent p-0 border-none; | |
333 | 415 | } |
334 | 416 | |
335 | 417 | .markdown-body blockquote { |
336 | - @apply border-l-4 border-muted-foreground pl-4 italic my-4; | |
418 | + @apply border-l-4 border-muted-foreground pl-4 italic my-4 text-muted-foreground; | |
337 | 419 | } |
338 | 420 | |
339 | 421 | .markdown-body table { |
| @@ -350,14 +432,17 @@ | ||
350 | 432 | } |
351 | 433 | |
352 | 434 | .markdown-body a { |
353 | - @apply text-primary hover:underline; | |
435 | + @apply text-primary hover:underline font-medium; | |
354 | 436 | } |
355 | 437 | |
356 | 438 | .markdown-body img { |
357 | - @apply max-w-full rounded-lg; | |
439 | + @apply max-w-full rounded-lg border border-border; | |
358 | 440 | } |
359 | 441 | |
360 | -/* Loading skeleton */ | |
442 | +/* ========================================================================== | |
443 | + Utilities | |
444 | + ========================================================================== */ | |
445 | + | |
361 | 446 | .skeleton { |
362 | 447 | @apply animate-pulse bg-muted rounded; |
363 | 448 | } |
| @@ -367,16 +452,20 @@ | ||
367 | 452 | @apply focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 focus:ring-offset-background; |
368 | 453 | } |
369 | 454 | |
370 | -/* ====== Premium Landing Page Animations ====== */ | |
455 | +.text-balance { | |
456 | + text-wrap: balance; | |
457 | +} | |
458 | + | |
459 | +/* ========================================================================== | |
460 | + Premium Landing Page Animations | |
461 | + ========================================================================== */ | |
371 | 462 | |
372 | -/* Text reveal animation - staggered word appearance */ | |
373 | 463 | @keyframes text-reveal { |
374 | 464 | 0% { |
375 | 465 | opacity: 0; |
376 | 466 | transform: translateY(20px); |
377 | 467 | filter: blur(4px); |
378 | 468 | } |
379 | - | |
380 | 469 | 100% { |
381 | 470 | opacity: 1; |
382 | 471 | transform: translateY(0); |
| @@ -389,28 +478,20 @@ | ||
389 | 478 | opacity: 0; |
390 | 479 | } |
391 | 480 | |
392 | -/* Shimmer effect for timeline */ | |
393 | 481 | @keyframes shimmer { |
394 | - 0% { | |
395 | - transform: translateX(-100%); | |
396 | - } | |
397 | - | |
398 | - 100% { | |
399 | - transform: translateX(200%); | |
400 | - } | |
482 | + 0% { transform: translateX(-100%); } | |
483 | + 100% { transform: translateX(200%); } | |
401 | 484 | } |
402 | 485 | |
403 | 486 | .animate-shimmer { |
404 | 487 | animation: shimmer 3s infinite linear; |
405 | 488 | } |
406 | 489 | |
407 | -/* Slide up + fade */ | |
408 | 490 | @keyframes slide-fade-up { |
409 | 491 | 0% { |
410 | 492 | opacity: 0; |
411 | 493 | transform: translateY(30px); |
412 | 494 | } |
413 | - | |
414 | 495 | 100% { |
415 | 496 | opacity: 1; |
416 | 497 | transform: translateY(0); |
| @@ -421,15 +502,11 @@ | ||
421 | 502 | animation: slide-fade-up 0.6s cubic-bezier(0.22, 1, 0.36, 1) forwards; |
422 | 503 | } |
423 | 504 | |
424 | -/* Soft pulse for dots */ | |
425 | 505 | @keyframes soft-pulse { |
426 | - | |
427 | - 0%, | |
428 | - 100% { | |
506 | + 0%, 100% { | |
429 | 507 | opacity: 0.6; |
430 | 508 | transform: scale(1); |
431 | 509 | } |
432 | - | |
433 | 510 | 50% { |
434 | 511 | opacity: 1; |
435 | 512 | transform: scale(1.3); |
| @@ -440,62 +517,74 @@ | ||
440 | 517 | animation: soft-pulse 2s ease-in-out infinite; |
441 | 518 | } |
442 | 519 | |
443 | -/* Glass card hover effect */ | |
520 | +/* CTA Button Styles */ | |
521 | +.btn-primary-glow { | |
522 | + background: linear-gradient(135deg, hsl(var(--primary)) 0%, color-mix(in srgb, hsl(var(--primary)) 80%, white) 100%); | |
523 | + color: hsl(var(--primary-foreground)); | |
524 | + transition: all 0.3s cubic-bezier(0.22, 1, 0.36, 1); | |
525 | + box-shadow: 0 4px 20px color-mix(in srgb, hsl(var(--primary)) 30%, transparent); | |
526 | +} | |
527 | + | |
528 | +.btn-primary-glow:hover { | |
529 | + transform: translateY(-2px); | |
530 | + box-shadow: 0 8px 30px color-mix(in srgb, hsl(var(--primary)) 50%, transparent); | |
531 | +} | |
532 | + | |
533 | +.hero-gradient { | |
534 | + background: var(--hero-gradient); | |
535 | +} | |
536 | + | |
537 | +/* ========================================================================== | |
538 | + Glass & Dashboard HUD | |
539 | + ========================================================================== */ | |
540 | + | |
444 | 541 | .glass-card { |
445 | 542 | background: var(--glass-bg); |
446 | 543 | backdrop-filter: blur(var(--glass-blur)); |
447 | - border: 1px solid rgba(255, 255, 255, 0.06); | |
544 | + border: 1px solid color-mix(in srgb, currentColor 10%, transparent); | |
448 | 545 | border-radius: 16px; |
449 | 546 | transition: all 0.3s cubic-bezier(0.22, 1, 0.36, 1); |
450 | 547 | } |
451 | 548 | |
452 | 549 | .glass-card:hover { |
453 | - background: rgba(18, 23, 42, 0.8); | |
454 | - border-color: rgba(255, 255, 255, 0.12); | |
550 | + background: color-mix(in srgb, var(--glass-bg) 90%, black); | |
551 | + border-color: color-mix(in srgb, currentColor 20%, transparent); | |
455 | 552 | transform: translateY(-2px); |
456 | - box-shadow: 0 20px 40px rgba(0, 0, 0, 0.3); | |
553 | + box-shadow: 0 20px 40px rgba(0, 0, 0, 0.1); | |
457 | 554 | } |
458 | 555 | |
459 | -/* CTA Button Styles */ | |
460 | -.btn-primary-glow { | |
461 | - background: linear-gradient(135deg, hsl(233 100% 74%) 0%, hsl(230 100% 82%) 100%); | |
462 | - color: hsl(227 45% 5%); | |
463 | - transition: all 0.3s cubic-bezier(0.22, 1, 0.36, 1); | |
464 | - box-shadow: 0 4px 20px rgba(124, 140, 255, 0.3); | |
556 | +/* Glass panel for admin dashboard / HUD */ | |
557 | +.glass-panel { | |
558 | + background: color-mix(in srgb, var(--glass-bg) 80%, transparent); | |
559 | + backdrop-filter: blur(var(--glass-blur)); | |
560 | + border: 1px solid color-mix(in srgb, currentColor 10%, transparent); | |
561 | + box-shadow: 0 4px 30px rgba(0, 0, 0, 0.05); | |
465 | 562 | } |
466 | 563 | |
467 | -.btn-primary-glow:hover { | |
468 | - transform: translateY(-2px); | |
469 | - box-shadow: 0 8px 30px rgba(124, 140, 255, 0.5); | |
564 | +/* Custom thin scrollbar for panels */ | |
565 | +.custom-scrollbar::-webkit-scrollbar { | |
566 | + width: 4px; | |
470 | 567 | } |
471 | - | |
472 | -/* Hero gradient background */ | |
473 | -.hero-gradient { | |
474 | - background: var(--hero-gradient); | |
568 | +.custom-scrollbar::-webkit-scrollbar-track { | |
569 | + background: transparent; | |
475 | 570 | } |
476 | - | |
477 | -/* Motion preference support */ | |
478 | -@media (prefers-reduced-motion: reduce) { | |
479 | - | |
480 | - .animate-text-reveal, | |
481 | - .animate-shimmer, | |
482 | - .animate-slide-up, | |
483 | - .animate-soft-pulse { | |
484 | - animation: none; | |
485 | - opacity: 1; | |
486 | - transform: none; | |
487 | - } | |
571 | +.custom-scrollbar::-webkit-scrollbar-thumb { | |
572 | + background: color-mix(in srgb, currentColor 15%, transparent); | |
573 | + border-radius: 2px; | |
574 | +} | |
575 | +.custom-scrollbar::-webkit-scrollbar-thumb:hover { | |
576 | + background: color-mix(in srgb, currentColor 25%, transparent); | |
488 | 577 | } |
489 | 578 | |
490 | -/* ====== Aceternity UI Styles ====== */ | |
579 | +/* ========================================================================== | |
580 | + Aceternity UI Styles | |
581 | + ========================================================================== */ | |
491 | 582 | |
492 | -/* Spotlight animation */ | |
493 | 583 | @keyframes spotlight { |
494 | 584 | 0% { |
495 | 585 | opacity: 0; |
496 | 586 | transform: translate(-72%, -62%) scale(0.5); |
497 | 587 | } |
498 | - | |
499 | 588 | 100% { |
500 | 589 | opacity: 1; |
501 | 590 | transform: translate(-50%, -40%) scale(1); |
| @@ -506,7 +595,6 @@ | ||
506 | 595 | animation: spotlight 2s ease 0.75s 1 forwards; |
507 | 596 | } |
508 | 597 | |
509 | -/* Dot backgrounds for Hero Highlight */ | |
510 | 598 | .bg-dot-thick-neutral-800 { |
511 | 599 | background-image: radial-gradient(circle, rgba(255, 255, 255, 0.05) 1px, transparent 1px); |
512 | 600 | background-size: 16px 16px; |
| @@ -517,73 +605,37 @@ | ||
517 | 605 | background-size: 16px 16px; |
518 | 606 | } |
519 | 607 | |
520 | -/* Grid background */ | |
521 | 608 | .bg-grid-white\/\[0\.02\] { |
522 | 609 | background-image: linear-gradient(to right, rgba(255, 255, 255, 0.02) 1px, transparent 1px), |
523 | 610 | linear-gradient(to bottom, rgba(255, 255, 255, 0.02) 1px, transparent 1px); |
524 | 611 | background-size: 40px 40px; |
525 | 612 | } |
526 | 613 | |
527 | -/* Gradient text */ | |
528 | 614 | .bg-clip-text { |
529 | 615 | -webkit-background-clip: text; |
530 | 616 | background-clip: text; |
531 | 617 | } |
532 | 618 | |
533 | -/* Glass panel for admin dashboard */ | |
534 | -.glass-panel { | |
535 | - background: rgba(18, 23, 42, 0.6); | |
536 | - backdrop-filter: blur(20px); | |
537 | - border: 1px solid rgba(255, 255, 255, 0.06); | |
538 | -} | |
539 | - | |
540 | -/* Custom scrollbar for panels */ | |
541 | -.custom-scrollbar::-webkit-scrollbar { | |
542 | - width: 6px; | |
543 | -} | |
544 | - | |
545 | -.custom-scrollbar::-webkit-scrollbar-track { | |
546 | - background: transparent; | |
547 | -} | |
548 | - | |
549 | -.custom-scrollbar::-webkit-scrollbar-thumb { | |
550 | - background: rgba(255, 255, 255, 0.1); | |
551 | - border-radius: 3px; | |
552 | -} | |
553 | - | |
554 | -.custom-scrollbar::-webkit-scrollbar-thumb:hover { | |
555 | - background: rgba(255, 255, 255, 0.2); | |
556 | -} | |
557 | - | |
558 | -/* Smooth transitions for all interactive elements */ | |
559 | 619 | @layer utilities { |
560 | 620 | .transition-smooth { |
561 | 621 | transition: all 0.3s cubic-bezier(0.22, 1, 0.36, 1); |
562 | 622 | } |
563 | 623 | } |
564 | 624 | |
565 | -/* Gradient text animation */ | |
566 | 625 | @keyframes gradient-x { |
567 | - 0% { | |
568 | - background-position: 0% 50%; | |
569 | - } | |
570 | - | |
571 | - 50% { | |
572 | - background-position: 100% 50%; | |
573 | - } | |
574 | - | |
575 | - 100% { | |
576 | - background-position: 0% 50%; | |
577 | - } | |
626 | + 0% { background-position: 0% 50%; } | |
627 | + 50% { background-position: 100% 50%; } | |
628 | + 100% { background-position: 0% 50%; } | |
578 | 629 | } |
579 | 630 | |
580 | 631 | .animate-gradient-x { |
581 | 632 | animation: gradient-x 3s ease infinite; |
582 | 633 | } |
583 | 634 | |
584 | -/* ====== Responsive Utilities ====== */ | |
635 | +/* ========================================================================== | |
636 | + Responsive & Accessibility Utilities | |
637 | + ========================================================================== */ | |
585 | 638 | |
586 | -/* Hide scrollbar on mobile */ | |
587 | 639 | .no-scrollbar::-webkit-scrollbar { |
588 | 640 | display: none; |
589 | 641 | } |
| @@ -592,20 +644,16 @@ | ||
592 | 644 | scrollbar-width: none; |
593 | 645 | } |
594 | 646 | |
595 | -/* Better mobile spacing */ | |
596 | 647 | @media (max-width: 640px) { |
597 | 648 | .container { |
598 | 649 | padding-left: 1rem; |
599 | 650 | padding-right: 1rem; |
600 | 651 | } |
601 | - | |
602 | - /* Stack grid items on mobile */ | |
603 | 652 | .grid-cols-2 { |
604 | 653 | grid-template-columns: repeat(1, minmax(0, 1fr)); |
605 | 654 | } |
606 | 655 | } |
607 | 656 | |
608 | -/* Tablet adjustments */ | |
609 | 657 | @media (min-width: 640px) and (max-width: 1024px) { |
610 | 658 | .container { |
611 | 659 | padding-left: 1.5rem; |
| @@ -613,33 +661,25 @@ | ||
613 | 661 | } |
614 | 662 | } |
615 | 663 | |
616 | -/* Touch-friendly interactive elements */ | |
617 | 664 | @media (hover: none) and (pointer: coarse) { |
618 | 665 | button, a, input, textarea, select { |
619 | 666 | min-height: 44px; |
620 | 667 | min-width: 44px; |
621 | 668 | } |
622 | - | |
623 | - /* Remove hover effects on touch devices */ | |
624 | 669 | .hover\:-translate-y-1:hover, |
625 | 670 | .hover\:scale-105:hover { |
626 | 671 | transform: none; |
627 | 672 | } |
628 | 673 | } |
629 | 674 | |
630 | -/* Print styles */ | |
631 | 675 | @media print { |
632 | - .no-print { | |
633 | - display: none !important; | |
634 | - } | |
635 | - | |
676 | + .no-print { display: none !important; } | |
636 | 677 | body { |
637 | 678 | background: white !important; |
638 | 679 | color: black !important; |
639 | 680 | } |
640 | 681 | } |
641 | 682 | |
642 | -/* Reduced motion */ | |
643 | 683 | @media (prefers-reduced-motion: reduce) { |
644 | 684 | *, *::before, *::after { |
645 | 685 | animation-duration: 0.01ms !important; |
| @@ -647,21 +687,28 @@ | ||
647 | 687 | transition-duration: 0.01ms !important; |
648 | 688 | scroll-behavior: auto !important; |
649 | 689 | } |
690 | + | |
691 | + .animate-text-reveal, | |
692 | + .animate-shimmer, | |
693 | + .animate-slide-up, | |
694 | + .animate-soft-pulse { | |
695 | + animation: none; | |
696 | + opacity: 1; | |
697 | + transform: none; | |
698 | + } | |
650 | 699 | } |
651 | 700 | |
652 | -/* Focus visible for keyboard navigation */ | |
653 | 701 | :focus-visible { |
654 | 702 | outline: 2px solid hsl(var(--ring)); |
655 | 703 | outline-offset: 2px; |
704 | + border-radius: calc(var(--radius) - 2px); | |
656 | 705 | } |
657 | 706 | |
658 | -/* Prevent layout shift from lazy images */ | |
659 | 707 | img { |
660 | 708 | max-width: 100%; |
661 | 709 | height: auto; |
662 | 710 | } |
663 | 711 | |
664 | -/* Better overflow handling */ | |
665 | 712 | .overflow-x-auto { |
666 | 713 | -webkit-overflow-scrolling: touch; |
667 | 714 | } |
| @@ -675,12 +722,12 @@ img { | ||
675 | 722 | background: transparent; |
676 | 723 | } |
677 | 724 | .blob-scrollbar::-webkit-scrollbar-thumb { |
678 | - background: #30363d; | |
725 | + background: color-mix(in srgb, currentColor 15%, transparent); | |
679 | 726 | border-radius: 5px; |
680 | - border: 2px solid #0d1117; | |
727 | + border: 2px solid var(--background); | |
681 | 728 | } |
682 | 729 | .blob-scrollbar::-webkit-scrollbar-thumb:hover { |
683 | - background: #424a53; | |
730 | + background: color-mix(in srgb, currentColor 25%, transparent); | |
684 | 731 | } |
685 | 732 | |
686 | 733 | /* Shiki code highlighting overrides */ |
| @@ -696,40 +743,4 @@ img { | ||
696 | 743 | .shiki .line { |
697 | 744 | height: 1.5rem; |
698 | 745 | display: block; |
699 | -} | |
700 | - | |
701 | -/* Admin HUD styles */ | |
702 | -.glass-panel { | |
703 | - background: rgba(13, 17, 23, 0.3); | |
704 | - backdrop-filter: blur(10px); | |
705 | - border: 1px solid rgba(255, 255, 255, 0.05); | |
706 | - box-shadow: 0 4px 30px rgba(0, 0, 0, 0.1); | |
707 | -} | |
708 | - | |
709 | -.custom-scrollbar::-webkit-scrollbar { | |
710 | - width: 4px; | |
711 | -} | |
712 | - | |
713 | -.custom-scrollbar::-webkit-scrollbar-thumb { | |
714 | - background: rgba(255, 255, 255, 0.1); | |
715 | - border-radius: 2px; | |
716 | -} | |
717 | - | |
718 | -/* Base layout styles */ | |
719 | -body { | |
720 | - font-family: "Inter", system-ui, sans-serif; | |
721 | -} | |
722 | - | |
723 | -code, | |
724 | -pre, | |
725 | -.font-mono { | |
726 | - font-family: "JetBrains Mono", monospace; | |
727 | -} | |
728 | - | |
729 | -.text-balance { | |
730 | - text-wrap: balance; | |
731 | -} | |
732 | - | |
733 | -html { | |
734 | - scroll-behavior: smooth; | |
735 | 746 | } |
736 | 747 | |