diff options
| -rw-r--r-- | .claude/settings.local.json | 12 | ||||
| -rw-r--r-- | .demo/index.html | 7 | ||||
| -rw-r--r-- | .dockerignore | 2 | ||||
| -rw-r--r-- | .gitignore | 7 | ||||
| -rw-r--r-- | Dockerfile | 21 | ||||
| -rw-r--r-- | docker-entrypoint.sh | 16 | ||||
| -rw-r--r-- | esbuild.config.js | 75 | ||||
| -rw-r--r-- | package-lock.json | 1185 | ||||
| -rw-r--r-- | package.json | 20 | ||||
| -rw-r--r-- | src/assets/fonts/Maple.woff2 (renamed from static/fonts/Maple.woff2) | bin | 73444 -> 73444 bytes | |||
| -rw-r--r-- | src/assets/img/bg.png (renamed from static/img/bg.png) | bin | 47672 -> 47672 bytes | |||
| -rw-r--r-- | src/assets/img/coffee.svg (renamed from static/img/coffee.svg) | 0 | ||||
| -rw-r--r-- | src/assets/img/favicon.ico (renamed from static/img/favicon.ico) | bin | 32243 -> 32243 bytes | |||
| -rw-r--r-- | src/assets/oneko/oneko.gif (renamed from static/oneko/oneko.gif) | bin | 3316 -> 3316 bytes | |||
| -rw-r--r-- | src/css/style.css (renamed from static/css/style.css) | 623 | ||||
| -rw-r--r-- | src/index.html (renamed from static/index.html) | 42 | ||||
| -rw-r--r-- | src/js/oneko.js (renamed from static/oneko/oneko.js) | 6 | ||||
| -rw-r--r-- | src/js/script.js (renamed from static/js/script.js) | 11 |
18 files changed, 1758 insertions, 269 deletions
diff --git a/.claude/settings.local.json b/.claude/settings.local.json new file mode 100644 index 0000000..282bb4b --- /dev/null +++ b/.claude/settings.local.json @@ -0,0 +1,12 @@ +{ + "permissions": { + "allow": [ + "Bash(tree:*)", + "Bash(find:*)", + "Bash(file:*)", + "Bash(npm run dev:*)", + "Bash(npm run build:*)", + "Bash(HOST=\"https://cdn.example.com\" npm run build:*)" + ] + } +} diff --git a/.demo/index.html b/.demo/index.html index 1b93990..7a0195d 100644 --- a/.demo/index.html +++ b/.demo/index.html @@ -4,8 +4,8 @@ <meta charset="UTF-8" /> <meta name="viewport" content="width=device-width, initial-scale=1.0" /> <title>Liz Dot Coffee!</title> - <link rel="stylesheet" href="/static/css/style.css" /> - <link rel="icon" href="/static/img/favicon.ico" /> + <link rel="stylesheet" href="/bundle.css" /> + <link rel="icon" href="/img/favicon.ico" /> </head> <body> <header> @@ -42,7 +42,6 @@ <p>© 2025 My Retro Blog. Made with coffee and nostalgia.</p> </footer> - <script src="/static/js/script.js"></script> - <script src="/static/oneko/oneko.js"></script> + <script src="/bundle.js"></script> </body> </html> diff --git a/.dockerignore b/.dockerignore index c336721..405a410 100644 --- a/.dockerignore +++ b/.dockerignore @@ -5,3 +5,5 @@ .DS_Store README.md *.md +node_modules +dist @@ -19,14 +19,19 @@ Thumbs.db .env .env.local -# Node (if you add build tooling later) +# Node and Build node_modules/ +dist/ npm-debug.log yarn-error.log +*.log # Docker .docker +# Claude +.claude + # Temporary files *.tmp *.log @@ -1,15 +1,24 @@ -FROM nginx:alpine as adelie +FROM node:22-alpine AS builder -COPY static/ /usr/share/nginx/html/ +ARG HOST="adelie.liz.coffee" +ENV HOST=${HOST} -COPY nginx.conf /etc/nginx/nginx.conf +WORKDIR /app +COPY package*.json ./ +RUN npm ci --only=production + +COPY src/ ./src/ +COPY esbuild.config.js ./ +RUN npm run build -COPY docker-entrypoint.sh /usr/local/bin/ -RUN chmod +x /usr/local/bin/docker-entrypoint.sh +FROM nginx:alpine as adelie + +COPY --from=builder /app/dist/ /usr/share/nginx/html/ +COPY nginx.conf /etc/nginx/nginx.conf EXPOSE 80 HEALTHCHECK --interval=30s --timeout=3s --start-period=5s --retries=3 \ CMD wget --quiet --tries=1 --spider http://localhost/ || exit 1 -ENTRYPOINT ["/usr/local/bin/docker-entrypoint.sh"] +CMD ["nginx", "-g", "daemon off;"] diff --git a/docker-entrypoint.sh b/docker-entrypoint.sh deleted file mode 100644 index b4bade6..0000000 --- a/docker-entrypoint.sh +++ /dev/null @@ -1,16 +0,0 @@ -#!/bin/sh -set -e - -if [ ! -z "$HOST" ]; then - ESCAPED_HOST=$(echo "$HOST" | sed 's/[\/&]/\\&/g') - - find /usr/share/nginx/html -name "*.css" -type f -exec sed -i "s|/static/|${ESCAPED_HOST}/|g" {} \; - find /usr/share/nginx/html -name "*.js" -type f -exec sed -i "s|/static/|${ESCAPED_HOST}/|g" {} \; - find /usr/share/nginx/html -name "*.html" -type f -exec sed -i "s|/static/|${ESCAPED_HOST}/|g" {} \; - - echo "Updated static URLs to use HOST: $HOST" -else - echo "Serving static assets from root" -fi - -exec nginx -g "daemon off;" diff --git a/esbuild.config.js b/esbuild.config.js new file mode 100644 index 0000000..1bee10c --- /dev/null +++ b/esbuild.config.js @@ -0,0 +1,75 @@ +const esbuild = require('esbuild'); +const fs = require('fs-extra'); +const path = require('path'); + +const production = process.env.NODE_ENV === 'production'; + +async function buildJS() { + await esbuild.build({ + entryPoints: ['src/js/script.js'], + bundle: true, + minify: production, + sourcemap: true, + target: 'es2020', + outfile: 'dist/bundle.js', + }); +} + +async function buildCSS() { + await esbuild.build({ + entryPoints: ['src/css/style.css'], + bundle: true, + minify: production, + sourcemap: true, + loader: { + '.css': 'css', + '.woff2': 'file', + '.png': 'file', + '.svg': 'file', + }, + outfile: 'dist/bundle.css', + }); +} + +async function copyAssets() { + await fs.copy('src/assets', 'dist', { + overwrite: true, + }); +} + +async function processHTML() { + let html = await fs.readFile('src/index.html', 'utf8'); + + const host = process.env.HOST || ''; + const cleanHost = host.replace(/\/$/, ''); + + if (cleanHost) { + html = html.replace(/href="\/bundle\./g, `href="${cleanHost}/bundle.`); + html = html.replace(/src="\/bundle\./g, `src="${cleanHost}/bundle.`); + html = html.replace(/href="\/img\//g, `href="${cleanHost}/img/`); + html = html.replace(/src="\/oneko\//g, `src="${cleanHost}/oneko/`); + } + + await fs.writeFile('dist/index.html', html); +} + +async function clean() { + await fs.remove('dist'); + await fs.ensureDir('dist'); +} + +async function build() { + try { + await clean(); + await Promise.all([ + buildJS(), + buildCSS(), + copyAssets(), + ]); + await processHTML(); + } catch (err) { + process.exit(1); + } +} + +build(); diff --git a/package-lock.json b/package-lock.json new file mode 100644 index 0000000..aa28f56 --- /dev/null +++ b/package-lock.json @@ -0,0 +1,1185 @@ +{ + "name": "adelie-css", + "version": "1.0.0", + "lockfileVersion": 3, + "requires": true, + "packages": { + "": { + "name": "adelie-css", + "version": "1.0.0", + "dependencies": { + "prismjs": "^1.29.0" + }, + "devDependencies": { + "esbuild": "^0.25.5", + "fs-extra": "^11.2.0", + "http-server": "^14.1.1" + } + }, + "node_modules/@esbuild/aix-ppc64": { + "version": "0.25.12", + "resolved": "https://registry.npmjs.org/@esbuild/aix-ppc64/-/aix-ppc64-0.25.12.tgz", + "integrity": "sha512-Hhmwd6CInZ3dwpuGTF8fJG6yoWmsToE+vYgD4nytZVxcu1ulHpUQRAB1UJ8+N1Am3Mz4+xOByoQoSZf4D+CpkA==", + "cpu": [ + "ppc64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "aix" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/android-arm": { + "version": "0.25.12", + "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.25.12.tgz", + "integrity": "sha512-VJ+sKvNA/GE7Ccacc9Cha7bpS8nyzVv0jdVgwNDaR4gDMC/2TTRc33Ip8qrNYUcpkOHUT5OZ0bUcNNVZQ9RLlg==", + "cpu": [ + "arm" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/android-arm64": { + "version": "0.25.12", + "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.25.12.tgz", + "integrity": "sha512-6AAmLG7zwD1Z159jCKPvAxZd4y/VTO0VkprYy+3N2FtJ8+BQWFXU+OxARIwA46c5tdD9SsKGZ/1ocqBS/gAKHg==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/android-x64": { + "version": "0.25.12", + "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.25.12.tgz", + "integrity": "sha512-5jbb+2hhDHx5phYR2By8GTWEzn6I9UqR11Kwf22iKbNpYrsmRB18aX/9ivc5cabcUiAT/wM+YIZ6SG9QO6a8kg==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/darwin-arm64": { + "version": "0.25.12", + "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.25.12.tgz", + "integrity": "sha512-N3zl+lxHCifgIlcMUP5016ESkeQjLj/959RxxNYIthIg+CQHInujFuXeWbWMgnTo4cp5XVHqFPmpyu9J65C1Yg==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/darwin-x64": { + "version": "0.25.12", + "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.25.12.tgz", + "integrity": "sha512-HQ9ka4Kx21qHXwtlTUVbKJOAnmG1ipXhdWTmNXiPzPfWKpXqASVcWdnf2bnL73wgjNrFXAa3yYvBSd9pzfEIpA==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/freebsd-arm64": { + "version": "0.25.12", + "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.25.12.tgz", + "integrity": "sha512-gA0Bx759+7Jve03K1S0vkOu5Lg/85dou3EseOGUes8flVOGxbhDDh/iZaoek11Y8mtyKPGF3vP8XhnkDEAmzeg==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "freebsd" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/freebsd-x64": { + "version": "0.25.12", + "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.25.12.tgz", + "integrity": "sha512-TGbO26Yw2xsHzxtbVFGEXBFH0FRAP7gtcPE7P5yP7wGy7cXK2oO7RyOhL5NLiqTlBh47XhmIUXuGciXEqYFfBQ==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "freebsd" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-arm": { + "version": "0.25.12", + "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.25.12.tgz", + "integrity": "sha512-lPDGyC1JPDou8kGcywY0YILzWlhhnRjdof3UlcoqYmS9El818LLfJJc3PXXgZHrHCAKs/Z2SeZtDJr5MrkxtOw==", + "cpu": [ + "arm" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-arm64": { + "version": "0.25.12", + "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.25.12.tgz", + "integrity": "sha512-8bwX7a8FghIgrupcxb4aUmYDLp8pX06rGh5HqDT7bB+8Rdells6mHvrFHHW2JAOPZUbnjUpKTLg6ECyzvas2AQ==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-ia32": { + "version": "0.25.12", + "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.25.12.tgz", + "integrity": "sha512-0y9KrdVnbMM2/vG8KfU0byhUN+EFCny9+8g202gYqSSVMonbsCfLjUO+rCci7pM0WBEtz+oK/PIwHkzxkyharA==", + "cpu": [ + "ia32" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-loong64": { + "version": "0.25.12", + "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.25.12.tgz", + "integrity": "sha512-h///Lr5a9rib/v1GGqXVGzjL4TMvVTv+s1DPoxQdz7l/AYv6LDSxdIwzxkrPW438oUXiDtwM10o9PmwS/6Z0Ng==", + "cpu": [ + "loong64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-mips64el": { + "version": "0.25.12", + "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.25.12.tgz", + "integrity": "sha512-iyRrM1Pzy9GFMDLsXn1iHUm18nhKnNMWscjmp4+hpafcZjrr2WbT//d20xaGljXDBYHqRcl8HnxbX6uaA/eGVw==", + "cpu": [ + "mips64el" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-ppc64": { + "version": "0.25.12", + "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.25.12.tgz", + "integrity": "sha512-9meM/lRXxMi5PSUqEXRCtVjEZBGwB7P/D4yT8UG/mwIdze2aV4Vo6U5gD3+RsoHXKkHCfSxZKzmDssVlRj1QQA==", + "cpu": [ + "ppc64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-riscv64": { + "version": "0.25.12", + "resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.25.12.tgz", + "integrity": "sha512-Zr7KR4hgKUpWAwb1f3o5ygT04MzqVrGEGXGLnj15YQDJErYu/BGg+wmFlIDOdJp0PmB0lLvxFIOXZgFRrdjR0w==", + "cpu": [ + "riscv64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-s390x": { + "version": "0.25.12", + "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.25.12.tgz", + "integrity": "sha512-MsKncOcgTNvdtiISc/jZs/Zf8d0cl/t3gYWX8J9ubBnVOwlk65UIEEvgBORTiljloIWnBzLs4qhzPkJcitIzIg==", + "cpu": [ + "s390x" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-x64": { + "version": "0.25.12", + "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.25.12.tgz", + "integrity": "sha512-uqZMTLr/zR/ed4jIGnwSLkaHmPjOjJvnm6TVVitAa08SLS9Z0VM8wIRx7gWbJB5/J54YuIMInDquWyYvQLZkgw==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/netbsd-arm64": { + "version": "0.25.12", + "resolved": "https://registry.npmjs.org/@esbuild/netbsd-arm64/-/netbsd-arm64-0.25.12.tgz", + "integrity": "sha512-xXwcTq4GhRM7J9A8Gv5boanHhRa/Q9KLVmcyXHCTaM4wKfIpWkdXiMog/KsnxzJ0A1+nD+zoecuzqPmCRyBGjg==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "netbsd" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/netbsd-x64": { + "version": "0.25.12", + "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.25.12.tgz", + "integrity": "sha512-Ld5pTlzPy3YwGec4OuHh1aCVCRvOXdH8DgRjfDy/oumVovmuSzWfnSJg+VtakB9Cm0gxNO9BzWkj6mtO1FMXkQ==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "netbsd" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/openbsd-arm64": { + "version": "0.25.12", + "resolved": "https://registry.npmjs.org/@esbuild/openbsd-arm64/-/openbsd-arm64-0.25.12.tgz", + "integrity": "sha512-fF96T6KsBo/pkQI950FARU9apGNTSlZGsv1jZBAlcLL1MLjLNIWPBkj5NlSz8aAzYKg+eNqknrUJ24QBybeR5A==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "openbsd" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/openbsd-x64": { + "version": "0.25.12", + "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.25.12.tgz", + "integrity": "sha512-MZyXUkZHjQxUvzK7rN8DJ3SRmrVrke8ZyRusHlP+kuwqTcfWLyqMOE3sScPPyeIXN/mDJIfGXvcMqCgYKekoQw==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "openbsd" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/openharmony-arm64": { + "version": "0.25.12", + "resolved": "https://registry.npmjs.org/@esbuild/openharmony-arm64/-/openharmony-arm64-0.25.12.tgz", + "integrity": "sha512-rm0YWsqUSRrjncSXGA7Zv78Nbnw4XL6/dzr20cyrQf7ZmRcsovpcRBdhD43Nuk3y7XIoW2OxMVvwuRvk9XdASg==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "openharmony" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/sunos-x64": { + "version": "0.25.12", + "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.25.12.tgz", + "integrity": "sha512-3wGSCDyuTHQUzt0nV7bocDy72r2lI33QL3gkDNGkod22EsYl04sMf0qLb8luNKTOmgF/eDEDP5BFNwoBKH441w==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "sunos" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/win32-arm64": { + "version": "0.25.12", + "resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.25.12.tgz", + "integrity": "sha512-rMmLrur64A7+DKlnSuwqUdRKyd3UE7oPJZmnljqEptesKM8wx9J8gx5u0+9Pq0fQQW8vqeKebwNXdfOyP+8Bsg==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/win32-ia32": { + "version": "0.25.12", + "resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.25.12.tgz", + "integrity": "sha512-HkqnmmBoCbCwxUKKNPBixiWDGCpQGVsrQfJoVGYLPT41XWF8lHuE5N6WhVia2n4o5QK5M4tYr21827fNhi4byQ==", + "cpu": [ + "ia32" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/win32-x64": { + "version": "0.25.12", + "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.25.12.tgz", + "integrity": "sha512-alJC0uCZpTFrSL0CCDjcgleBXPnCrEAhTBILpeAp7M/OFgoqtAetfBzX0xM00MUsVVPpVjlPuMbREqnZCXaTnA==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, + "license": "MIT", + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/async": { + "version": "3.2.6", + "resolved": "https://registry.npmjs.org/async/-/async-3.2.6.tgz", + "integrity": "sha512-htCUDlxyyCLMgaM3xXg0C0LW2xqfuQ6p05pCEIsXuyQ+a1koYKTuBMzRNwmybfLgvJDMd0r1LTn4+E0Ti6C2AA==", + "dev": true, + "license": "MIT" + }, + "node_modules/basic-auth": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/basic-auth/-/basic-auth-2.0.1.tgz", + "integrity": "sha512-NF+epuEdnUYVlGuhaxbbq+dvJttwLnGY+YixlXlME5KpQ5W3CnXA5cVTneY3SPbPDRkcjMbifrwmFYcClgOZeg==", + "dev": true, + "license": "MIT", + "dependencies": { + "safe-buffer": "5.1.2" + }, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/call-bind-apply-helpers": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/call-bind-apply-helpers/-/call-bind-apply-helpers-1.0.2.tgz", + "integrity": "sha512-Sp1ablJ0ivDkSzjcaJdxEunN5/XvksFJ2sMBFfq6x0ryhQV/2b/KwFe21cMpmHtPOSij8K99/wSfoEuTObmuMQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "es-errors": "^1.3.0", + "function-bind": "^1.1.2" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/call-bound": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/call-bound/-/call-bound-1.0.4.tgz", + "integrity": "sha512-+ys997U96po4Kx/ABpBCqhA9EuxJaQWDQg7295H4hBphv3IZg0boBKuwYpt4YXp6MZ5AmZQnU/tyMTlRpaSejg==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind-apply-helpers": "^1.0.2", + "get-intrinsic": "^1.3.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/chalk": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" + } + }, + "node_modules/color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "color-name": "~1.1.4" + }, + "engines": { + "node": ">=7.0.0" + } + }, + "node_modules/color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true, + "license": "MIT" + }, + "node_modules/corser": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/corser/-/corser-2.0.1.tgz", + "integrity": "sha512-utCYNzRSQIZNPIcGZdQc92UVJYAhtGAteCFg0yRaFm8f0P+CPtyGyHXJcGXnffjCybUCEx3FQ2G7U3/o9eIkVQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.4.0" + } + }, + "node_modules/debug": { + "version": "4.4.3", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.4.3.tgz", + "integrity": "sha512-RGwwWnwQvkVfavKVt22FGLw+xYSdzARwm0ru6DhTVA3umU5hZc28V3kO4stgYryrTlLpuvgI9GiijltAjNbcqA==", + "dev": true, + "license": "MIT", + "dependencies": { + "ms": "^2.1.3" + }, + "engines": { + "node": ">=6.0" + }, + "peerDependenciesMeta": { + "supports-color": { + "optional": true + } + } + }, + "node_modules/dunder-proto": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/dunder-proto/-/dunder-proto-1.0.1.tgz", + "integrity": "sha512-KIN/nDJBQRcXw0MLVhZE9iQHmG68qAVIBg9CqmUYjmQIhgij9U5MFvrqkUL5FbtyyzZuOeOt0zdeRe4UY7ct+A==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind-apply-helpers": "^1.0.1", + "es-errors": "^1.3.0", + "gopd": "^1.2.0" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/es-define-property": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/es-define-property/-/es-define-property-1.0.1.tgz", + "integrity": "sha512-e3nRfgfUZ4rNGL232gUgX06QNyyez04KdjFrF+LTRoOXmrOgFKDg4BCdsjW8EnT69eqdYGmRpJwiPVYNrCaW3g==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/es-errors": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/es-errors/-/es-errors-1.3.0.tgz", + "integrity": "sha512-Zf5H2Kxt2xjTvbJvP2ZWLEICxA6j+hAmMzIlypy4xcBg1vKVnx89Wy0GbS+kf5cwCVFFzdCFh2XSCFNULS6csw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/es-object-atoms": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/es-object-atoms/-/es-object-atoms-1.1.1.tgz", + "integrity": "sha512-FGgH2h8zKNim9ljj7dankFPcICIK9Cp5bm+c2gQSYePhpaG5+esrLODihIorn+Pe6FGJzWhXQotPv73jTaldXA==", + "dev": true, + "license": "MIT", + "dependencies": { + "es-errors": "^1.3.0" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/esbuild": { + "version": "0.25.12", + "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.25.12.tgz", + "integrity": "sha512-bbPBYYrtZbkt6Os6FiTLCTFxvq4tt3JKall1vRwshA3fdVztsLAatFaZobhkBC8/BrPetoa0oksYoKXoG4ryJg==", + "dev": true, + "hasInstallScript": true, + "license": "MIT", + "bin": { + "esbuild": "bin/esbuild" + }, + "engines": { + "node": ">=18" + }, + "optionalDependencies": { + "@esbuild/aix-ppc64": "0.25.12", + "@esbuild/android-arm": "0.25.12", + "@esbuild/android-arm64": "0.25.12", + "@esbuild/android-x64": "0.25.12", + "@esbuild/darwin-arm64": "0.25.12", + "@esbuild/darwin-x64": "0.25.12", + "@esbuild/freebsd-arm64": "0.25.12", + "@esbuild/freebsd-x64": "0.25.12", + "@esbuild/linux-arm": "0.25.12", + "@esbuild/linux-arm64": "0.25.12", + "@esbuild/linux-ia32": "0.25.12", + "@esbuild/linux-loong64": "0.25.12", + "@esbuild/linux-mips64el": "0.25.12", + "@esbuild/linux-ppc64": "0.25.12", + "@esbuild/linux-riscv64": "0.25.12", + "@esbuild/linux-s390x": "0.25.12", + "@esbuild/linux-x64": "0.25.12", + "@esbuild/netbsd-arm64": "0.25.12", + "@esbuild/netbsd-x64": "0.25.12", + "@esbuild/openbsd-arm64": "0.25.12", + "@esbuild/openbsd-x64": "0.25.12", + "@esbuild/openharmony-arm64": "0.25.12", + "@esbuild/sunos-x64": "0.25.12", + "@esbuild/win32-arm64": "0.25.12", + "@esbuild/win32-ia32": "0.25.12", + "@esbuild/win32-x64": "0.25.12" + } + }, + "node_modules/eventemitter3": { + "version": "4.0.7", + "resolved": "https://registry.npmjs.org/eventemitter3/-/eventemitter3-4.0.7.tgz", + "integrity": "sha512-8guHBZCwKnFhYdHr2ysuRWErTwhoN2X8XELRlrRwpmfeY2jjuUN4taQMsULKUVo1K4DvZl+0pgfyoysHxvmvEw==", + "dev": true, + "license": "MIT" + }, + "node_modules/follow-redirects": { + "version": "1.15.11", + "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.15.11.tgz", + "integrity": "sha512-deG2P0JfjrTxl50XGCDyfI97ZGVCxIpfKYmfyrQ54n5FO/0gfIES8C/Psl6kWVDolizcaaxZJnTS0QSMxvnsBQ==", + "dev": true, + "funding": [ + { + "type": "individual", + "url": "https://github.com/sponsors/RubenVerborgh" + } + ], + "license": "MIT", + "engines": { + "node": ">=4.0" + }, + "peerDependenciesMeta": { + "debug": { + "optional": true + } + } + }, + "node_modules/fs-extra": { + "version": "11.3.2", + "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-11.3.2.tgz", + "integrity": "sha512-Xr9F6z6up6Ws+NjzMCZc6WXg2YFRlrLP9NQDO3VQrWrfiojdhS56TzueT88ze0uBdCTwEIhQ3ptnmKeWGFAe0A==", + "dev": true, + "license": "MIT", + "dependencies": { + "graceful-fs": "^4.2.0", + "jsonfile": "^6.0.1", + "universalify": "^2.0.0" + }, + "engines": { + "node": ">=14.14" + } + }, + "node_modules/function-bind": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.2.tgz", + "integrity": "sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==", + "dev": true, + "license": "MIT", + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/get-intrinsic": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.3.0.tgz", + "integrity": "sha512-9fSjSaos/fRIVIp+xSJlE6lfwhES7LNtKaCBIamHsjr2na1BiABJPo0mOjjz8GJDURarmCPGqaiVg5mfjb98CQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind-apply-helpers": "^1.0.2", + "es-define-property": "^1.0.1", + "es-errors": "^1.3.0", + "es-object-atoms": "^1.1.1", + "function-bind": "^1.1.2", + "get-proto": "^1.0.1", + "gopd": "^1.2.0", + "has-symbols": "^1.1.0", + "hasown": "^2.0.2", + "math-intrinsics": "^1.1.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/get-proto": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/get-proto/-/get-proto-1.0.1.tgz", + "integrity": "sha512-sTSfBjoXBp89JvIKIefqw7U2CCebsc74kiY6awiGogKtoSGbgjYE/G/+l9sF3MWFPNc9IcoOC4ODfKHfxFmp0g==", + "dev": true, + "license": "MIT", + "dependencies": { + "dunder-proto": "^1.0.1", + "es-object-atoms": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/gopd": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/gopd/-/gopd-1.2.0.tgz", + "integrity": "sha512-ZUKRh6/kUFoAiTAtTYPZJ3hw9wNxx+BIBOijnlG9PnrJsCcSjs1wyyD6vJpaYtgnzDrKYRSqf3OO6Rfa93xsRg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/graceful-fs": { + "version": "4.2.11", + "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.11.tgz", + "integrity": "sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==", + "dev": true, + "license": "ISC" + }, + "node_modules/has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/has-symbols": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.1.0.tgz", + "integrity": "sha512-1cDNdwJ2Jaohmb3sg4OmKaMBwuC48sYni5HUw2DvsC8LjGTLK9h+eb1X6RyuOHe4hT0ULCW68iomhjUoKUqlPQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/hasown": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/hasown/-/hasown-2.0.2.tgz", + "integrity": "sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "function-bind": "^1.1.2" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/he": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/he/-/he-1.2.0.tgz", + "integrity": "sha512-F/1DnUGPopORZi0ni+CvrCgHQ5FyEAHRLSApuYWMmrbSwoN2Mn/7k+Gl38gJnR7yyDZk6WLXwiGod1JOWNDKGw==", + "dev": true, + "license": "MIT", + "bin": { + "he": "bin/he" + } + }, + "node_modules/html-encoding-sniffer": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/html-encoding-sniffer/-/html-encoding-sniffer-3.0.0.tgz", + "integrity": "sha512-oWv4T4yJ52iKrufjnyZPkrN0CH3QnrUqdB6In1g5Fe1mia8GmF36gnfNySxoZtxD5+NmYw1EElVXiBk93UeskA==", + "dev": true, + "license": "MIT", + "dependencies": { + "whatwg-encoding": "^2.0.0" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/http-proxy": { + "version": "1.18.1", + "resolved": "https://registry.npmjs.org/http-proxy/-/http-proxy-1.18.1.tgz", + "integrity": "sha512-7mz/721AbnJwIVbnaSv1Cz3Am0ZLT/UBwkC92VlxhXv/k/BBQfM2fXElQNC27BVGr0uwUpplYPQM9LnaBMR5NQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "eventemitter3": "^4.0.0", + "follow-redirects": "^1.0.0", + "requires-port": "^1.0.0" + }, + "engines": { + "node": ">=8.0.0" + } + }, + "node_modules/http-server": { + "version": "14.1.1", + "resolved": "https://registry.npmjs.org/http-server/-/http-server-14.1.1.tgz", + "integrity": "sha512-+cbxadF40UXd9T01zUHgA+rlo2Bg1Srer4+B4NwIHdaGxAGGv59nYRnGGDJ9LBk7alpS0US+J+bLLdQOOkJq4A==", + "dev": true, + "license": "MIT", + "dependencies": { + "basic-auth": "^2.0.1", + "chalk": "^4.1.2", + "corser": "^2.0.1", + "he": "^1.2.0", + "html-encoding-sniffer": "^3.0.0", + "http-proxy": "^1.18.1", + "mime": "^1.6.0", + "minimist": "^1.2.6", + "opener": "^1.5.1", + "portfinder": "^1.0.28", + "secure-compare": "3.0.1", + "union": "~0.5.0", + "url-join": "^4.0.1" + }, + "bin": { + "http-server": "bin/http-server" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/iconv-lite": { + "version": "0.6.3", + "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.6.3.tgz", + "integrity": "sha512-4fCk79wshMdzMp2rH06qWrJE4iolqLhCUH+OiuIgU++RB0+94NlDL81atO7GX55uUKueo0txHNtvEyI6D7WdMw==", + "dev": true, + "license": "MIT", + "dependencies": { + "safer-buffer": ">= 2.1.2 < 3.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/jsonfile": { + "version": "6.2.0", + "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-6.2.0.tgz", + "integrity": "sha512-FGuPw30AdOIUTRMC2OMRtQV+jkVj2cfPqSeWXv1NEAJ1qZ5zb1X6z1mFhbfOB/iy3ssJCD+3KuZ8r8C3uVFlAg==", + "dev": true, + "license": "MIT", + "dependencies": { + "universalify": "^2.0.0" + }, + "optionalDependencies": { + "graceful-fs": "^4.1.6" + } + }, + "node_modules/math-intrinsics": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/math-intrinsics/-/math-intrinsics-1.1.0.tgz", + "integrity": "sha512-/IXtbwEk5HTPyEwyKX6hGkYXxM9nbj64B+ilVJnC/R6B0pH5G4V3b0pVbL7DBj4tkhBAppbQUlf6F6Xl9LHu1g==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/mime": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/mime/-/mime-1.6.0.tgz", + "integrity": "sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg==", + "dev": true, + "license": "MIT", + "bin": { + "mime": "cli.js" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/minimist": { + "version": "1.2.8", + "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.8.tgz", + "integrity": "sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA==", + "dev": true, + "license": "MIT", + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/ms": { + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", + "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==", + "dev": true, + "license": "MIT" + }, + "node_modules/object-inspect": { + "version": "1.13.4", + "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.13.4.tgz", + "integrity": "sha512-W67iLl4J2EXEGTbfeHCffrjDfitvLANg0UlX3wFUUSTx92KXRFegMHUVgSqE+wvhAbi4WqjGg9czysTV2Epbew==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/opener": { + "version": "1.5.2", + "resolved": "https://registry.npmjs.org/opener/-/opener-1.5.2.tgz", + "integrity": "sha512-ur5UIdyw5Y7yEj9wLzhqXiy6GZ3Mwx0yGI+5sMn2r0N0v3cKJvUmFH5yPP+WXh9e0xfyzyJX95D8l088DNFj7A==", + "dev": true, + "license": "(WTFPL OR MIT)", + "bin": { + "opener": "bin/opener-bin.js" + } + }, + "node_modules/portfinder": { + "version": "1.0.38", + "resolved": "https://registry.npmjs.org/portfinder/-/portfinder-1.0.38.tgz", + "integrity": "sha512-rEwq/ZHlJIKw++XtLAO8PPuOQA/zaPJOZJ37BVuN97nLpMJeuDVLVGRwbFoBgLudgdTMP2hdRJP++H+8QOA3vg==", + "dev": true, + "license": "MIT", + "dependencies": { + "async": "^3.2.6", + "debug": "^4.3.6" + }, + "engines": { + "node": ">= 10.12" + } + }, + "node_modules/prismjs": { + "version": "1.30.0", + "resolved": "https://registry.npmjs.org/prismjs/-/prismjs-1.30.0.tgz", + "integrity": "sha512-DEvV2ZF2r2/63V+tK8hQvrR2ZGn10srHbXviTlcv7Kpzw8jWiNTqbVgjO3IY8RxrrOUF8VPMQQFysYYYv0YZxw==", + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/qs": { + "version": "6.14.0", + "resolved": "https://registry.npmjs.org/qs/-/qs-6.14.0.tgz", + "integrity": "sha512-YWWTjgABSKcvs/nWBi9PycY/JiPJqOD4JA6o9Sej2AtvSGarXxKC3OQSk4pAarbdQlKAh5D4FCQkJNkW+GAn3w==", + "dev": true, + "license": "BSD-3-Clause", + "dependencies": { + "side-channel": "^1.1.0" + }, + "engines": { + "node": ">=0.6" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/requires-port": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/requires-port/-/requires-port-1.0.0.tgz", + "integrity": "sha512-KigOCHcocU3XODJxsu8i/j8T9tzT4adHiecwORRQ0ZZFcp7ahwXuRU1m+yuO90C5ZUyGeGfocHDI14M3L3yDAQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/safe-buffer": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", + "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", + "dev": true, + "license": "MIT" + }, + "node_modules/safer-buffer": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", + "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==", + "dev": true, + "license": "MIT" + }, + "node_modules/secure-compare": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/secure-compare/-/secure-compare-3.0.1.tgz", + "integrity": "sha512-AckIIV90rPDcBcglUwXPF3kg0P0qmPsPXAj6BBEENQE1p5yA1xfmDJzfi1Tappj37Pv2mVbKpL3Z1T+Nn7k1Qw==", + "dev": true, + "license": "MIT" + }, + "node_modules/side-channel": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/side-channel/-/side-channel-1.1.0.tgz", + "integrity": "sha512-ZX99e6tRweoUXqR+VBrslhda51Nh5MTQwou5tnUDgbtyM0dBgmhEDtWGP/xbKn6hqfPRHujUNwz5fy/wbbhnpw==", + "dev": true, + "license": "MIT", + "dependencies": { + "es-errors": "^1.3.0", + "object-inspect": "^1.13.3", + "side-channel-list": "^1.0.0", + "side-channel-map": "^1.0.1", + "side-channel-weakmap": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/side-channel-list": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/side-channel-list/-/side-channel-list-1.0.0.tgz", + "integrity": "sha512-FCLHtRD/gnpCiCHEiJLOwdmFP+wzCmDEkc9y7NsYxeF4u7Btsn1ZuwgwJGxImImHicJArLP4R0yX4c2KCrMrTA==", + "dev": true, + "license": "MIT", + "dependencies": { + "es-errors": "^1.3.0", + "object-inspect": "^1.13.3" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/side-channel-map": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/side-channel-map/-/side-channel-map-1.0.1.tgz", + "integrity": "sha512-VCjCNfgMsby3tTdo02nbjtM/ewra6jPHmpThenkTYh8pG9ucZ/1P8So4u4FGBek/BjpOVsDCMoLA/iuBKIFXRA==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bound": "^1.0.2", + "es-errors": "^1.3.0", + "get-intrinsic": "^1.2.5", + "object-inspect": "^1.13.3" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/side-channel-weakmap": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/side-channel-weakmap/-/side-channel-weakmap-1.0.2.tgz", + "integrity": "sha512-WPS/HvHQTYnHisLo9McqBHOJk2FkHO/tlpvldyrnem4aeQp4hai3gythswg6p01oSoTl58rcpiFAjF2br2Ak2A==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bound": "^1.0.2", + "es-errors": "^1.3.0", + "get-intrinsic": "^1.2.5", + "object-inspect": "^1.13.3", + "side-channel-map": "^1.0.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "dev": true, + "license": "MIT", + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/union": { + "version": "0.5.0", + "resolved": "https://registry.npmjs.org/union/-/union-0.5.0.tgz", + "integrity": "sha512-N6uOhuW6zO95P3Mel2I2zMsbsanvvtgn6jVqJv4vbVcz/JN0OkL9suomjQGmWtxJQXOCqUJvquc1sMeNz/IwlA==", + "dev": true, + "dependencies": { + "qs": "^6.4.0" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/universalify": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/universalify/-/universalify-2.0.1.tgz", + "integrity": "sha512-gptHNQghINnc/vTGIk0SOFGFNXw7JVrlRUtConJRlvaw6DuX0wO5Jeko9sWrMBhh+PsYAZ7oXAiOnf/UKogyiw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 10.0.0" + } + }, + "node_modules/url-join": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/url-join/-/url-join-4.0.1.tgz", + "integrity": "sha512-jk1+QP6ZJqyOiuEI9AEWQfju/nB2Pw466kbA0LEZljHwKeMgd9WrAEgEGxjPDD2+TNbbb37rTyhEfrCXfuKXnA==", + "dev": true, + "license": "MIT" + }, + "node_modules/whatwg-encoding": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/whatwg-encoding/-/whatwg-encoding-2.0.0.tgz", + "integrity": "sha512-p41ogyeMUrw3jWclHWTQg1k05DSVXPLcVxRTYsXUk+ZooOCZLcoYgPZ/HL/D/N+uQPOtcp1me1WhBEaX02mhWg==", + "dev": true, + "license": "MIT", + "dependencies": { + "iconv-lite": "0.6.3" + }, + "engines": { + "node": ">=12" + } + } + } +} diff --git a/package.json b/package.json new file mode 100644 index 0000000..9414767 --- /dev/null +++ b/package.json @@ -0,0 +1,20 @@ +{ + "name": "adelie", + "version": "0.0.1", + "private": true, + "scripts": { + "build": "NODE_ENV=production node esbuild.config.js", + "dev": "node esbuild.config.js", + "clean": "rm -rf dist", + "serve": "npx http-server dist -p 8080 -o", + "dev:serve": "npm run dev && npm run serve" + }, + "dependencies": { + "prismjs": "^1.29.0" + }, + "devDependencies": { + "esbuild": "^0.25.5", + "fs-extra": "^11.2.0", + "http-server": "^14.1.1" + } +} diff --git a/static/fonts/Maple.woff2 b/src/assets/fonts/Maple.woff2 Binary files differindex d3641fe..d3641fe 100644 --- a/static/fonts/Maple.woff2 +++ b/src/assets/fonts/Maple.woff2 diff --git a/static/img/bg.png b/src/assets/img/bg.png Binary files differindex ea94170..ea94170 100644 --- a/static/img/bg.png +++ b/src/assets/img/bg.png diff --git a/static/img/coffee.svg b/src/assets/img/coffee.svg index 6af3eb0..6af3eb0 100644 --- a/static/img/coffee.svg +++ b/src/assets/img/coffee.svg diff --git a/static/img/favicon.ico b/src/assets/img/favicon.ico Binary files differindex e441116..e441116 100644 --- a/static/img/favicon.ico +++ b/src/assets/img/favicon.ico diff --git a/static/oneko/oneko.gif b/src/assets/oneko/oneko.gif Binary files differindex a009c2c..a009c2c 100644 --- a/static/oneko/oneko.gif +++ b/src/assets/oneko/oneko.gif diff --git a/static/css/style.css b/src/css/style.css index c51d1e0..50c6f48 100644 --- a/static/css/style.css +++ b/src/css/style.css @@ -1,99 +1,141 @@ :root { - --bg: #f9f5f0; - --bg-pattern: #f0ebe5; - --fg: #2a1810; - - /* Primary colors */ - --primary: #e8739d; - --primary-light: #f08db5; - --primary-dark: #d85980; - - /* Secondary colors */ - --secondary: #b19cd9; - --secondary-light: #c4b5fd; - --secondary-dark: #9d7eb8; - - /* Accent colors */ - --accent-brown: #8b6f47; - --accent-brown-light: #a8865b; - --accent-brown-dark: #6e5837; - - /* Status colors */ - --success: #4caf50; - --error: #d32f2f; - --warning: #ff9800; - --info: #2196f3; - - /* Neutral colors */ - --border: #2a1810; - --surface: #ffe8f0; - --surface-alt: #fdfcfb; - --muted: #6b5d54; - --border-light: #c0c0c0; - - /* Legacy aliases */ - --accent-pink: #e8739d; - --accent-lavender: #b19cd9; - + /* Win95 "strawberry latte" tokens */ + + /* Desktop (rarely used, but handy for full-page demos) */ + --desktop: #d7a5b7; + + /* Page + surfaces */ + --bg: #f4ece7; /* page behind windows */ + --bg-pattern: #efe5df; + + /* Background texture (dither/checker overlay) */ + --dither-ink: rgba(59, 46, 44, 0.22); + --dither-opacity: 0.18; + --surface: #e9dcd5; /* window face */ + --surface-alt: #fff7f2; /* milk highlight */ + + /* Text */ + --fg: #2a1f1d; + --muted: #6a5550; + + /* 3D border system */ + --border: #3b2e2c; + --border-light: #fff7f2; + --border-dark: #8e7670; + + /* Girly coffee accents */ + --primary: #e56aa6; /* strawberry */ + --primary-light: #f08dbe; /* strawberry milk */ + --primary-dark: #c84d86; /* rose */ + + --secondary: #b69cff; /* lilac */ + --secondary-light: #d7c8ff; + --secondary-dark: #8f78d6; + + --accent-brown: #b88a68; /* latte */ + --accent-brown-light: #d4a574; + --accent-brown-dark: #7a5245; + + /* Title bar (Win95-ish window chrome) */ + --titlebar-a: #d85b9b; + --titlebar-b: #7a3e8e; + --titlebar-fg: #fff7f2; + + /* Links */ + --link: #c84d86; + --link-visited: #6f2f80; + --link-active: #b5173d; + + /* Keep existing names as aliases */ + --accent-pink: var(--primary); + --accent-lavender: var(--secondary); + + /* Status colors (slightly softened) */ + --success: #2e8b57; + --error: #b3261e; + --warning: #b7791f; + --info: #2b6cb0; + + /* Spacing */ --space-xs: 0.5rem; --space-sm: 1rem; --space-md: 1.5rem; --space-lg: 2rem; --space-xl: 3rem; + /* Borders */ --border-width: 2px; --border-style: solid; - --font-mono: "Mono", monospace; - --line-height: 1.4; + /* Type */ + --font-mono: "Mono", ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, "Liberation Mono", "Courier New", monospace; + --line-height: 1.35; + + /* Shadows */ + --shadow-sm: 1px 1px 0; + --shadow-md: 2px 2px 0; + --shadow-lg: 3px 3px 0; + --shadow-color: rgba(0, 0, 0, 0.22); + --shadow-box: 2px 2px 0 rgba(0, 0, 0, 0.12); + --shadow-button: 1px 1px 0 rgba(0, 0, 0, 0.18); - --shadow-sm: 1px 1px 0, 2px 2px 0, 1px 2px 0; - --shadow-md: 1px 1px 0, 2px 2px 0, 3px 3px 0, 2px 1px 0; - --shadow-lg: 1px 1px 0, 2px 2px 0, 3px 3px 0, 4px 4px 0, 2px 1px 0, 1px 2px 0, - 3px 1px 0; - --shadow-color: rgba(42, 24, 16, 0.5); - --shadow-box: 3px 3px 0 rgba(0, 0, 0, 0.2); - --shadow-button: 2px 2px 0 rgba(0, 0, 0, 0.2); - --highlight: rgba(255, 255, 255, 0.4); - --lowlight: rgba(42, 24, 16, 0.6); + --highlight: rgba(255, 247, 242, 0.9); + --lowlight: rgba(59, 46, 44, 0.55); --content-max-width: 1000px; } [data-theme="dark"] { - --bg: #35302a; - --bg-pattern: #2b2620; - --fg: #f5f5f5; + /* Espresso-night variant */ + --bg: #2d2523; + --bg-pattern: #241e1c; + + --dither-ink: rgba(255, 247, 242, 0.12); + --dither-opacity: 0.14; + --surface: #3b312f; + --surface-alt: #463a37; - --primary: #e8739d; - --primary-light: #f08db5; - --primary-dark: #d85980; + --fg: #f9efea; + --muted: #cbb8b1; - --secondary: #b19cd9; - --secondary-light: #c4b5fd; - --secondary-dark: #9d7eb8; + --border: #f1e6e0; + --border-light: #6e5b57; + --border-dark: #120d0c; - --accent-brown: #d4a574; - --accent-brown-light: #e8b896; - --accent-brown-dark: #b8885a; + --primary: #f06aa6; + --primary-light: #ff97c8; + --primary-dark: #d94b8e; - --border: #e8e8e8; - --border-light: #8b7d6b; - --surface: #3f3932; - --surface-alt: #47403a; - --muted: #a89f94; + --secondary: #b69cff; + --secondary-light: #d7c8ff; + --secondary-dark: #8f78d6; - --accent-pink: #e8739d; - --accent-lavender: #b19cd9; + --accent-brown: #a57353; + --accent-brown-light: #c9936a; + --accent-brown-dark: #6b4a34; - --shadow-color: rgba(0, 0, 0, 0.8); - --highlight: rgba(255, 255, 255, 0.3); - --lowlight: rgba(0, 0, 0, 0.8); + --titlebar-a: #b04a80; + --titlebar-b: #4f245e; + --titlebar-fg: #fff7f2; + + --link: #ff97c8; + --link-visited: #d7c8ff; + --link-active: #fff0f7; + + /* Status colors (brightened for dark mode) */ + --success: #4caf50; + --error: #ff6b6b; + --warning: #ffa500; + --info: #64b5f6; + + --shadow-color: rgba(0, 0, 0, 0.75); + --highlight: rgba(255, 255, 255, 0.2); + --lowlight: rgba(0, 0, 0, 0.85); } @font-face { font-family: "Mono"; - src: url("/static/fonts/Maple.woff2") format("woff2"); + src: url("../assets/fonts/Maple.woff2") format("woff2"); font-display: swap; font-weight: normal; } @@ -101,7 +143,7 @@ @supports (font-synthesis: none) { @font-face { font-family: "Mono"; - src: url("/static/fonts/Maple.woff2") format("woff2"); + src: url("../assets/fonts/Maple.woff2") format("woff2"); font-synthesis: none; } } @@ -113,11 +155,21 @@ margin: 0; padding: 0; cursor: - url('data:image/svg+xml;utf8,<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 32 24" width="32" height="24"><path d="M1 3h1v1h1v1h1v1h1v1h1v1h1v1h1v1h1v1h1v1h1v1h1v1h1v2H9v1h1v2h1v2h-1v1H8v-1H7v-2H6v-2H5v1H4v1H3v1H1" fill="%23ff69b4" stroke="%23b19cd9" stroke-width="0.5"/><path d="M2 5h1v1h1v1h1v1h1v1h1v1h1v1h1v1h1v1h1v1h1v1H8v2h1v2h1v2H8v-2H7v-2H6v-1H5v1H4v1H3v1H2" fill="white" stroke="%23ff69b4" stroke-width="0.5"/></svg>') + url('data:image/svg+xml;utf8,<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 32 24" width="32" height="24"><path d="M1 3h1v1h1v1h1v1h1v1h1v1h1v1h1v1h1v1h1v1h1v1h1v2H9v1h1v2h1v2h-1v1H8v-1H7v-2H6v-2H5v1H4v1H3v1H1" fill="%23ff69b4" stroke="%23b19cd9" stroke-width="0.5"/><path d="M2 5h1v1h1v1h1v1h1v1h1v1h1v1h1v1h1v1h1v1h1v1H8v2h1v2h1v2H8v-2H7v-2H6v-1H5v1H4v1H3v1H2" fill="white" stroke="%23ff69b4" stroke-width="0.5"/></svg>') 0 0, auto !important; } +::selection { + background: var(--primary); + color: var(--surface-alt); +} + +:focus-visible { + outline: 1px dotted var(--fg); + outline-offset: 2px; +} + html { font-size: 16px; background-color: var(--bg); @@ -137,19 +189,19 @@ html::before { height: 100%; background-image: linear-gradient( 45deg, - rgba(0, 0, 0, 0.2) 25%, + var(--dither-ink) 25%, transparent 25%, transparent 75%, - rgba(0, 0, 0, 0.2) 75% + var(--dither-ink) 75% ), linear-gradient( 45deg, - rgba(0, 0, 0, 0.2) 25%, + var(--dither-ink) 25%, transparent 25%, transparent 75%, - rgba(0, 0, 0, 0.2) 75% + var(--dither-ink) 75% ), - url("/static/img/bg.png"); + url("../assets/img/bg.png"); background-size: 10px 10px, 10px 10px, @@ -159,7 +211,7 @@ html::before { 5px 5px, 0 0; background-repeat: repeat; - opacity: 0.15; + opacity: var(--dither-opacity); z-index: -1; pointer-events: none; } @@ -187,7 +239,10 @@ body { ::-webkit-scrollbar-track { background: var(--bg); - border: 2px solid var(--border-light); + border: 2px solid var(--border); + box-shadow: + inset 1px 1px 0 var(--border-light), + inset -1px -1px 0 var(--border-dark); } ::-webkit-scrollbar-thumb { @@ -222,47 +277,49 @@ h4, h5, h6 { font-family: var(--font-mono); - font-weight: bold; - line-height: 1.2; + font-weight: 700; + line-height: 1.15; margin-bottom: var(--space-md); - border: 2px solid var(--border-light); - padding: var(--space-sm); - background-size: 4px 4px; - background-color: var(--accent-pink); - background-position: - 0 0, - 2px 2px; - color: var(--bg); + color: var(--fg); } h1 { font-size: 2rem; margin-bottom: var(--space-lg); + background: linear-gradient(90deg, var(--titlebar-a), var(--titlebar-b)); } + +/* "Titlebar" headings: retro, but still cute */ +h1, +h2, +h3 { + padding: 0.55rem 0.75rem; + border: var(--border-width) solid var(--border); + box-shadow: + inset 1px 1px 0 var(--border-light), + inset -1px -1px 0 var(--border-dark); + color: var(--titlebar-fg); + text-shadow: 1px 1px 0 rgba(0, 0, 0, 0.25); +} + h2 { font-size: 1.5rem; - background-size: 4px 4px; - background-position: - 0 0, - 2px 2px; - background-color: var(--accent-lavender); - margin-bottom: var(--space-md); + background: linear-gradient(90deg, var(--titlebar-a), var(--titlebar-b)); } + h3 { font-size: 1.25rem; - background-size: 4px 4px; - background-position: - 0 0, - 2px 2px; - background-color: var(--accent-brown); - box-shadow: var(--shadow-box); + background: linear-gradient(90deg, var(--accent-brown-dark), var(--accent-brown)); } + h4 { font-size: 1.1rem; } + h5 { font-size: 1rem; } + h6 { font-size: 0.9rem; } @@ -272,15 +329,23 @@ p { } a { - color: var(--accent-pink); - text-decoration: none; - border-bottom: 2px solid var(--accent-pink); - font-weight: bold; + color: var(--link); + text-decoration: underline; + text-decoration-thickness: 2px; + text-underline-offset: 2px; +} + +a:visited { + color: var(--link-visited); } a:hover { - background: var(--accent-pink); - color: var(--bg); + background: var(--primary-light); + color: var(--fg); +} + +a:active { + color: var(--link-active); } small { @@ -314,59 +379,59 @@ table { width: 100%; border-collapse: collapse; margin: var(--space-md) 0; - border: 2px solid var(--border-light); - background: var(--bg); + border: var(--border-width) solid var(--border); + background: var(--surface); box-shadow: - inset 1px 1px 0 rgba(255, 255, 255, 0.3), - inset -1px -1px 0 rgba(0, 0, 0, 0.6), - 3px 3px 0 rgba(0, 0, 0, 0.15); + inset 1px 1px 0 var(--border-light), + inset -1px -1px 0 var(--border-dark), + 3px 3px 0 rgba(0, 0, 0, 0.12); } thead { - background: var(--secondary); - color: var(--bg); - font-weight: bold; + background: linear-gradient(90deg, var(--titlebar-a), var(--titlebar-b)); + color: var(--titlebar-fg); + font-weight: 700; } th, td { padding: var(--space-xs) var(--space-sm); - border: 1px solid var(--border-light); + border: 1px solid var(--border-dark); text-align: left; } tbody tr:nth-child(odd) { - background: var(--surface-alt); + background: var(--surface-alt); } tbody tr:nth-child(even) { - background: var(--bg); + background: var(--surface); } tbody tr:hover { - background: rgba(232, 115, 157, 0.1); + background: color-mix(in srgb, var(--primary) 12%, transparent); } /* code */ code { - background: var(--bg); + background: var(--surface-alt); padding: 0.25rem 0.5rem; - border: 1px solid var(--border-light); + border: 1px solid var(--border-dark); font-size: 0.875rem; font-family: var(--font-mono); } pre { - background: var(--bg); - border: 2px solid var(--border-light); + background: var(--surface-alt); + border: var(--border-width) solid var(--border); padding: var(--space-md); margin: var(--space-md) 0; overflow-x: auto; box-shadow: - inset 1px 1px 0 rgba(255, 255, 255, 0.3), - inset -1px -1px 0 rgba(0, 0, 0, 0.6), - 3px 3px 0 rgba(0, 0, 0, 0.15); + inset 1px 1px 0 var(--border-light), + inset -1px -1px 0 var(--border-dark), + 3px 3px 0 rgba(0, 0, 0, 0.12); } pre code { @@ -376,11 +441,95 @@ pre code { font-size: 0.875rem; } +/* Prism.js syntax highlighting */ + +.token.comment, +.token.prolog, +.token.doctype, +.token.cdata { + color: var(--muted); + font-style: italic; +} + +.token.punctuation { + color: var(--fg); +} + +.token.property, +.token.tag, +.token.boolean, +.token.number, +.token.constant, +.token.symbol { + color: var(--secondary-dark); +} + +.token.selector, +.token.attr-name, +.token.string, +.token.char, +.token.builtin { + color: var(--accent-brown-dark); +} + +.token.operator, +.token.entity, +.token.url, +.language-css .token.string, +.style .token.string { + color: var(--primary-dark); +} + +.token.atrule, +.token.attr-value, +.token.keyword { + color: var(--primary-dark); + font-weight: 700; +} + +.token.function, +.token.class-name { + color: var(--primary); + font-weight: 700; +} + +.token.regex, +.token.important, +.token.variable { + color: var(--accent-brown); +} + +.token.important, +.token.bold { + font-weight: bold; +} + +.token.italic { + font-style: italic; +} + +/* Dark theme variants */ + +[data-theme="dark"] .token.keyword, +[data-theme="dark"] .token.operator { + color: var(--primary-light); +} + +[data-theme="dark"] .token.string, +[data-theme="dark"] .token.selector { + color: var(--accent-brown-light); +} + +[data-theme="dark"] .token.number, +[data-theme="dark"] .token.constant { + color: var(--secondary-light); +} + /* dividers */ hr { border: none; - border-top: 2px solid var(--border-light); + border-top: 2px solid var(--border-dark); margin: var(--space-lg) 0; height: 0; } @@ -393,14 +542,19 @@ header { left: 0; right: 0; z-index: 1000; - border-bottom: 2px outset var(--border-light); - padding: 0.4rem var(--space-md); + border-bottom: 2px solid var(--border); + padding: 0.45rem var(--space-md); margin-bottom: 0; - background: var(--surface); + background: linear-gradient(90deg, var(--titlebar-a), var(--titlebar-b)); + color: var(--titlebar-fg); display: flex; align-items: center; justify-content: space-between; gap: var(--space-md); + box-shadow: + inset 1px 1px 0 var(--border-light), + inset -1px -1px 0 var(--border-dark), + 0 2px 0 rgba(0, 0, 0, 0.08); } header h1 { @@ -412,10 +566,16 @@ header::before { display: inline-block; width: 1.5rem; height: 1.5rem; - background-image: url("/static/img/coffee.svg"); - background-size: contain; + background-image: url("../assets/img/coffee.svg"); + background-size: 1.1rem 1.1rem; + background-position: center; background-repeat: no-repeat; margin-right: 0.5rem; + background-color: var(--surface); + border: 2px outset var(--border-light); + box-shadow: + inset 1px 1px 0 var(--highlight), + inset -1px -1px 0 var(--lowlight); } nav { @@ -429,9 +589,24 @@ nav { nav a { font-size: 0.85rem; - padding: 0.2rem 0.4rem; - color: var(--fg); - border-bottom: 2px solid var(--accent-pink); + padding: 0.1rem 0.15rem; + color: var(--titlebar-fg); + text-decoration: none; + border-bottom: 2px solid color-mix(in srgb, var(--titlebar-fg) 55%, transparent); +} + +nav a:visited { + color: var(--titlebar-fg); +} + +nav a:hover { + background: color-mix(in srgb, var(--surface-alt) 18%, transparent); + border-bottom-color: var(--primary-light); +} + +nav a:active { + background: color-mix(in srgb, var(--surface-alt) 28%, transparent); + border-bottom-color: var(--primary); } main { @@ -439,15 +614,15 @@ main { } article { - border: 2px solid var(--border-light); + border: var(--border-width) solid var(--border); padding: var(--space-md); margin-bottom: var(--space-lg); background: var(--surface); box-shadow: - inset 1px 1px 0 rgba(255, 255, 255, 0.3), - inset -1px -1px 0 rgba(0, 0, 0, 0.6), - 4px 4px 0 rgba(0, 0, 0, 0.2), - 5px 5px 0 rgba(0, 0, 0, 0.08); + inset 1px 1px 0 var(--border-light), + inset -1px -1px 0 var(--border-dark), + 4px 4px 0 rgba(0, 0, 0, 0.14), + 5px 5px 0 rgba(0, 0, 0, 0.06); } article > :last-child { @@ -459,19 +634,22 @@ article h2 { border-left: none; border-right: none; border-top: none; + border-bottom: var(--border-width) solid var(--border); + box-shadow: none; + text-shadow: none; } footer { - border: 2px solid var(--border-light); + border: var(--border-width) solid var(--border); padding: var(--space-md); text-align: center; background: var(--surface); font-size: 0.875rem; box-shadow: - inset 1px 1px 0 rgba(255, 255, 255, 0.3), - inset -1px -1px 0 rgba(0, 0, 0, 0.6), - 4px 4px 0 rgba(0, 0, 0, 0.2), - 5px 5px 0 rgba(0, 0, 0, 0.08); + inset 1px 1px 0 var(--border-light), + inset -1px -1px 0 var(--border-dark), + 4px 4px 0 rgba(0, 0, 0, 0.14), + 5px 5px 0 rgba(0, 0, 0, 0.06); } footer > :last-child { @@ -487,16 +665,14 @@ textarea, select { font-family: var(--font-mono); padding: var(--space-xs) var(--space-sm); - border: 2px outset var(--border-light); - background: var(--bg); + border: 2px inset var(--border-light); + background: var(--surface-alt); color: var(--fg); font-size: 0.875rem; box-shadow: - inset 1px 1px 0 var(--highlight), - inset -1px -1px 0 var(--lowlight), - inset 2px 2px 0 rgba(255, 255, 255, 0.2), - inset -2px -2px 0 rgba(0, 0, 0, 0.4); - transition: border-color 0.2s, box-shadow 0.2s; + inset 1px 1px 0 var(--lowlight), + inset -1px -1px 0 var(--highlight); + transition: border-color 0.15s, box-shadow 0.15s; width: 100%; max-width: 100%; } @@ -518,11 +694,12 @@ select::placeholder { input:focus, textarea:focus, select:focus { - outline: none; + outline: 1px dotted var(--fg); + outline-offset: 2px; border-color: var(--primary); box-shadow: - inset 1px 1px 0 var(--highlight), - inset -1px -1px 0 var(--lowlight), + inset 1px 1px 0 var(--lowlight), + inset -1px -1px 0 var(--highlight), 0 0 0 2px var(--primary); } @@ -548,7 +725,7 @@ textarea { select { cursor: pointer; appearance: none; - background-image: url("data:image/svg+xml;charset=UTF-8,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%232a1810' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpolyline points='6 9 12 15 18 9'%3E%3C/polyline%3E%3C/svg%3E"); + background-image: url("data:image/svg+xml;charset=UTF-8,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%232a1f1d' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpolyline points='6 9 12 15 18 9'%3E%3C/polyline%3E%3C/svg%3E"); background-repeat: no-repeat; background-position: right 0.5rem center; background-size: 1.2em; @@ -556,7 +733,7 @@ select { } [data-theme="dark"] select { - background-image: url("data:image/svg+xml;charset=UTF-8,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23f5e6e8' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpolyline points='6 9 12 15 18 9'%3E%3C/polyline%3E%3C/svg%3E"); + background-image: url("data:image/svg+xml;charset=UTF-8,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23f9efea' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpolyline points='6 9 12 15 18 9'%3E%3C/polyline%3E%3C/svg%3E"); } option { @@ -581,9 +758,11 @@ input[type="radio"] { cursor: pointer; margin: 0 0.5rem 0 0; vertical-align: middle; - border: 2px solid var(--border-light); - box-shadow: inset 1px 1px 0 var(--highlight), inset -1px -1px 0 var(--lowlight); - background: var(--bg); + border: 2px inset var(--border-light); + box-shadow: + inset 1px 1px 0 var(--lowlight), + inset -1px -1px 0 var(--highlight); + background: var(--surface-alt); display: inline-flex; align-items: center; justify-content: center; @@ -598,6 +777,7 @@ input[type="radio"] { input[type="checkbox"]:checked, input[type="radio"]:checked { background: var(--primary); + border-style: inset; } label { @@ -677,7 +857,7 @@ input[type="checkbox"].toggle:checked::after { transform: translateY(-50%); font-size: 0.9rem; line-height: 1; - color: var(--bg); + color: var(--titlebar-fg); transition: opacity 0.2s; } @@ -799,99 +979,96 @@ legend { button { font-family: var(--font-mono); - font-weight: bold; + font-weight: 700; padding: var(--space-xs) var(--space-sm); border: 2px outset var(--border-light); - background: var(--secondary); - color: var(--bg); + background: var(--surface); + color: var(--fg); font-size: 0.875rem; box-shadow: - inset 1px 1px 0 rgba(255, 255, 255, 0.6), - inset -1px -1px 0 rgba(0, 0, 0, 0.8), - 3px 3px 0 rgba(0, 0, 0, 0.3), - 4px 4px 0 rgba(0, 0, 0, 0.1); + inset 1px 1px 0 var(--highlight), + inset -1px -1px 0 var(--lowlight), + 2px 2px 0 rgba(0, 0, 0, 0.18); transition: transform 0.05s, - box-shadow 0.05s; + box-shadow 0.05s, + background 0.1s; cursor: pointer; } button:hover { - background: var(--secondary-dark); - transform: translate(1px, 1px); - box-shadow: - inset 1px 1px 0 rgba(255, 255, 255, 0.6), - inset -1px -1px 0 rgba(0, 0, 0, 0.8), - 2px 2px 0 rgba(0, 0, 0, 0.3), - 3px 3px 0 rgba(0, 0, 0, 0.1); + background: var(--surface-alt); } button:active { - transform: translate(4px, 4px); + transform: translate(1px, 1px); + border-style: inset; box-shadow: - inset 1px 1px 0 rgba(0, 0, 0, 0.6), - inset -1px -1px 0 rgba(255, 255, 255, 0.3); + inset 1px 1px 0 var(--lowlight), + inset -1px -1px 0 var(--highlight); } /* button variants */ button.primary { background: var(--primary); - color: var(--bg); + color: var(--surface-alt); } button.primary:hover { + background: var(--primary-light); +} + +button.primary:active { background: var(--primary-dark); } button.secondary { background: var(--secondary); - color: var(--bg); + color: var(--fg); } button.secondary:hover { + background: var(--secondary-light); +} + +button.secondary:active { background: var(--secondary-dark); } -button.success { - background: var(--success); - color: white; +button.success, +button.error, +button.warning, +button.info { + color: var(--surface-alt); } -button.success:hover { - background: #45a049; +button.success { + background: var(--success); } button.error { background: var(--error); - color: white; -} - -button.error:hover { - background: #da190b; } button.warning { background: var(--warning); - color: white; -} - -button.warning:hover { - background: #e68900; } button.info { background: var(--info); - color: white; } +button.success:hover, +button.error:hover, +button.warning:hover, button.info:hover { - background: #0b7dda; + filter: brightness(1.06); } button.contrast { background: var(--fg); - color: var(--bg); + color: var(--surface-alt); } button.contrast:hover { @@ -908,11 +1085,11 @@ button:disabled { .button-group { display: inline-flex; - border: 2px solid var(--border-light); + border: var(--border-width) solid var(--border); box-shadow: - inset 1px 1px 0 rgba(255, 255, 255, 0.3), - inset -1px -1px 0 rgba(0, 0, 0, 0.6), - 3px 3px 0 rgba(0, 0, 0, 0.15); + inset 1px 1px 0 var(--border-light), + inset -1px -1px 0 var(--border-dark), + 3px 3px 0 rgba(0, 0, 0, 0.12); } .button-group button { @@ -923,7 +1100,7 @@ button:disabled { } .button-group button:not(:last-child) { - border-right: 1px solid var(--border-light); + border-right: 1px solid var(--border-dark); } .button-group button:hover { @@ -941,33 +1118,33 @@ button:disabled { .alert { padding: var(--space-md); margin: var(--space-md) 0; - border: 2px solid var(--border-light); + border: var(--border-width) solid var(--border); border-left: 4px solid var(--info); background: var(--surface); box-shadow: - inset 1px 1px 0 rgba(255, 255, 255, 0.3), - inset -1px -1px 0 rgba(0, 0, 0, 0.6), - 3px 3px 0 rgba(0, 0, 0, 0.15); + inset 1px 1px 0 var(--border-light), + inset -1px -1px 0 var(--border-dark), + 3px 3px 0 rgba(0, 0, 0, 0.12); } .alert.success { border-left-color: var(--success); - background-color: rgba(76, 175, 80, 0.1); + background-color: color-mix(in srgb, var(--success) 10%, transparent); } .alert.error { border-left-color: var(--error); - background-color: rgba(244, 67, 54, 0.1); + background-color: color-mix(in srgb, var(--error) 10%, transparent); } .alert.warning { border-left-color: var(--warning); - background-color: rgba(255, 152, 0, 0.1); + background-color: color-mix(in srgb, var(--warning) 10%, transparent); } .alert.info { border-left-color: var(--info); - background-color: rgba(33, 150, 243, 0.1); + background-color: color-mix(in srgb, var(--info) 10%, transparent); } /* badges & pills */ @@ -976,40 +1153,44 @@ button:disabled { display: inline-block; padding: 0.25rem 0.5rem; margin: 0 0.25rem; - background: var(--secondary); - color: var(--bg); + background: var(--surface-alt); + color: var(--fg); font-size: 0.75rem; - font-weight: bold; - border: 1px solid var(--border-light); + font-weight: 700; + border: 1px solid var(--border-dark); + box-shadow: + inset 1px 1px 0 var(--border-light), + inset -1px -1px 0 var(--border-dark); } .badge.primary { background: var(--primary); + color: var(--surface-alt); } .badge.success { background: var(--success); - color: white; + color: var(--surface-alt); } .badge.error { background: var(--error); - color: white; + color: var(--surface-alt); } .badge.warning { background: var(--warning); - color: white; + color: var(--surface-alt); } .badge.info { background: var(--info); - color: white; + color: var(--surface-alt); } .badge.contrast { background: var(--fg); - color: var(--bg); + color: var(--surface-alt); } /* helpers */ diff --git a/static/index.html b/src/index.html index dcaa56b..c5f83a2 100644 --- a/static/index.html +++ b/src/index.html @@ -4,8 +4,8 @@ <meta charset="UTF-8" /> <meta name="viewport" content="width=device-width, initial-scale=1.0" /> <title>Liz CSS - Framework Demo</title> - <link rel="stylesheet" href="/static/css/style.css" /> - <link rel="icon" href="/static/img/favicon.ico" /> + <link rel="stylesheet" href="/bundle.css" /> + <link rel="icon" href="/img/favicon.ico" /> <style> .demo-section { margin-bottom: var(--space-xl); @@ -19,10 +19,13 @@ } .component-box { - border: 2px solid var(--border-light); + border: var(--border-width) solid var(--border); padding: var(--space-md); background: var(--surface); - box-shadow: var(--shadow-box); + box-shadow: + inset 1px 1px 0 var(--border-light), + inset -1px -1px 0 var(--border-dark), + var(--shadow-box); } .component-box > :last-child { @@ -61,10 +64,13 @@ display: inline-block; width: 40px; height: 40px; - border: 2px solid var(--border-light); + border: var(--border-width) solid var(--border); margin-right: var(--space-sm); vertical-align: middle; - box-shadow: var(--shadow-sm); + box-shadow: + inset 1px 1px 0 var(--border-light), + inset -1px -1px 0 var(--border-dark), + var(--shadow-sm); } </style> </head> @@ -92,7 +98,7 @@ class="color-swatch" style="background: var(--primary);" ></div> - <code>#ff69b4</code> + <code>#e56aa6</code> </div> </div> <div class="component-box"> @@ -102,7 +108,7 @@ class="color-swatch" style="background: var(--primary-light);" ></div> - <code>#ff85c0</code> + <code>#f08dbe</code> </div> </div> <div class="component-box"> @@ -112,7 +118,7 @@ class="color-swatch" style="background: var(--primary-dark);" ></div> - <code>#ff4a9f</code> + <code>#c84d86</code> </div> </div> </div> @@ -126,7 +132,7 @@ class="color-swatch" style="background: var(--secondary);" ></div> - <code>#b19cd9</code> + <code>#b69cff</code> </div> </div> <div class="component-box"> @@ -136,7 +142,7 @@ class="color-swatch" style="background: var(--secondary-light);" ></div> - <code>#c4b5fd</code> + <code>#d7c8ff</code> </div> </div> <div class="component-box"> @@ -146,7 +152,7 @@ class="color-swatch" style="background: var(--secondary-dark);" ></div> - <code>#9d7eb8</code> + <code>#8f78d6</code> </div> </div> </div> @@ -160,14 +166,14 @@ class="color-swatch" style="background: var(--success);" ></div> - <code>#4caf50</code> + <code>#2e8b57</code> </div> </div> <div class="component-box"> <span class="component-label">Error</span> <div style="display: flex; align-items: center;"> <div class="color-swatch" style="background: var(--error);"></div> - <code>#f44336</code> + <code>#b3261e</code> </div> </div> <div class="component-box"> @@ -177,14 +183,14 @@ class="color-swatch" style="background: var(--warning);" ></div> - <code>#ff9800</code> + <code>#b7791f</code> </div> </div> <div class="component-box"> <span class="component-label">Info</span> <div style="display: flex; align-items: center;"> <div class="color-swatch" style="background: var(--info);"></div> - <code>#2196f3</code> + <code>#2b6cb0</code> </div> </div> </div> @@ -485,7 +491,7 @@ <article> <h2>Code</h2> <p>Inline <code>const x = 42;</code> looks different from block code:</p> - <pre><code>function retro() { + <pre><code class="language-javascript">function retro() { return "That's totally rad!"; } @@ -588,6 +594,6 @@ retro(); // "That's totally rad!"</code></pre> <p>© 2025 Liz CSS Framework. Made with coffee and retro vibes.</p> </footer> - <script src="/static/js/script.js"></script> + <script src="/bundle.js"></script> </body> </html> diff --git a/static/oneko/oneko.js b/src/js/oneko.js index 058f168..dcf927f 100644 --- a/static/oneko/oneko.js +++ b/src/js/oneko.js @@ -1,6 +1,6 @@ // oneko.js: https://github.com/adryd325/oneko.js -(function oneko() { +export function initOneko() { const isReducedMotion = window.matchMedia(`(prefers-reduced-motion: reduce)`) === true || window.matchMedia(`(prefers-reduced-motion: reduce)`).matches === true; @@ -86,7 +86,7 @@ }; function init() { - let nekoFile = "/static/oneko/oneko.gif"; + let nekoFile = "/oneko/oneko.gif"; const curScript = document.currentScript; if (curScript && curScript.dataset.cat) { nekoFile = curScript.dataset.cat; @@ -281,4 +281,4 @@ } init(); -})(); +} diff --git a/static/js/script.js b/src/js/script.js index d04c09d..8ba3d82 100644 --- a/static/js/script.js +++ b/src/js/script.js @@ -1,3 +1,9 @@ +import Prism from 'prismjs'; +import 'prismjs/components/prism-javascript'; +import 'prismjs/components/prism-css'; +import 'prismjs/components/prism-markup'; +import { initOneko } from './oneko.js'; + (() => { const toggleButton = document.getElementById("theme-toggle"); const html = document.documentElement; @@ -74,3 +80,8 @@ setTimeout(() => particle.remove(), 800); }; })(); + +document.addEventListener('DOMContentLoaded', () => { + Prism.highlightAll(); + initOneko(); +}); |
