diff --git a/components.json b/components.json index 779a9d1..95c806a 100644 --- a/components.json +++ b/components.json @@ -1,8 +1,14 @@ { "$schema": "https://ui.shadcn.com/schema.json", + "style": "default", + "rsc": false, + "tsx": false, "tailwind": { + "config": "tailwind.config.ts", "css": "src/app.css", - "baseColor": "slate" + "baseColor": "slate", + "cssVariables": true, + "prefix": "" }, "aliases": { "components": "$lib/components", @@ -13,4 +19,4 @@ }, "typescript": true, "registry": "https://tw3.shadcn-svelte.com/registry/default" -} +} \ No newline at end of file diff --git a/package-lock.json b/package-lock.json index fdab00c..a3ae4f6 100644 --- a/package-lock.json +++ b/package-lock.json @@ -31,6 +31,7 @@ "@sveltejs/adapter-static": "^3.0.6", "@sveltejs/kit": "^2.9.0", "@sveltejs/vite-plugin-svelte": "^5.0.0", + "@tailwindcss/vite": "^4.1.18", "@tauri-apps/cli": "^2", "@types/marked": "^5.0.2", "autoprefixer": "^10.4.20", @@ -39,26 +40,14 @@ "svelte": "^5.0.0", "svelte-check": "^4.0.0", "tailwind-variants": "^0.2.1", - "tailwindcss": "^3.4.17", + "tailwindcss": "^4.1.18", "tailwindcss-animate": "^1.0.7", + "tw-animate-css": "^1.4.0", "typescript": "~5.6.2", "vaul-svelte": "^1.0.0-next.7", "vite": "^6.0.3" } }, - "node_modules/@alloc/quick-lru": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/@alloc/quick-lru/-/quick-lru-5.2.0.tgz", - "integrity": "sha512-UrcABB+4bUrFABwbluTIBErXwvbsU/V7TZWfmbgJfbkwiBuziS9gxdODUyuiecfdGQ85jglMW6juS3+z5TsKLw==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, "node_modules/@esbuild/aix-ppc64": { "version": "0.25.12", "resolved": "https://registry.npmjs.org/@esbuild/aix-ppc64/-/aix-ppc64-0.25.12.tgz", @@ -594,44 +583,6 @@ "svelte": "^5" } }, - "node_modules/@nodelib/fs.scandir": { - "version": "2.1.5", - "resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz", - "integrity": "sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==", - "dev": true, - "license": "MIT", - "dependencies": { - "@nodelib/fs.stat": "2.0.5", - "run-parallel": "^1.1.9" - }, - "engines": { - "node": ">= 8" - } - }, - "node_modules/@nodelib/fs.stat": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/@nodelib/fs.stat/-/fs.stat-2.0.5.tgz", - "integrity": "sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">= 8" - } - }, - "node_modules/@nodelib/fs.walk": { - "version": "1.2.8", - "resolved": "https://registry.npmjs.org/@nodelib/fs.walk/-/fs.walk-1.2.8.tgz", - "integrity": "sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg==", - "dev": true, - "license": "MIT", - "dependencies": { - "@nodelib/fs.scandir": "2.1.5", - "fastq": "^1.6.0" - }, - "engines": { - "node": ">= 8" - } - }, "node_modules/@polka/url": { "version": "1.0.0-next.29", "resolved": "https://registry.npmjs.org/@polka/url/-/url-1.0.0-next.29.tgz", @@ -979,6 +930,7 @@ "integrity": "sha512-Vp3zX/qlwerQmHMP6x0Ry1oY7eKKRcOWGc2P59srOp4zcqyn+etJyQpELgOi4+ZSUgteX8Y387NuwruLgGXLUQ==", "dev": true, "license": "MIT", + "peer": true, "dependencies": { "@standard-schema/spec": "^1.0.0", "@sveltejs/acorn-typescript": "^1.0.5", @@ -1018,6 +970,7 @@ "integrity": "sha512-Y1Cs7hhTc+a5E9Va/xwKlAJoariQyHY+5zBgCZg4PFWNYQ1nMN9sjK1zhw1gK69DuqVP++sht/1GZg1aRwmAXQ==", "dev": true, "license": "MIT", + "peer": true, "dependencies": { "@sveltejs/vite-plugin-svelte-inspector": "^4.0.1", "debug": "^4.4.1", @@ -1062,6 +1015,278 @@ "tslib": "^2.8.0" } }, + "node_modules/@tailwindcss/node": { + "version": "4.1.18", + "resolved": "https://registry.npmjs.org/@tailwindcss/node/-/node-4.1.18.tgz", + "integrity": "sha512-DoR7U1P7iYhw16qJ49fgXUlry1t4CpXeErJHnQ44JgTSKMaZUdf17cfn5mHchfJ4KRBZRFA/Coo+MUF5+gOaCQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@jridgewell/remapping": "^2.3.4", + "enhanced-resolve": "^5.18.3", + "jiti": "^2.6.1", + "lightningcss": "1.30.2", + "magic-string": "^0.30.21", + "source-map-js": "^1.2.1", + "tailwindcss": "4.1.18" + } + }, + "node_modules/@tailwindcss/oxide": { + "version": "4.1.18", + "resolved": "https://registry.npmjs.org/@tailwindcss/oxide/-/oxide-4.1.18.tgz", + "integrity": "sha512-EgCR5tTS5bUSKQgzeMClT6iCY3ToqE1y+ZB0AKldj809QXk1Y+3jB0upOYZrn9aGIzPtUsP7sX4QQ4XtjBB95A==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 10" + }, + "optionalDependencies": { + "@tailwindcss/oxide-android-arm64": "4.1.18", + "@tailwindcss/oxide-darwin-arm64": "4.1.18", + "@tailwindcss/oxide-darwin-x64": "4.1.18", + "@tailwindcss/oxide-freebsd-x64": "4.1.18", + "@tailwindcss/oxide-linux-arm-gnueabihf": "4.1.18", + "@tailwindcss/oxide-linux-arm64-gnu": "4.1.18", + "@tailwindcss/oxide-linux-arm64-musl": "4.1.18", + "@tailwindcss/oxide-linux-x64-gnu": "4.1.18", + "@tailwindcss/oxide-linux-x64-musl": "4.1.18", + "@tailwindcss/oxide-wasm32-wasi": "4.1.18", + "@tailwindcss/oxide-win32-arm64-msvc": "4.1.18", + "@tailwindcss/oxide-win32-x64-msvc": "4.1.18" + } + }, + "node_modules/@tailwindcss/oxide-android-arm64": { + "version": "4.1.18", + "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-android-arm64/-/oxide-android-arm64-4.1.18.tgz", + "integrity": "sha512-dJHz7+Ugr9U/diKJA0W6N/6/cjI+ZTAoxPf9Iz9BFRF2GzEX8IvXxFIi/dZBloVJX/MZGvRuFA9rqwdiIEZQ0Q==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@tailwindcss/oxide-darwin-arm64": { + "version": "4.1.18", + "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-darwin-arm64/-/oxide-darwin-arm64-4.1.18.tgz", + "integrity": "sha512-Gc2q4Qhs660bhjyBSKgq6BYvwDz4G+BuyJ5H1xfhmDR3D8HnHCmT/BSkvSL0vQLy/nkMLY20PQ2OoYMO15Jd0A==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@tailwindcss/oxide-darwin-x64": { + "version": "4.1.18", + "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-darwin-x64/-/oxide-darwin-x64-4.1.18.tgz", + "integrity": "sha512-FL5oxr2xQsFrc3X9o1fjHKBYBMD1QZNyc1Xzw/h5Qu4XnEBi3dZn96HcHm41c/euGV+GRiXFfh2hUCyKi/e+yw==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@tailwindcss/oxide-freebsd-x64": { + "version": "4.1.18", + "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-freebsd-x64/-/oxide-freebsd-x64-4.1.18.tgz", + "integrity": "sha512-Fj+RHgu5bDodmV1dM9yAxlfJwkkWvLiRjbhuO2LEtwtlYlBgiAT4x/j5wQr1tC3SANAgD+0YcmWVrj8R9trVMA==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "freebsd" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@tailwindcss/oxide-linux-arm-gnueabihf": { + "version": "4.1.18", + "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-linux-arm-gnueabihf/-/oxide-linux-arm-gnueabihf-4.1.18.tgz", + "integrity": "sha512-Fp+Wzk/Ws4dZn+LV2Nqx3IilnhH51YZoRaYHQsVq3RQvEl+71VGKFpkfHrLM/Li+kt5c0DJe/bHXK1eHgDmdiA==", + "cpu": [ + "arm" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@tailwindcss/oxide-linux-arm64-gnu": { + "version": "4.1.18", + "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-linux-arm64-gnu/-/oxide-linux-arm64-gnu-4.1.18.tgz", + "integrity": "sha512-S0n3jboLysNbh55Vrt7pk9wgpyTTPD0fdQeh7wQfMqLPM/Hrxi+dVsLsPrycQjGKEQk85Kgbx+6+QnYNiHalnw==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@tailwindcss/oxide-linux-arm64-musl": { + "version": "4.1.18", + "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-linux-arm64-musl/-/oxide-linux-arm64-musl-4.1.18.tgz", + "integrity": "sha512-1px92582HkPQlaaCkdRcio71p8bc8i/ap5807tPRDK/uw953cauQBT8c5tVGkOwrHMfc2Yh6UuxaH4vtTjGvHg==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@tailwindcss/oxide-linux-x64-gnu": { + "version": "4.1.18", + "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-linux-x64-gnu/-/oxide-linux-x64-gnu-4.1.18.tgz", + "integrity": "sha512-v3gyT0ivkfBLoZGF9LyHmts0Isc8jHZyVcbzio6Wpzifg/+5ZJpDiRiUhDLkcr7f/r38SWNe7ucxmGW3j3Kb/g==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@tailwindcss/oxide-linux-x64-musl": { + "version": "4.1.18", + "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-linux-x64-musl/-/oxide-linux-x64-musl-4.1.18.tgz", + "integrity": "sha512-bhJ2y2OQNlcRwwgOAGMY0xTFStt4/wyU6pvI6LSuZpRgKQwxTec0/3Scu91O8ir7qCR3AuepQKLU/kX99FouqQ==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@tailwindcss/oxide-wasm32-wasi": { + "version": "4.1.18", + "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-wasm32-wasi/-/oxide-wasm32-wasi-4.1.18.tgz", + "integrity": "sha512-LffYTvPjODiP6PT16oNeUQJzNVyJl1cjIebq/rWWBF+3eDst5JGEFSc5cWxyRCJ0Mxl+KyIkqRxk1XPEs9x8TA==", + "bundleDependencies": [ + "@napi-rs/wasm-runtime", + "@emnapi/core", + "@emnapi/runtime", + "@tybys/wasm-util", + "@emnapi/wasi-threads", + "tslib" + ], + "cpu": [ + "wasm32" + ], + "dev": true, + "license": "MIT", + "optional": true, + "dependencies": { + "@emnapi/core": "^1.7.1", + "@emnapi/runtime": "^1.7.1", + "@emnapi/wasi-threads": "^1.1.0", + "@napi-rs/wasm-runtime": "^1.1.0", + "@tybys/wasm-util": "^0.10.1", + "tslib": "^2.4.0" + }, + "engines": { + "node": ">=14.0.0" + } + }, + "node_modules/@tailwindcss/oxide-win32-arm64-msvc": { + "version": "4.1.18", + "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-win32-arm64-msvc/-/oxide-win32-arm64-msvc-4.1.18.tgz", + "integrity": "sha512-HjSA7mr9HmC8fu6bdsZvZ+dhjyGCLdotjVOgLA2vEqxEBZaQo9YTX4kwgEvPCpRh8o4uWc4J/wEoFzhEmjvPbA==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@tailwindcss/oxide-win32-x64-msvc": { + "version": "4.1.18", + "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-win32-x64-msvc/-/oxide-win32-x64-msvc-4.1.18.tgz", + "integrity": "sha512-bJWbyYpUlqamC8dpR7pfjA0I7vdF6t5VpUGMWRkXVE3AXgIZjYUYAK7II1GNaxR8J1SSrSrppRar8G++JekE3Q==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@tailwindcss/vite": { + "version": "4.1.18", + "resolved": "https://registry.npmjs.org/@tailwindcss/vite/-/vite-4.1.18.tgz", + "integrity": "sha512-jVA+/UpKL1vRLg6Hkao5jldawNmRo7mQYrZtNHMIVpLfLhDml5nMRUo/8MwoX2vNXvnaXNNMedrMfMugAVX1nA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@tailwindcss/node": "4.1.18", + "@tailwindcss/oxide": "4.1.18", + "tailwindcss": "4.1.18" + }, + "peerDependencies": { + "vite": "^5.2.0 || ^6 || ^7" + } + }, "node_modules/@tauri-apps/api": { "version": "2.9.1", "resolved": "https://registry.npmjs.org/@tauri-apps/api/-/api-2.9.1.tgz", @@ -1377,6 +1602,7 @@ "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.15.0.tgz", "integrity": "sha512-NZyJarBfL7nWwIq+FDL6Zp/yHEhePMNnnJ0y3qfieCrmNvYct8uvtiV41UvlSe6apAfk0fY1FbWx+NwfmpvtTg==", "license": "MIT", + "peer": true, "bin": { "acorn": "bin/acorn" }, @@ -1384,47 +1610,6 @@ "node": ">=0.4.0" } }, - "node_modules/any-promise": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/any-promise/-/any-promise-1.3.0.tgz", - "integrity": "sha512-7UvmKalWRt1wgjL1RrGxoSJW/0QZFIegpeGvZG9kjp8vrRu55XTHbwnqq2GpXm9uLbcuhxm3IqX9OB4MZR1b2A==", - "dev": true, - "license": "MIT" - }, - "node_modules/anymatch": { - "version": "3.1.3", - "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.3.tgz", - "integrity": "sha512-KMReFUr0B4t+D+OBkjR3KYqvocp2XaSzO55UcB6mgQMd3KbcE+mWTyvVV7D/zsdEbNnV6acZUutkiHQXvTr1Rw==", - "dev": true, - "license": "ISC", - "dependencies": { - "normalize-path": "^3.0.0", - "picomatch": "^2.0.4" - }, - "engines": { - "node": ">= 8" - } - }, - "node_modules/anymatch/node_modules/picomatch": { - "version": "2.3.1", - "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz", - "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=8.6" - }, - "funding": { - "url": "https://github.com/sponsors/jonschlinkert" - } - }, - "node_modules/arg": { - "version": "5.0.2", - "resolved": "https://registry.npmjs.org/arg/-/arg-5.0.2.tgz", - "integrity": "sha512-PYjyFOLKQ9y57JvQ6QLo8dAgNqswh8M1RMJYdQduT6xbWSgK36P/Z/v+p888pM69jMMfS8Xd8F6I1kQ/I9HUGg==", - "dev": true, - "license": "MIT" - }, "node_modules/aria-query": { "version": "5.3.2", "resolved": "https://registry.npmjs.org/aria-query/-/aria-query-5.3.2.tgz", @@ -1490,19 +1675,6 @@ "baseline-browser-mapping": "dist/cli.js" } }, - "node_modules/binary-extensions": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.3.0.tgz", - "integrity": "sha512-Ceh+7ox5qe7LJuLHoY0feh3pHuUDHAcRUeyL2VYghZwfpkNIy/+8Ocg0a3UuSoYzavmylwuLWQOf3hl0jjMMIw==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, "node_modules/bits-ui": { "version": "1.8.0", "resolved": "https://registry.npmjs.org/bits-ui/-/bits-ui-1.8.0.tgz", @@ -1530,19 +1702,6 @@ "svelte": "^5.11.0" } }, - "node_modules/braces": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.3.tgz", - "integrity": "sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA==", - "dev": true, - "license": "MIT", - "dependencies": { - "fill-range": "^7.1.1" - }, - "engines": { - "node": ">=8" - } - }, "node_modules/browserslist": { "version": "4.28.1", "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.28.1.tgz", @@ -1563,6 +1722,7 @@ } ], "license": "MIT", + "peer": true, "dependencies": { "baseline-browser-mapping": "^2.9.0", "caniuse-lite": "^1.0.30001759", @@ -1577,16 +1737,6 @@ "node": "^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7" } }, - "node_modules/camelcase-css": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/camelcase-css/-/camelcase-css-2.0.1.tgz", - "integrity": "sha512-QOSvevhslijgYwRx6Rv7zKdMF8lbRmx+uQGx2+vDc+KI/eBnsy9kit5aj23AgGu3pa4t9AgwbnXWqS+iOY+2aA==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">= 6" - } - }, "node_modules/caniuse-lite": { "version": "1.0.30001762", "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001762.tgz", @@ -1633,16 +1783,6 @@ "node": ">=6" } }, - "node_modules/commander": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/commander/-/commander-4.1.1.tgz", - "integrity": "sha512-NOKm8xhkzAjzFx8B2v5OAHT+u5pRQc2UCa2Vq9jYL/31o2wi9mxBA7LIFs3sV5VSC49z6pEhfbMULvShKj26WA==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">= 6" - } - }, "node_modules/cookie": { "version": "0.6.0", "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.6.0.tgz", @@ -1660,19 +1800,6 @@ "dev": true, "license": "MIT" }, - "node_modules/cssesc": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/cssesc/-/cssesc-3.0.0.tgz", - "integrity": "sha512-/Tb/JcjK111nNScGob5MNtsntNM1aCNUDipB/TkwZFhyDrrE47SOx/18wF2bbjgc3ZzCSKW1T5nt5EbFoAz/Vg==", - "dev": true, - "license": "MIT", - "bin": { - "cssesc": "bin/cssesc" - }, - "engines": { - "node": ">=4" - } - }, "node_modules/debug": { "version": "4.4.3", "resolved": "https://registry.npmjs.org/debug/-/debug-4.4.3.tgz", @@ -1701,26 +1828,22 @@ "node": ">=0.10.0" } }, + "node_modules/detect-libc": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/detect-libc/-/detect-libc-2.1.2.tgz", + "integrity": "sha512-Btj2BOOO83o3WyH59e8MgXsxEQVcarkUOpEYrubB0urwnN10yQ364rsiByU11nZlqWYZm05i/of7io4mzihBtQ==", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": ">=8" + } + }, "node_modules/devalue": { "version": "5.6.1", "resolved": "https://registry.npmjs.org/devalue/-/devalue-5.6.1.tgz", "integrity": "sha512-jDwizj+IlEZBunHcOuuFVBnIMPAEHvTsJj0BcIp94xYguLRVBcXO853px/MyIJvbVzWdsGvrRweIUWJw8hBP7A==", "license": "MIT" }, - "node_modules/didyoumean": { - "version": "1.2.2", - "resolved": "https://registry.npmjs.org/didyoumean/-/didyoumean-1.2.2.tgz", - "integrity": "sha512-gxtyfqMg7GKyhQmb056K7M3xszy/myH8w+B4RT+QXBQsvAOdc3XymqDDPHx1BgPgsdAA5SIifona89YtRATDzw==", - "dev": true, - "license": "Apache-2.0" - }, - "node_modules/dlv": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/dlv/-/dlv-1.1.3.tgz", - "integrity": "sha512-+HlytyjlPKnIG8XuRG8WvmBP8xs8P71y+SKKS6ZXWoEgLuePxtDoUEiH7WkdePWrQ5JBpE6aoVqfZfJUQkjXwA==", - "dev": true, - "license": "MIT" - }, "node_modules/electron-to-chromium": { "version": "1.5.267", "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.5.267.tgz", @@ -1728,6 +1851,20 @@ "dev": true, "license": "ISC" }, + "node_modules/enhanced-resolve": { + "version": "5.18.4", + "resolved": "https://registry.npmjs.org/enhanced-resolve/-/enhanced-resolve-5.18.4.tgz", + "integrity": "sha512-LgQMM4WXU3QI+SYgEc2liRgznaD5ojbmY3sb8LxyguVkIg5FxdpTkvk72te2R38/TGKxH634oLxXRGY6d7AP+Q==", + "dev": true, + "license": "MIT", + "dependencies": { + "graceful-fs": "^4.2.4", + "tapable": "^2.2.0" + }, + "engines": { + "node": ">=10.13.0" + } + }, "node_modules/esbuild": { "version": "0.25.12", "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.25.12.tgz", @@ -1795,46 +1932,6 @@ "@jridgewell/sourcemap-codec": "^1.4.15" } }, - "node_modules/fast-glob": { - "version": "3.3.3", - "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.3.3.tgz", - "integrity": "sha512-7MptL8U0cqcFdzIzwOTHoilX9x5BrNqye7Z/LuC7kCMRio1EMSyqRK3BEAUD7sXRq4iT4AzTVuZdhgQ2TCvYLg==", - "dev": true, - "license": "MIT", - "dependencies": { - "@nodelib/fs.stat": "^2.0.2", - "@nodelib/fs.walk": "^1.2.3", - "glob-parent": "^5.1.2", - "merge2": "^1.3.0", - "micromatch": "^4.0.8" - }, - "engines": { - "node": ">=8.6.0" - } - }, - "node_modules/fast-glob/node_modules/glob-parent": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz", - "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==", - "dev": true, - "license": "ISC", - "dependencies": { - "is-glob": "^4.0.1" - }, - "engines": { - "node": ">= 6" - } - }, - "node_modules/fastq": { - "version": "1.20.1", - "resolved": "https://registry.npmjs.org/fastq/-/fastq-1.20.1.tgz", - "integrity": "sha512-GGToxJ/w1x32s/D2EKND7kTil4n8OVk/9mycTc4VDza13lOvpUZTGX3mFSCtV9ksdGBVzvsyAVLM6mHFThxXxw==", - "dev": true, - "license": "ISC", - "dependencies": { - "reusify": "^1.0.4" - } - }, "node_modules/fdir": { "version": "6.5.0", "resolved": "https://registry.npmjs.org/fdir/-/fdir-6.5.0.tgz", @@ -1853,19 +1950,6 @@ } } }, - "node_modules/fill-range": { - "version": "7.1.1", - "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.1.1.tgz", - "integrity": "sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg==", - "dev": true, - "license": "MIT", - "dependencies": { - "to-regex-range": "^5.0.1" - }, - "engines": { - "node": ">=8" - } - }, "node_modules/fraction.js": { "version": "5.3.4", "resolved": "https://registry.npmjs.org/fraction.js/-/fraction.js-5.3.4.tgz", @@ -1895,54 +1979,25 @@ "node": "^8.16.0 || ^10.6.0 || >=11.0.0" } }, - "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/glob-parent": { - "version": "6.0.2", - "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-6.0.2.tgz", - "integrity": "sha512-XxwI8EOhVQgWp6iDL+3b0r86f4d6AX6zSU55HfB4ydCEuXLXc5FcYeOu+nnGftS4TEju/11rt4KJPTMgbfmv4A==", - "dev": true, - "license": "ISC", - "dependencies": { - "is-glob": "^4.0.3" - }, - "engines": { - "node": ">=10.13.0" - } - }, "node_modules/gpt-tokenizer": { "version": "3.4.0", "resolved": "https://registry.npmjs.org/gpt-tokenizer/-/gpt-tokenizer-3.4.0.tgz", "integrity": "sha512-wxFLnhIXTDjYebd9A9pGl3e31ZpSypbpIJSOswbgop5jLte/AsZVDvjlbEuVFlsqZixVKqbcoNmRlFDf6pz/UQ==", "license": "MIT" }, + "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/harper.js": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/harper.js/-/harper.js-1.2.0.tgz", "integrity": "sha512-yer9QibW0pKdQdUaV1FO9KNGmuqrj943nx+gTx2/RfSns1wrAeumuSeOBnIWBDkBCXKLvgcG68poHF90W+T21Q==", "license": "Apache-2.0" }, - "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/html5-qrcode": { "version": "2.3.8", "resolved": "https://registry.npmjs.org/html5-qrcode/-/html5-qrcode-2.3.8.tgz", @@ -1956,68 +2011,6 @@ "dev": true, "license": "MIT" }, - "node_modules/is-binary-path": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-2.1.0.tgz", - "integrity": "sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==", - "dev": true, - "license": "MIT", - "dependencies": { - "binary-extensions": "^2.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/is-core-module": { - "version": "2.16.1", - "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.16.1.tgz", - "integrity": "sha512-UfoeMA6fIJ8wTYFEUjelnaGI67v6+N7qXJEvQuIGa99l4xsCruSYOVSQ0uPANn4dAzm8lkYPaKLrrijLq7x23w==", - "dev": true, - "license": "MIT", - "dependencies": { - "hasown": "^2.0.2" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/is-extglob": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", - "integrity": "sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/is-glob": { - "version": "4.0.3", - "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz", - "integrity": "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==", - "dev": true, - "license": "MIT", - "dependencies": { - "is-extglob": "^2.1.1" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/is-number": { - "version": "7.0.0", - "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", - "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=0.12.0" - } - }, "node_modules/is-reference": { "version": "3.0.3", "resolved": "https://registry.npmjs.org/is-reference/-/is-reference-3.0.3.tgz", @@ -2028,13 +2021,13 @@ } }, "node_modules/jiti": { - "version": "1.21.7", - "resolved": "https://registry.npmjs.org/jiti/-/jiti-1.21.7.tgz", - "integrity": "sha512-/imKNG4EbWNrVjoNC/1H5/9GFy+tqjGBHCaSsN+P2RnPqjsLmv6UD3Ej+Kj8nBWaRAwyk7kK5ZUc+OEatnTR3A==", + "version": "2.6.1", + "resolved": "https://registry.npmjs.org/jiti/-/jiti-2.6.1.tgz", + "integrity": "sha512-ekilCSN1jwRvIbgeg/57YFh8qQDNbwDb9xT/qu2DAHbFFZUicIl4ygVaAvzveMhMVr3LnpSKTNnwt8PoOfmKhQ==", "dev": true, "license": "MIT", "bin": { - "jiti": "bin/jiti.js" + "jiti": "lib/jiti-cli.mjs" } }, "node_modules/jsonrepair": { @@ -2056,25 +2049,266 @@ "node": ">=6" } }, - "node_modules/lilconfig": { - "version": "3.1.3", - "resolved": "https://registry.npmjs.org/lilconfig/-/lilconfig-3.1.3.tgz", - "integrity": "sha512-/vlFKAoH5Cgt3Ie+JLhRbwOsCQePABiU3tJ1egGvyQ+33R/vcwM2Zl2QR/LzjsBeItPt3oSVXapn+m4nQDvpzw==", + "node_modules/lightningcss": { + "version": "1.30.2", + "resolved": "https://registry.npmjs.org/lightningcss/-/lightningcss-1.30.2.tgz", + "integrity": "sha512-utfs7Pr5uJyyvDETitgsaqSyjCb2qNRAtuqUeWIAKztsOYdcACf2KtARYXg2pSvhkt+9NfoaNY7fxjl6nuMjIQ==", "dev": true, - "license": "MIT", + "license": "MPL-2.0", + "dependencies": { + "detect-libc": "^2.0.3" + }, "engines": { - "node": ">=14" + "node": ">= 12.0.0" }, "funding": { - "url": "https://github.com/sponsors/antonk52" + "type": "opencollective", + "url": "https://opencollective.com/parcel" + }, + "optionalDependencies": { + "lightningcss-android-arm64": "1.30.2", + "lightningcss-darwin-arm64": "1.30.2", + "lightningcss-darwin-x64": "1.30.2", + "lightningcss-freebsd-x64": "1.30.2", + "lightningcss-linux-arm-gnueabihf": "1.30.2", + "lightningcss-linux-arm64-gnu": "1.30.2", + "lightningcss-linux-arm64-musl": "1.30.2", + "lightningcss-linux-x64-gnu": "1.30.2", + "lightningcss-linux-x64-musl": "1.30.2", + "lightningcss-win32-arm64-msvc": "1.30.2", + "lightningcss-win32-x64-msvc": "1.30.2" } }, - "node_modules/lines-and-columns": { - "version": "1.2.4", - "resolved": "https://registry.npmjs.org/lines-and-columns/-/lines-and-columns-1.2.4.tgz", - "integrity": "sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg==", + "node_modules/lightningcss-android-arm64": { + "version": "1.30.2", + "resolved": "https://registry.npmjs.org/lightningcss-android-arm64/-/lightningcss-android-arm64-1.30.2.tgz", + "integrity": "sha512-BH9sEdOCahSgmkVhBLeU7Hc9DWeZ1Eb6wNS6Da8igvUwAe0sqROHddIlvU06q3WyXVEOYDZ6ykBZQnjTbmo4+A==", + "cpu": [ + "arm64" + ], "dev": true, - "license": "MIT" + "license": "MPL-2.0", + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">= 12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/lightningcss-darwin-arm64": { + "version": "1.30.2", + "resolved": "https://registry.npmjs.org/lightningcss-darwin-arm64/-/lightningcss-darwin-arm64-1.30.2.tgz", + "integrity": "sha512-ylTcDJBN3Hp21TdhRT5zBOIi73P6/W0qwvlFEk22fkdXchtNTOU4Qc37SkzV+EKYxLouZ6M4LG9NfZ1qkhhBWA==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MPL-2.0", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">= 12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/lightningcss-darwin-x64": { + "version": "1.30.2", + "resolved": "https://registry.npmjs.org/lightningcss-darwin-x64/-/lightningcss-darwin-x64-1.30.2.tgz", + "integrity": "sha512-oBZgKchomuDYxr7ilwLcyms6BCyLn0z8J0+ZZmfpjwg9fRVZIR5/GMXd7r9RH94iDhld3UmSjBM6nXWM2TfZTQ==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MPL-2.0", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">= 12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/lightningcss-freebsd-x64": { + "version": "1.30.2", + "resolved": "https://registry.npmjs.org/lightningcss-freebsd-x64/-/lightningcss-freebsd-x64-1.30.2.tgz", + "integrity": "sha512-c2bH6xTrf4BDpK8MoGG4Bd6zAMZDAXS569UxCAGcA7IKbHNMlhGQ89eRmvpIUGfKWNVdbhSbkQaWhEoMGmGslA==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MPL-2.0", + "optional": true, + "os": [ + "freebsd" + ], + "engines": { + "node": ">= 12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/lightningcss-linux-arm-gnueabihf": { + "version": "1.30.2", + "resolved": "https://registry.npmjs.org/lightningcss-linux-arm-gnueabihf/-/lightningcss-linux-arm-gnueabihf-1.30.2.tgz", + "integrity": "sha512-eVdpxh4wYcm0PofJIZVuYuLiqBIakQ9uFZmipf6LF/HRj5Bgm0eb3qL/mr1smyXIS1twwOxNWndd8z0E374hiA==", + "cpu": [ + "arm" + ], + "dev": true, + "license": "MPL-2.0", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/lightningcss-linux-arm64-gnu": { + "version": "1.30.2", + "resolved": "https://registry.npmjs.org/lightningcss-linux-arm64-gnu/-/lightningcss-linux-arm64-gnu-1.30.2.tgz", + "integrity": "sha512-UK65WJAbwIJbiBFXpxrbTNArtfuznvxAJw4Q2ZGlU8kPeDIWEX1dg3rn2veBVUylA2Ezg89ktszWbaQnxD/e3A==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MPL-2.0", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/lightningcss-linux-arm64-musl": { + "version": "1.30.2", + "resolved": "https://registry.npmjs.org/lightningcss-linux-arm64-musl/-/lightningcss-linux-arm64-musl-1.30.2.tgz", + "integrity": "sha512-5Vh9dGeblpTxWHpOx8iauV02popZDsCYMPIgiuw97OJ5uaDsL86cnqSFs5LZkG3ghHoX5isLgWzMs+eD1YzrnA==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MPL-2.0", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/lightningcss-linux-x64-gnu": { + "version": "1.30.2", + "resolved": "https://registry.npmjs.org/lightningcss-linux-x64-gnu/-/lightningcss-linux-x64-gnu-1.30.2.tgz", + "integrity": "sha512-Cfd46gdmj1vQ+lR6VRTTadNHu6ALuw2pKR9lYq4FnhvgBc4zWY1EtZcAc6EffShbb1MFrIPfLDXD6Xprbnni4w==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MPL-2.0", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/lightningcss-linux-x64-musl": { + "version": "1.30.2", + "resolved": "https://registry.npmjs.org/lightningcss-linux-x64-musl/-/lightningcss-linux-x64-musl-1.30.2.tgz", + "integrity": "sha512-XJaLUUFXb6/QG2lGIW6aIk6jKdtjtcffUT0NKvIqhSBY3hh9Ch+1LCeH80dR9q9LBjG3ewbDjnumefsLsP6aiA==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MPL-2.0", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/lightningcss-win32-arm64-msvc": { + "version": "1.30.2", + "resolved": "https://registry.npmjs.org/lightningcss-win32-arm64-msvc/-/lightningcss-win32-arm64-msvc-1.30.2.tgz", + "integrity": "sha512-FZn+vaj7zLv//D/192WFFVA0RgHawIcHqLX9xuWiQt7P0PtdFEVaxgF9rjM/IRYHQXNnk61/H/gb2Ei+kUQ4xQ==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MPL-2.0", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">= 12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/lightningcss-win32-x64-msvc": { + "version": "1.30.2", + "resolved": "https://registry.npmjs.org/lightningcss-win32-x64-msvc/-/lightningcss-win32-x64-msvc-1.30.2.tgz", + "integrity": "sha512-5g1yc73p+iAkid5phb4oVFMB45417DkRevRbt/El/gKXJk4jid+vPFF/AXbxn05Aky8PapwzZrdJShv5C0avjw==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MPL-2.0", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">= 12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } }, "node_modules/locate-character": { "version": "3.0.0", @@ -2112,43 +2346,6 @@ "node": ">= 20" } }, - "node_modules/merge2": { - "version": "1.4.1", - "resolved": "https://registry.npmjs.org/merge2/-/merge2-1.4.1.tgz", - "integrity": "sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">= 8" - } - }, - "node_modules/micromatch": { - "version": "4.0.8", - "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.8.tgz", - "integrity": "sha512-PXwfBhYu0hBCPw8Dn0E+WDYb7af3dSLVWKi3HGv84IdF4TyFoC0ysxFd0Goxw7nSv4T/PzEJQxsYsEiFCKo2BA==", - "dev": true, - "license": "MIT", - "dependencies": { - "braces": "^3.0.3", - "picomatch": "^2.3.1" - }, - "engines": { - "node": ">=8.6" - } - }, - "node_modules/micromatch/node_modules/picomatch": { - "version": "2.3.1", - "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz", - "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=8.6" - }, - "funding": { - "url": "https://github.com/sponsors/jonschlinkert" - } - }, "node_modules/mri": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/mri/-/mri-1.2.0.tgz", @@ -2176,18 +2373,6 @@ "dev": true, "license": "MIT" }, - "node_modules/mz": { - "version": "2.7.0", - "resolved": "https://registry.npmjs.org/mz/-/mz-2.7.0.tgz", - "integrity": "sha512-z81GNO7nnYMEhrGh9LeymoE4+Yr0Wn5McHIZMK5cfQCl+NDX08sCZgUc9/6MHni9IWuFLm1Z3HTCXu2z9fN62Q==", - "dev": true, - "license": "MIT", - "dependencies": { - "any-promise": "^1.0.0", - "object-assign": "^4.0.1", - "thenify-all": "^1.0.0" - } - }, "node_modules/nanoid": { "version": "3.3.11", "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.11.tgz", @@ -2214,43 +2399,6 @@ "dev": true, "license": "MIT" }, - "node_modules/normalize-path": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz", - "integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/object-assign": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", - "integrity": "sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/object-hash": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/object-hash/-/object-hash-3.0.0.tgz", - "integrity": "sha512-RSn9F68PjH9HqtltsSnqYC1XXoWe9Bju5+213R98cNGttag9q9yAOTzdbsqvIa7aNm5WffBZFpWYr2aWrklWAw==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">= 6" - } - }, - "node_modules/path-parse": { - "version": "1.0.7", - "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.7.tgz", - "integrity": "sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==", - "dev": true, - "license": "MIT" - }, "node_modules/picocolors": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.1.1.tgz", @@ -2272,26 +2420,6 @@ "url": "https://github.com/sponsors/jonschlinkert" } }, - "node_modules/pify": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/pify/-/pify-2.3.0.tgz", - "integrity": "sha512-udgsAY+fTnvv7kI7aaxbqwWNb0AHiB0qBO89PZKPkoTmGOgdbrHDKD+0B2X4uTfJ/FT1R09r9gTsjUjNJotuog==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/pirates": { - "version": "4.0.7", - "resolved": "https://registry.npmjs.org/pirates/-/pirates-4.0.7.tgz", - "integrity": "sha512-TfySrs/5nm8fQJDcBDuUng3VOUKsd7S+zqvbOTiGXHfxX4wK31ard+hoNuvkicM/2YFzlpDgABOevKSsB4G/FA==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">= 6" - } - }, "node_modules/postcss": { "version": "8.5.6", "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.5.6.tgz", @@ -2312,6 +2440,7 @@ } ], "license": "MIT", + "peer": true, "dependencies": { "nanoid": "^3.3.11", "picocolors": "^1.1.1", @@ -2321,133 +2450,6 @@ "node": "^10 || ^12 || >=14" } }, - "node_modules/postcss-import": { - "version": "15.1.0", - "resolved": "https://registry.npmjs.org/postcss-import/-/postcss-import-15.1.0.tgz", - "integrity": "sha512-hpr+J05B2FVYUAXHeK1YyI267J/dDDhMU6B6civm8hSY1jYJnBXxzKDKDswzJmtLHryrjhnDjqqp/49t8FALew==", - "dev": true, - "license": "MIT", - "dependencies": { - "postcss-value-parser": "^4.0.0", - "read-cache": "^1.0.0", - "resolve": "^1.1.7" - }, - "engines": { - "node": ">=14.0.0" - }, - "peerDependencies": { - "postcss": "^8.0.0" - } - }, - "node_modules/postcss-js": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/postcss-js/-/postcss-js-4.1.0.tgz", - "integrity": "sha512-oIAOTqgIo7q2EOwbhb8UalYePMvYoIeRY2YKntdpFQXNosSu3vLrniGgmH9OKs/qAkfoj5oB3le/7mINW1LCfw==", - "dev": true, - "funding": [ - { - "type": "opencollective", - "url": "https://opencollective.com/postcss/" - }, - { - "type": "github", - "url": "https://github.com/sponsors/ai" - } - ], - "license": "MIT", - "dependencies": { - "camelcase-css": "^2.0.1" - }, - "engines": { - "node": "^12 || ^14 || >= 16" - }, - "peerDependencies": { - "postcss": "^8.4.21" - } - }, - "node_modules/postcss-load-config": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/postcss-load-config/-/postcss-load-config-6.0.1.tgz", - "integrity": "sha512-oPtTM4oerL+UXmx+93ytZVN82RrlY/wPUV8IeDxFrzIjXOLF1pN+EmKPLbubvKHT2HC20xXsCAH2Z+CKV6Oz/g==", - "dev": true, - "funding": [ - { - "type": "opencollective", - "url": "https://opencollective.com/postcss/" - }, - { - "type": "github", - "url": "https://github.com/sponsors/ai" - } - ], - "license": "MIT", - "dependencies": { - "lilconfig": "^3.1.1" - }, - "engines": { - "node": ">= 18" - }, - "peerDependencies": { - "jiti": ">=1.21.0", - "postcss": ">=8.0.9", - "tsx": "^4.8.1", - "yaml": "^2.4.2" - }, - "peerDependenciesMeta": { - "jiti": { - "optional": true - }, - "postcss": { - "optional": true - }, - "tsx": { - "optional": true - }, - "yaml": { - "optional": true - } - } - }, - "node_modules/postcss-nested": { - "version": "6.2.0", - "resolved": "https://registry.npmjs.org/postcss-nested/-/postcss-nested-6.2.0.tgz", - "integrity": "sha512-HQbt28KulC5AJzG+cZtj9kvKB93CFCdLvog1WFLf1D+xmMvPGlBstkpTEZfK5+AN9hfJocyBFCNiqyS48bpgzQ==", - "dev": true, - "funding": [ - { - "type": "opencollective", - "url": "https://opencollective.com/postcss/" - }, - { - "type": "github", - "url": "https://github.com/sponsors/ai" - } - ], - "license": "MIT", - "dependencies": { - "postcss-selector-parser": "^6.1.1" - }, - "engines": { - "node": ">=12.0" - }, - "peerDependencies": { - "postcss": "^8.2.14" - } - }, - "node_modules/postcss-selector-parser": { - "version": "6.1.2", - "resolved": "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-6.1.2.tgz", - "integrity": "sha512-Q8qQfPiZ+THO/3ZrOrO0cJJKfpYCagtMUkXbnEfmgUjwXg6z/WBeOyS9APBBPCTSiDV+s4SwQGu8yFsiMRIudg==", - "dev": true, - "license": "MIT", - "dependencies": { - "cssesc": "^3.0.0", - "util-deprecate": "^1.0.2" - }, - "engines": { - "node": ">=4" - } - }, "node_modules/postcss-value-parser": { "version": "4.2.0", "resolved": "https://registry.npmjs.org/postcss-value-parser/-/postcss-value-parser-4.2.0.tgz", @@ -2455,37 +2457,6 @@ "dev": true, "license": "MIT" }, - "node_modules/queue-microtask": { - "version": "1.2.3", - "resolved": "https://registry.npmjs.org/queue-microtask/-/queue-microtask-1.2.3.tgz", - "integrity": "sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==", - "dev": true, - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/feross" - }, - { - "type": "patreon", - "url": "https://www.patreon.com/feross" - }, - { - "type": "consulting", - "url": "https://feross.org/support" - } - ], - "license": "MIT" - }, - "node_modules/read-cache": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/read-cache/-/read-cache-1.0.0.tgz", - "integrity": "sha512-Owdv/Ft7IjOgm/i0xvNDZ1LrRANRfew4b2prF3OWMQLxLfu3bS8FVhCsrSCMK4lR56Y9ya+AThoTpDCTxCmpRA==", - "dev": true, - "license": "MIT", - "dependencies": { - "pify": "^2.3.0" - } - }, "node_modules/readdirp": { "version": "4.1.2", "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-4.1.2.tgz", @@ -2500,38 +2471,6 @@ "url": "https://paulmillr.com/funding/" } }, - "node_modules/resolve": { - "version": "1.22.11", - "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.11.tgz", - "integrity": "sha512-RfqAvLnMl313r7c9oclB1HhUEAezcpLjz95wFH4LVuhk9JF/r22qmVP9AMmOU4vMX7Q8pN8jwNg/CSpdFnMjTQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "is-core-module": "^2.16.1", - "path-parse": "^1.0.7", - "supports-preserve-symlinks-flag": "^1.0.0" - }, - "bin": { - "resolve": "bin/resolve" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/reusify": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/reusify/-/reusify-1.1.0.tgz", - "integrity": "sha512-g6QUff04oZpHs0eG5p83rFLhHeV00ug/Yf9nZM6fLeUrPguBTkTQOdpAWWspMh55TZfVQDPaN3NQJfbVRAxdIw==", - "dev": true, - "license": "MIT", - "engines": { - "iojs": ">=1.0.0", - "node": ">=0.10.0" - } - }, "node_modules/rollup": { "version": "4.54.0", "resolved": "https://registry.npmjs.org/rollup/-/rollup-4.54.0.tgz", @@ -2574,30 +2513,6 @@ "fsevents": "~2.3.2" } }, - "node_modules/run-parallel": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/run-parallel/-/run-parallel-1.2.0.tgz", - "integrity": "sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA==", - "dev": true, - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/feross" - }, - { - "type": "patreon", - "url": "https://www.patreon.com/feross" - }, - { - "type": "consulting", - "url": "https://feross.org/support" - } - ], - "license": "MIT", - "dependencies": { - "queue-microtask": "^1.2.2" - } - }, "node_modules/runed": { "version": "0.23.4", "resolved": "https://registry.npmjs.org/runed/-/runed-0.23.4.tgz", @@ -2669,47 +2584,12 @@ "inline-style-parser": "0.2.7" } }, - "node_modules/sucrase": { - "version": "3.35.1", - "resolved": "https://registry.npmjs.org/sucrase/-/sucrase-3.35.1.tgz", - "integrity": "sha512-DhuTmvZWux4H1UOnWMB3sk0sbaCVOoQZjv8u1rDoTV0HTdGem9hkAZtl4JZy8P2z4Bg0nT+YMeOFyVr4zcG5Tw==", - "dev": true, - "license": "MIT", - "dependencies": { - "@jridgewell/gen-mapping": "^0.3.2", - "commander": "^4.0.0", - "lines-and-columns": "^1.1.6", - "mz": "^2.7.0", - "pirates": "^4.0.1", - "tinyglobby": "^0.2.11", - "ts-interface-checker": "^0.1.9" - }, - "bin": { - "sucrase": "bin/sucrase", - "sucrase-node": "bin/sucrase-node" - }, - "engines": { - "node": ">=16 || 14 >=14.17" - } - }, - "node_modules/supports-preserve-symlinks-flag": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/supports-preserve-symlinks-flag/-/supports-preserve-symlinks-flag-1.0.0.tgz", - "integrity": "sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, "node_modules/svelte": { "version": "5.46.1", "resolved": "https://registry.npmjs.org/svelte/-/svelte-5.46.1.tgz", "integrity": "sha512-ynjfCHD3nP2el70kN5Pmg37sSi0EjOm9FgHYQdC4giWG/hzO3AatzXXJJgP305uIhGQxSufJLuYWtkY8uK/8RA==", "license": "MIT", + "peer": true, "dependencies": { "@jridgewell/remapping": "^2.3.4", "@jridgewell/sourcemap-codec": "^1.5.0", @@ -2822,43 +2702,12 @@ } }, "node_modules/tailwindcss": { - "version": "3.4.19", - "resolved": "https://registry.npmjs.org/tailwindcss/-/tailwindcss-3.4.19.tgz", - "integrity": "sha512-3ofp+LL8E+pK/JuPLPggVAIaEuhvIz4qNcf3nA1Xn2o/7fb7s/TYpHhwGDv1ZU3PkBluUVaF8PyCHcm48cKLWQ==", + "version": "4.1.18", + "resolved": "https://registry.npmjs.org/tailwindcss/-/tailwindcss-4.1.18.tgz", + "integrity": "sha512-4+Z+0yiYyEtUVCScyfHCxOYP06L5Ne+JiHhY2IjR2KWMIWhJOYZKLSGZaP5HkZ8+bY0cxfzwDE5uOmzFXyIwxw==", "dev": true, "license": "MIT", - "peer": true, - "dependencies": { - "@alloc/quick-lru": "^5.2.0", - "arg": "^5.0.2", - "chokidar": "^3.6.0", - "didyoumean": "^1.2.2", - "dlv": "^1.1.3", - "fast-glob": "^3.3.2", - "glob-parent": "^6.0.2", - "is-glob": "^4.0.3", - "jiti": "^1.21.7", - "lilconfig": "^3.1.3", - "micromatch": "^4.0.8", - "normalize-path": "^3.0.0", - "object-hash": "^3.0.0", - "picocolors": "^1.1.1", - "postcss": "^8.4.47", - "postcss-import": "^15.1.0", - "postcss-js": "^4.0.1", - "postcss-load-config": "^4.0.2 || ^5.0 || ^6.0", - "postcss-nested": "^6.2.0", - "postcss-selector-parser": "^6.1.2", - "resolve": "^1.22.8", - "sucrase": "^3.35.0" - }, - "bin": { - "tailwind": "lib/cli.js", - "tailwindcss": "lib/cli.js" - }, - "engines": { - "node": ">=14.0.0" - } + "peer": true }, "node_modules/tailwindcss-animate": { "version": "1.0.7", @@ -2870,91 +2719,18 @@ "tailwindcss": ">=3.0.0 || insiders" } }, - "node_modules/tailwindcss/node_modules/chokidar": { - "version": "3.6.0", - "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.6.0.tgz", - "integrity": "sha512-7VT13fmjotKpGipCW9JEQAusEPE+Ei8nl6/g4FBAmIm0GOOLMua9NDDo/DWp0ZAxCr3cPq5ZpBqmPAQgDda2Pw==", + "node_modules/tapable": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/tapable/-/tapable-2.3.0.tgz", + "integrity": "sha512-g9ljZiwki/LfxmQADO3dEY1CbpmXT5Hm2fJ+QaGKwSXUylMybePR7/67YW7jOrrvjEgL1Fmz5kzyAjWVWLlucg==", "dev": true, "license": "MIT", - "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" - }, "engines": { - "node": ">= 8.10.0" + "node": ">=6" }, "funding": { - "url": "https://paulmillr.com/funding/" - }, - "optionalDependencies": { - "fsevents": "~2.3.2" - } - }, - "node_modules/tailwindcss/node_modules/chokidar/node_modules/glob-parent": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz", - "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==", - "dev": true, - "license": "ISC", - "dependencies": { - "is-glob": "^4.0.1" - }, - "engines": { - "node": ">= 6" - } - }, - "node_modules/tailwindcss/node_modules/picomatch": { - "version": "2.3.1", - "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz", - "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=8.6" - }, - "funding": { - "url": "https://github.com/sponsors/jonschlinkert" - } - }, - "node_modules/tailwindcss/node_modules/readdirp": { - "version": "3.6.0", - "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.6.0.tgz", - "integrity": "sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==", - "dev": true, - "license": "MIT", - "dependencies": { - "picomatch": "^2.2.1" - }, - "engines": { - "node": ">=8.10.0" - } - }, - "node_modules/thenify": { - "version": "3.3.1", - "resolved": "https://registry.npmjs.org/thenify/-/thenify-3.3.1.tgz", - "integrity": "sha512-RVZSIV5IG10Hk3enotrhvz0T9em6cyHBLkH/YAZuKqd8hRkKhSfCGIcP2KUY0EPxndzANBmNllzWPwak+bheSw==", - "dev": true, - "license": "MIT", - "dependencies": { - "any-promise": "^1.0.0" - } - }, - "node_modules/thenify-all": { - "version": "1.6.0", - "resolved": "https://registry.npmjs.org/thenify-all/-/thenify-all-1.6.0.tgz", - "integrity": "sha512-RNxQH/qI8/t3thXJDwcstUO4zeqo64+Uy/+sNVRBx4Xn2OX+OZ9oP+iJnNFqplFra2ZUVeKCSa2oVWi3T4uVmA==", - "dev": true, - "license": "MIT", - "dependencies": { - "thenify": ">= 3.1.0 < 4" - }, - "engines": { - "node": ">=0.8" + "type": "opencollective", + "url": "https://opencollective.com/webpack" } }, "node_modules/tinyglobby": { @@ -2974,19 +2750,6 @@ "url": "https://github.com/sponsors/SuperchupuDev" } }, - "node_modules/to-regex-range": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", - "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "is-number": "^7.0.0" - }, - "engines": { - "node": ">=8.0" - } - }, "node_modules/totalist": { "version": "3.0.1", "resolved": "https://registry.npmjs.org/totalist/-/totalist-3.0.1.tgz", @@ -2997,13 +2760,6 @@ "node": ">=6" } }, - "node_modules/ts-interface-checker": { - "version": "0.1.13", - "resolved": "https://registry.npmjs.org/ts-interface-checker/-/ts-interface-checker-0.1.13.tgz", - "integrity": "sha512-Y/arvbn+rrz3JCKl9C4kVNfTfSm2/mEp5FSz5EsZSANGPSlQrpRI5M4PKF+mJnE52jOO90PnPSc3Ur3bTQw0gA==", - "dev": true, - "license": "Apache-2.0" - }, "node_modules/tslib": { "version": "2.8.1", "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.8.1.tgz", @@ -3011,12 +2767,23 @@ "dev": true, "license": "0BSD" }, + "node_modules/tw-animate-css": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/tw-animate-css/-/tw-animate-css-1.4.0.tgz", + "integrity": "sha512-7bziOlRqH0hJx80h/3mbicLW7o8qLsH5+RaLR2t+OHM3D0JlWGODQKQ4cxbK7WlvmUxpcj6Kgu6EKqjrGFe3QQ==", + "dev": true, + "license": "MIT", + "funding": { + "url": "https://github.com/sponsors/Wombosvideo" + } + }, "node_modules/typescript": { "version": "5.6.3", "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.6.3.tgz", "integrity": "sha512-hjcS1mhfuyi4WW8IWtjP7brDrG2cuDZukyrYrSauoXGNgx0S7zceP07adYkJycEr56BOUTNPzbInooiN3fn1qw==", "dev": true, "license": "Apache-2.0", + "peer": true, "bin": { "tsc": "bin/tsc", "tsserver": "bin/tsserver" @@ -3056,13 +2823,6 @@ "browserslist": ">= 4.21.0" } }, - "node_modules/util-deprecate": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", - "integrity": "sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==", - "dev": true, - "license": "MIT" - }, "node_modules/vaul-svelte": { "version": "1.0.0-next.7", "resolved": "https://registry.npmjs.org/vaul-svelte/-/vaul-svelte-1.0.0-next.7.tgz", @@ -3087,6 +2847,7 @@ "integrity": "sha512-+Oxm7q9hDoLMyJOYfUYBuHQo+dkAloi33apOPP56pzj+vsdJDzr+j1NISE5pyaAuKL4A3UD34qd0lx5+kfKp2g==", "dev": true, "license": "MIT", + "peer": true, "dependencies": { "esbuild": "^0.25.0", "fdir": "^6.4.4", diff --git a/package.json b/package.json index 29cc78e..0b98323 100644 --- a/package.json +++ b/package.json @@ -35,6 +35,7 @@ "@sveltejs/adapter-static": "^3.0.6", "@sveltejs/kit": "^2.9.0", "@sveltejs/vite-plugin-svelte": "^5.0.0", + "@tailwindcss/vite": "^4.1.18", "@tauri-apps/cli": "^2", "@types/marked": "^5.0.2", "autoprefixer": "^10.4.20", @@ -43,8 +44,9 @@ "svelte": "^5.0.0", "svelte-check": "^4.0.0", "tailwind-variants": "^0.2.1", - "tailwindcss": "^3.4.17", + "tailwindcss": "^4.1.18", "tailwindcss-animate": "^1.0.7", + "tw-animate-css": "^1.4.0", "typescript": "~5.6.2", "vaul-svelte": "^1.0.0-next.7", "vite": "^6.0.3" diff --git a/postcss.config.js b/postcss.config.js deleted file mode 100644 index 2aa7205..0000000 --- a/postcss.config.js +++ /dev/null @@ -1,6 +0,0 @@ -export default { - plugins: { - tailwindcss: {}, - autoprefixer: {}, - }, -}; diff --git a/src/app.css b/src/app.css index c4b7085..063c490 100644 --- a/src/app.css +++ b/src/app.css @@ -1,488 +1,514 @@ -@tailwind base; -@tailwind components; -@tailwind utilities; +@import "tailwindcss"; +/* @import "tw-animate-css"; */ + +@custom-variant dark (&:is(.dark *)); + +@theme { + /* Radius (for rounded-*) */ + --radius-sm: calc(var(--radius) - 4px); + --radius-md: calc(var(--radius) - 2px); + --radius-lg: var(--radius); + --radius-xl: calc(var(--radius) + 4px); + + /* Colors - map to Tailwind theme system */ + --color-background: var(--background); + --color-foreground: var(--foreground); + --color-muted: var(--muted); + --color-muted-foreground: var(--muted-foreground); + --color-popover: var(--popover); + --color-popover-foreground: var(--popover-foreground); + --color-card: var(--card); + --color-card-foreground: var(--card-foreground); + --color-border: var(--border); + --color-input: var(--input); + --color-primary: var(--primary); + --color-primary-foreground: var(--primary-foreground); + --color-secondary: var(--secondary); + --color-secondary-foreground: var(--secondary-foreground); + --color-accent: var(--accent); + --color-accent-foreground: var(--accent-foreground); + --color-destructive: var(--destructive); + --color-destructive-foreground: var(--destructive-foreground); + --color-ring: var(--ring); + --color-radius: var(--radius); + + /* Surface Colors */ + --color-surface-50: var(--color-surface-50); + --color-surface-100: var(--color-surface-100); + --color-surface-200: var(--color-surface-200); + --color-surface-300: var(--color-surface-300); + --color-surface-400: var(--color-surface-400); + --color-surface-500: var(--color-surface-500); + --color-surface-600: var(--color-surface-600); + --color-surface-700: var(--color-surface-700); + --color-surface-800: var(--color-surface-800); + --color-surface-850: var(--color-surface-850); + --color-surface-900: var(--color-surface-900); + --color-surface-950: var(--color-surface-950); + + /* Accent Palette */ + --color-accent-50: var(--color-accent-50); + --color-accent-100: var(--color-accent-100); + --color-accent-200: var(--color-accent-200); + --color-accent-300: var(--color-accent-300); + --color-accent-400: var(--color-accent-400); + --color-accent-500: var(--color-accent-500); + --color-accent-600: var(--color-accent-600); + --color-accent-700: var(--color-accent-700); + --color-accent-800: var(--color-accent-800); + --color-accent-900: var(--color-accent-900); + --color-accent-950: var(--color-accent-950); +} /* ============================================= THEMING SYSTEM - CSS Custom Properties ============================================= */ -@layer base { +:root { + /* Shadcn Variables (Dark Default) */ + --radius: 0.5rem; + --background: hsl(222 47% 11%); + --foreground: hsl(210 40% 98%); + --muted: hsl(217 33% 25%); + --muted-foreground: hsl(215 20.2% 65.1%); + --popover: hsl(217 33% 17%); + --popover-foreground: hsl(210 40% 98%); + --card: hsl(217 33% 17%); + --card-foreground: hsl(210 40% 98%); + --border: hsl(217 33% 25%); + --input: hsl(217 33% 25%); + --primary: hsl(221.2 83.2% 53.3%); + --primary-foreground: hsl(210 40% 98%); + --secondary: hsl(217 33% 25%); + --secondary-foreground: hsl(210 40% 98%); + --accent: hsl(217 33% 25%); + --accent-foreground: hsl(210 40% 98%); + --destructive: hsl(0 62.8% 30.6%); + --destructive-foreground: hsl(210 40% 98%); + --ring: hsl(221.2 83.2% 53.3%); - /* Default/Dark Theme (base) */ - :root { - /* Surface colors (backgrounds, borders) */ - --color-surface-50: #f8fafc; - --color-surface-100: #f1f5f9; - --color-surface-200: #e2e8f0; - --color-surface-300: #cbd5e1; - --color-surface-400: #94a3b8; - --color-surface-500: #64748b; - --color-surface-600: #475569; - --color-surface-700: #334155; - --color-surface-800: #1e293b; - --color-surface-850: #141b25; - --color-surface-900: #0f172a; - --color-surface-950: #020617; + /* Surface colors (backgrounds, borders) */ + --color-surface-50: #f8fafc; + --color-surface-100: #f1f5f9; + --color-surface-200: #e2e8f0; + --color-surface-300: #cbd5e1; + --color-surface-400: #94a3b8; + --color-surface-500: #64748b; + --color-surface-600: #475569; + --color-surface-700: #334155; + --color-surface-800: #1e293b; + --color-surface-850: #141b25; + --color-surface-900: #0f172a; + --color-surface-950: #020617; - /* Accent colors (interactive elements) */ - --color-accent-50: #eff6ff; - --color-accent-100: #dbeafe; - --color-accent-200: #bfdbfe; - --color-accent-300: #93c5fd; - --color-accent-400: #60a5fa; - --color-accent-500: #3b82f6; - --color-accent-600: #2563eb; - --color-accent-700: #1d4ed8; - --color-accent-800: #1e40af; - --color-accent-900: #1e3a8a; - --color-accent-950: #172554; + /* Accent colors (interactive elements) */ + --color-accent-50: #eff6ff; + --color-accent-100: #dbeafe; + --color-accent-200: #bfdbfe; + --color-accent-300: #93c5fd; + --color-accent-400: #60a5fa; + --color-accent-500: #3b82f6; + --color-accent-600: #2563eb; + --color-accent-700: #1d4ed8; + --color-accent-800: #1e40af; + --color-accent-900: #1e3a8a; + --color-accent-950: #172554; - /* Semantic colors */ - --bg-primary: var(--color-surface-900); - --bg-secondary: var(--color-surface-800); - --bg-tertiary: var(--color-surface-700); - --text-primary: var(--color-surface-100); - --text-secondary: var(--color-surface-300); - --text-muted: var(--color-surface-400); - --text-accent: var(--color-accent-400); - --border-primary: var(--color-surface-700); - --border-secondary: var(--color-surface-600); + /* Semantic colors */ + --bg-primary: var(--color-surface-900); + --bg-secondary: var(--color-surface-800); + --bg-tertiary: var(--color-surface-700); + --text-primary: var(--color-surface-100); + --text-secondary: var(--color-surface-300); + --text-muted: var(--color-surface-400); + --text-accent: var(--color-accent-400); + --border-primary: var(--color-surface-700); + --border-secondary: var(--color-surface-600); - /* Scrollbar */ - --scrollbar-track: var(--color-surface-800); - --scrollbar-thumb: var(--color-surface-600); - --scrollbar-thumb-hover: var(--color-surface-500); + /* Scrollbar */ + --scrollbar-track: var(--color-surface-800); + --scrollbar-thumb: var(--color-surface-600); + --scrollbar-thumb-hover: var(--color-surface-500); - /* Special effects */ - --crt-scanline: transparent; - --crt-glow: none; - --crt-flicker: none; - --font-story: 'Georgia', 'Cambria', serif; - - /* Shadcn Variables (Dark Default) */ - --background: 222 47% 11%; - --foreground: 210 40% 98%; - --card: 217 33% 17%; - --card-foreground: 210 40% 98%; - --popover: 217 33% 17%; - --popover-foreground: 210 40% 98%; - --primary: 221.2 83.2% 53.3%; - --primary-foreground: 210 40% 98%; - --secondary: 217 33% 25%; - --secondary-foreground: 210 40% 98%; - --muted: 217 33% 25%; - --muted-foreground: 215 20.2% 65.1%; - --accent: 217 33% 25%; - --accent-foreground: 210 40% 98%; - --destructive: 0 62.8% 30.6%; - --destructive-foreground: 210 40% 98%; - --border: 217 33% 25%; - --input: 217 33% 25%; - --ring: 221.2 83.2% 53.3%; - --radius: 0.5rem; - } - - /* ============================================= - LIGHT THEME (Paper) - Clean paper-like backgrounds with high contrast text - ============================================= */ - [data-theme="light"] { - /* Paper-inspired surface colors */ - --color-surface-50: #faf9f7; - /* Clean paper white */ - --color-surface-100: #f5f3f0; - /* Slightly off-white */ - --color-surface-200: #eceae5; - /* Light warm gray */ - --color-surface-300: #dedad3; - /* Soft border gray */ - --color-surface-400: #b8b3a9; - /* Muted gray for icons */ - --color-surface-500: #7d786e; - /* Medium gray - muted text */ - --color-surface-600: #5c5850; - /* Dark gray */ - --color-surface-700: #3d3a35; - /* Very dark - body text */ - --color-surface-800: #2a2825; - /* Near black */ - --color-surface-850: #1f1e1b; - /* Darker */ - --color-surface-900: #161513; - /* Rich black - headers */ - --color-surface-950: #0a0a09; - /* Deepest black */ - - /* Warm accent colors (amber/brown - ink on paper) */ - --color-accent-50: #fef8ee; - --color-accent-100: #fcf0dc; - --color-accent-200: #f8ddb8; - --color-accent-300: #f3c78a; - --color-accent-400: #e6a54a; - /* Warm amber */ - --color-accent-500: #c4872d; - /* Rich golden brown */ - --color-accent-600: #a66b1f; - /* Deep amber */ - --color-accent-700: #8a5419; - --color-accent-800: #724516; - --color-accent-900: #5f3a14; - --color-accent-950: #361e0a; - - /* Semantic colors */ - --bg-primary: var(--color-surface-50); - --bg-secondary: var(--color-surface-100); - --bg-tertiary: var(--color-surface-200); - --text-primary: var(--color-surface-900); - --text-secondary: var(--color-surface-700); - --text-muted: var(--color-surface-500); - --text-accent: var(--color-accent-600); - --border-primary: var(--color-surface-300); - --border-secondary: var(--color-surface-400); - --scrollbar-track: var(--color-surface-200); - --scrollbar-thumb: var(--color-surface-400); - --scrollbar-thumb-hover: var(--color-surface-500); - - /* Shadcn Variables (Light) */ - --background: 0 0% 100%; - --foreground: 222.2 84% 4.9%; - --card: 0 0% 100%; - --card-foreground: 222.2 84% 4.9%; - --popover: 0 0% 100%; - --popover-foreground: 222.2 84% 4.9%; - --primary: 222.2 47.4% 11.2%; - --primary-foreground: 210 40% 98%; - --secondary: 210 40% 96.1%; - --secondary-foreground: 222.2 47.4% 11.2%; - --muted: 210 40% 96.1%; - --muted-foreground: 215.4 16.3% 46.9%; - --accent: 210 40% 96.1%; - --accent-foreground: 222.2 47.4% 11.2%; - --destructive: 0 84.2% 60.2%; - --destructive-foreground: 210 40% 98%; - --border: 214.3 31.8% 91.4%; - --input: 214.3 31.8% 91.4%; - --ring: 215 20.2% 65.1%; - } - - /* ============================================= - LIGHT THEME (Solarized) - Classic Solarized color scheme - ============================================= */ - [data-theme="light-solarized"] { - /* Solarized base colors */ - --color-surface-50: #fdf6e3; - /* base3 - main background */ - --color-surface-100: #f5eedb; - /* between base3 and base2 */ - --color-surface-200: #eee8d5; - /* base2 - background highlights */ - --color-surface-300: #e0d6c1; - /* border color */ - --color-surface-400: #9a9181; - /* muted UI elements */ - --color-surface-500: #6b6459; - /* muted text - darker for visibility */ - --color-surface-600: #544f46; - /* secondary text */ - --color-surface-700: #3d3933; - /* body text - dark for contrast */ - --color-surface-800: #2a2721; - /* emphasized text */ - --color-surface-850: #1e1c18; - /* darker */ - --color-surface-900: #141310; - /* headers - near black */ - --color-surface-950: #0a0908; - /* deepest */ - - /* Solarized accent colors (cyan) */ - --color-accent-50: #e8f5f4; - --color-accent-100: #d1ebe9; - --color-accent-200: #a3d7d3; - --color-accent-300: #75c3bd; - --color-accent-400: #2aa198; - /* Solarized cyan */ - --color-accent-500: #24897f; - /* Slightly darker for contrast */ - --color-accent-600: #1e7268; - --color-accent-700: #185b52; - --color-accent-800: #12443d; - --color-accent-900: #0c2d28; - --color-accent-950: #061614; - - /* Semantic colors */ - --bg-primary: var(--color-surface-50); - --bg-secondary: var(--color-surface-100); - --bg-tertiary: var(--color-surface-200); - --text-primary: var(--color-surface-900); - --text-secondary: var(--color-surface-700); - --text-muted: var(--color-surface-500); - --text-accent: var(--color-accent-500); - --border-primary: var(--color-surface-300); - --border-secondary: var(--color-surface-400); - --scrollbar-track: var(--color-surface-200); - --scrollbar-thumb: var(--color-surface-400); - --scrollbar-thumb-hover: var(--color-surface-500); - - /* Shadcn Variables (Light - Solarized) */ - --background: 44 26% 94%; - /* base3 */ - --foreground: 204 11% 23%; - /* base00 */ - --card: 43 27% 91%; - /* base2 */ - --card-foreground: 204 11% 23%; - --popover: 43 27% 91%; - --popover-foreground: 204 11% 23%; - --primary: 175 59% 40%; - /* cyan */ - --primary-foreground: 44 26% 94%; - --secondary: 42 16% 87%; - /* base2ish */ - --secondary-foreground: 204 11% 23%; - --muted: 42 16% 87%; - --muted-foreground: 38 7% 40%; - /* base1 */ - --accent: 42 16% 87%; - --accent-foreground: 175 59% 40%; - --destructive: 1 71% 52%; - /* red */ - --destructive-foreground: 44 26% 94%; - --border: 38 15% 82%; - /* base2/3 mix */ - --input: 38 15% 82%; - --ring: 175 59% 40%; - } - - /* ============================================= - RETRO CONSOLE THEME - Inspired by PS2-era games and Serial Experiments Lain - CRT phosphor aesthetic with warm amber accents - ============================================= */ - [data-theme="retro-console"] { - /* Retro CRT color palette */ - --color-retro-black: #050808; - --color-retro-dark: #0a1210; - --color-retro-green-dark: #0c1f18; - --color-retro-green: #39ff14; - --color-retro-green-bright: #7fff00; - --color-retro-green-dim: #2eb82e; - --color-retro-green-muted: #1a4a2e; - --color-retro-cyan: #00e5ff; - --color-retro-cyan-dim: #00b8cc; - --color-retro-amber: #ffb000; - --color-retro-amber-dim: #cc8800; - --color-retro-red: #ff2d2d; - --color-retro-purple: #bf00ff; - - /* Override semantic colors */ - --bg-primary: var(--color-retro-black); - --bg-secondary: var(--color-retro-dark); - --bg-tertiary: var(--color-retro-green-dark); - --text-primary: var(--color-retro-green); - --text-secondary: var(--color-retro-green-dim); - --text-muted: var(--color-retro-green-muted); - --text-accent: var(--color-retro-cyan); - --border-primary: var(--color-retro-green-muted); - --border-secondary: var(--color-retro-green-dark); - --scrollbar-track: var(--color-retro-dark); - --scrollbar-thumb: var(--color-retro-green-muted); - --scrollbar-thumb-hover: var(--color-retro-green-dim); - - /* Surface colors mapped to retro palette */ - --color-surface-50: #d4ffd4; - --color-surface-100: #a8ffa8; - --color-surface-200: #7cff7c; - --color-surface-300: var(--color-retro-green-dim); - --color-surface-400: var(--color-retro-green); - --color-surface-500: var(--color-retro-green-muted); - --color-surface-600: #163828; - --color-surface-700: var(--color-retro-green-dark); - --color-surface-800: var(--color-retro-dark); - --color-surface-850: #070d0b; - --color-surface-900: var(--color-retro-black); - --color-surface-950: #020404; - - /* Accent colors mapped to cyan */ - --color-accent-50: #d4ffff; - --color-accent-100: #a8ffff; - --color-accent-200: #7cffff; - --color-accent-300: #50e5ff; - --color-accent-400: var(--color-retro-cyan); - --color-accent-500: var(--color-retro-cyan-dim); - --color-accent-600: #008fa3; - --color-accent-700: #006b7a; - --color-accent-800: #004752; - --color-accent-900: #002329; - --color-accent-950: #001214; - - /* Enhanced CRT Effects */ - --crt-scanline: rgba(57, 255, 20, 0.04); - --crt-glow: 0 0 8px rgba(57, 255, 20, 0.4), 0 0 16px rgba(57, 255, 20, 0.2), 0 0 32px rgba(57, 255, 20, 0.1); - --crt-text-glow: 0 0 2px rgba(57, 255, 20, 0.8), 0 0 4px rgba(57, 255, 20, 0.4), 0 0 8px rgba(57, 255, 20, 0.2); - --crt-amber-glow: 0 0 4px rgba(255, 176, 0, 0.6), 0 0 8px rgba(255, 176, 0, 0.3); - --crt-cyan-glow: 0 0 4px rgba(0, 229, 255, 0.6), 0 0 8px rgba(0, 229, 255, 0.3); - - /* Retro UI chrome */ - --retro-border: 2px solid var(--color-retro-green-muted); - --retro-border-glow: 0 0 4px rgba(57, 255, 20, 0.3); - - /* Shadcn Variables (Retro) */ - --background: 180 30% 2%; - /* retro-black */ - --foreground: 110 100% 54%; - /* retro-green */ - --card: 168 29% 5%; - /* retro-dark */ - --card-foreground: 110 100% 54%; - --popover: 168 29% 5%; - --popover-foreground: 110 100% 54%; - --primary: 186 100% 50%; - /* retro-cyan */ - --primary-foreground: 180 30% 2%; - --secondary: 158 44% 8%; - /* retro-green-dark */ - --secondary-foreground: 110 100% 54%; - --muted: 158 44% 8%; - --muted-foreground: 144 48% 20%; - /* retro-green-muted */ - --accent: 158 44% 8%; - --accent-foreground: 186 100% 50%; - --destructive: 0 100% 59%; - /* retro-red */ - --destructive-foreground: 180 30% 2%; - --border: 144 48% 20%; - --input: 144 48% 20%; - --ring: 186 100% 50%; - --radius: 0; - - /* Typography - pixelated monospace feel */ - --font-story: 'VT323', 'Share Tech Mono', 'JetBrains Mono', 'Fira Code', 'Courier New', monospace; - } - - /* ============================================= - FALLEN DOWN THEME - Undertale/Deltarune inspired pixel aesthetic - ============================================= */ - [data-theme="fallen-down"] { - /* Undertale color palette */ - --color-ut-black: #000000; - --color-ut-white: #FFFFFF; - --color-ut-yellow: #FFFF00; - --color-ut-red: #FF0000; - --color-ut-orange: #FFA500; - --color-ut-gray: #808080; - --color-ut-dark-gray: #333333; - - /* Surface colors - pure black for authentic Undertale void */ - --color-surface-50: #FFFFFF; - --color-surface-100: #E0E0E0; - --color-surface-200: #C0C0C0; - --color-surface-300: #A0A0A0; - --color-surface-400: #808080; - --color-surface-500: #404040; - --color-surface-600: #1a1a1a; - --color-surface-700: #0a0a0a; - --color-surface-800: #000000; - --color-surface-850: #000000; - --color-surface-900: #000000; - --color-surface-950: #000000; - - /* Accent colors (yellow scale) */ - --color-accent-50: #FFFFF0; - --color-accent-100: #FFFFE0; - --color-accent-200: #FFFFC0; - --color-accent-300: #FFFF80; - --color-accent-400: #FFFF00; - --color-accent-500: #E6E600; - --color-accent-600: #CCCC00; - --color-accent-700: #999900; - --color-accent-800: #666600; - --color-accent-900: #333300; - --color-accent-950: #1A1A00; - - /* Semantic colors */ - --bg-primary: var(--color-ut-black); - --bg-secondary: var(--color-ut-black); - --bg-tertiary: var(--color-ut-dark-gray); - --text-primary: var(--color-ut-white); - --text-secondary: #C0C0C0; - --text-muted: var(--color-ut-gray); - --text-accent: var(--color-ut-yellow); - --border-primary: var(--color-ut-white); - --border-secondary: var(--color-ut-gray); - - /* Scrollbar */ - --scrollbar-track: var(--color-ut-black); - --scrollbar-thumb: var(--color-ut-white); - --scrollbar-thumb-hover: var(--color-ut-yellow); - - /* Special undertale effects */ - --ut-border: 4px solid var(--color-ut-white); - --ut-heart-color: var(--color-ut-red); - --ut-action-color: var(--color-ut-orange); - - /* Shadcn Variables (Fallen Down) */ - --background: 0 0% 0%; - /* Black */ - --foreground: 0 0% 100%; - /* White */ - --card: 0 0% 0%; - --card-foreground: 0 0% 100%; - --popover: 0 0% 0%; - --popover-foreground: 0 0% 100%; - --primary: 60 100% 50%; - /* Yellow */ - --primary-foreground: 0 0% 0%; - --secondary: 0 0% 10%; - /* Dark Gray */ - --secondary-foreground: 0 0% 100%; - --muted: 0 0% 20%; - --muted-foreground: 0 0% 75%; - /* Silver */ - --accent: 60 100% 50%; - /* Yellow */ - --accent-foreground: 0 0% 0%; - --destructive: 0 100% 50%; - /* Red */ - --destructive-foreground: 0 0% 100%; - --border: 0 0% 100%; - /* White Border */ - --input: 0 0% 100%; - --ring: 60 100% 50%; - --radius: 0; - - /* Typography - VT323 pixel font */ - --font-story: 'VT323', 'Share Tech Mono', monospace; - } + /* Special effects */ + --crt-scanline: transparent; + --crt-glow: none; + --crt-flicker: none; + --font-story: 'Georgia', 'Cambria', serif; } +/* Dark theme selector for explicit data-theme="dark" */ +[data-theme="dark"] { + /* Same as :root for shadcn variables */ + --background: hsl(222 47% 11%); + --foreground: hsl(210 40% 98%); + --card: hsl(217 33% 17%); + --card-foreground: hsl(210 40% 98%); + --popover: hsl(217 33% 17%); + --popover-foreground: hsl(210 40% 98%); + --primary: hsl(221.2 83.2% 53.3%); + --primary-foreground: hsl(210 40% 98%); + --secondary: hsl(217 33% 25%); + --secondary-foreground: hsl(210 40% 98%); + --muted: hsl(217 33% 25%); + --muted-foreground: hsl(215 20.2% 65.1%); + --accent: hsl(217 33% 25%); + --accent-foreground: hsl(210 40% 98%); + --destructive: hsl(0 62.8% 30.6%); + --destructive-foreground: hsl(210 40% 98%); + --border: hsl(217 33% 25%); + --input: hsl(217 33% 25%); + --ring: hsl(221.2 83.2% 53.3%); +} + +/* ============================================= + LIGHT THEME (Paper) + Clean paper-like backgrounds with high contrast text + ============================================= */ +[data-theme="light"] { + /* Paper-inspired surface colors */ + --color-surface-50: #faf9f7; + --color-surface-100: #f5f3f0; + --color-surface-200: #eceae5; + --color-surface-300: #dedad3; + --color-surface-400: #b8b3a9; + --color-surface-500: #7d786e; + --color-surface-600: #5c5850; + --color-surface-700: #3d3a35; + --color-surface-800: #2a2825; + --color-surface-850: #1f1e1b; + --color-surface-900: #161513; + --color-surface-950: #0a0a09; + + /* Warm accent colors (amber/brown - ink on paper) */ + --color-accent-50: #fef8ee; + --color-accent-100: #fcf0dc; + --color-accent-200: #f8ddb8; + --color-accent-300: #f3c78a; + --color-accent-400: #e6a54a; + --color-accent-500: #c4872d; + --color-accent-600: #a66b1f; + --color-accent-700: #8a5419; + --color-accent-800: #724516; + --color-accent-900: #5f3a14; + --color-accent-950: #361e0a; + + /* Semantic colors */ + --bg-primary: var(--color-surface-50); + --bg-secondary: var(--color-surface-100); + --bg-tertiary: var(--color-surface-200); + --text-primary: var(--color-surface-900); + --text-secondary: var(--color-surface-700); + --text-muted: var(--color-surface-500); + --text-accent: var(--color-accent-600); + --border-primary: var(--color-surface-300); + --border-secondary: var(--color-surface-400); + --scrollbar-track: var(--color-surface-200); + --scrollbar-thumb: var(--color-surface-400); + --scrollbar-thumb-hover: var(--color-surface-500); + + /* Shadcn Variables (Light) */ + --background: hsl(0 0% 100%); + --foreground: hsl(222.2 84% 4.9%); + --card: hsl(0 0% 100%); + --card-foreground: hsl(222.2 84% 4.9%); + --popover: hsl(0 0% 100%); + --popover-foreground: hsl(222.2 84% 4.9%); + --primary: hsl(222.2 47.4% 11.2%); + --primary-foreground: hsl(210 40% 98%); + --secondary: hsl(210 40% 96.1%); + --secondary-foreground: hsl(222.2 47.4% 11.2%); + --muted: hsl(210 40% 96.1%); + --muted-foreground: hsl(215.4 16.3% 46.9%); + --accent: hsl(210 40% 96.1%); + --accent-foreground: hsl(222.2 47.4% 11.2%); + --destructive: hsl(0 84.2% 60.2%); + --destructive-foreground: hsl(210 40% 98%); + --border: hsl(214.3 31.8% 91.4%); + --input: hsl(214.3 31.8% 91.4%); + --ring: hsl(215 20.2% 65.1%); +} + +/* ============================================= + LIGHT THEME (Solarized) + Classic Solarized color scheme + ============================================= */ +[data-theme="light-solarized"] { + /* Solarized base colors */ + --color-surface-50: #fdf6e3; + --color-surface-100: #f5eedb; + --color-surface-200: #eee8d5; + --color-surface-300: #e0d6c1; + --color-surface-400: #9a9181; + --color-surface-500: #6b6459; + --color-surface-600: #544f46; + --color-surface-700: #3d3933; + --color-surface-800: #2a2721; + --color-surface-850: #1e1c18; + --color-surface-900: #141310; + --color-surface-950: #0a0908; + + /* Solarized accent colors (cyan) */ + --color-accent-50: #e8f5f4; + --color-accent-100: #d1ebe9; + --color-accent-200: #a3d7d3; + --color-accent-300: #75c3bd; + --color-accent-400: #2aa198; + --color-accent-500: #24897f; + --color-accent-600: #1e7268; + --color-accent-700: #185b52; + --color-accent-800: #12443d; + --color-accent-900: #0c2d28; + --color-accent-950: #061614; + + /* Semantic colors */ + --bg-primary: var(--color-surface-50); + --bg-secondary: var(--color-surface-100); + --bg-tertiary: var(--color-surface-200); + --text-primary: var(--color-surface-900); + --text-secondary: var(--color-surface-700); + --text-muted: var(--color-surface-500); + --text-accent: var(--color-accent-500); + --border-primary: var(--color-surface-300); + --border-secondary: var(--color-surface-400); + --scrollbar-track: var(--color-surface-200); + --scrollbar-thumb: var(--color-surface-400); + --scrollbar-thumb-hover: var(--color-surface-500); + + /* Shadcn Variables (Light - Solarized) */ + --background: hsl(44 26% 94%); + --foreground: hsl(204 11% 23%); + --card: hsl(43 27% 91%); + --card-foreground: hsl(204 11% 23%); + --popover: hsl(43 27% 91%); + --popover-foreground: hsl(204 11% 23%); + --primary: hsl(175 59% 40%); + --primary-foreground: hsl(44 26% 94%); + --secondary: hsl(42 16% 87%); + --secondary-foreground: hsl(204 11% 23%); + --muted: hsl(42 16% 87%); + --muted-foreground: hsl(38 7% 40%); + --accent: hsl(42 16% 87%); + --accent-foreground: hsl(175 59% 40%); + --destructive: hsl(1 71% 52%); + --destructive-foreground: hsl(44 26% 94%); + --border: hsl(38 15% 82%); + --input: hsl(38 15% 82%); + --ring: hsl(175 59% 40%); +} + +/* ============================================= + RETRO CONSOLE THEME + Inspired by PS2-era games and Serial Experiments Lain + CRT phosphor aesthetic with warm amber accents + ============================================= */ +[data-theme="retro-console"] { + /* Retro CRT color palette */ + --color-retro-black: #050808; + --color-retro-dark: #0a1210; + --color-retro-green-dark: #0c1f18; + --color-retro-green: #39ff14; + --color-retro-green-bright: #7fff00; + --color-retro-green-dim: #2eb82e; + --color-retro-green-muted: #1a4a2e; + --color-retro-cyan: #00e5ff; + --color-retro-cyan-dim: #00b8cc; + --color-retro-amber: #ffb000; + --color-retro-amber-dim: #cc8800; + --color-retro-red: #ff2d2d; + --color-retro-purple: #bf00ff; + + /* Override semantic colors */ + --bg-primary: var(--color-retro-black); + --bg-secondary: var(--color-retro-dark); + --bg-tertiary: var(--color-retro-green-dark); + --text-primary: var(--color-retro-green); + --text-secondary: var(--color-retro-green-dim); + --text-muted: var(--color-retro-green-muted); + --text-accent: var(--color-retro-cyan); + --border-primary: var(--color-retro-green-muted); + --border-secondary: var(--color-retro-green-dark); + --scrollbar-track: var(--color-retro-dark); + --scrollbar-thumb: var(--color-retro-green-muted); + --scrollbar-thumb-hover: var(--color-retro-green-dim); + + /* Surface colors mapped to retro palette */ + --color-surface-50: #d4ffd4; + --color-surface-100: #a8ffa8; + --color-surface-200: #7cff7c; + --color-surface-300: var(--color-retro-green-dim); + --color-surface-400: var(--color-retro-green); + --color-surface-500: var(--color-retro-green-muted); + --color-surface-600: #163828; + --color-surface-700: var(--color-retro-green-dark); + --color-surface-800: var(--color-retro-dark); + --color-surface-850: #070d0b; + --color-surface-900: var(--color-retro-black); + --color-surface-950: #020404; + + /* Accent colors mapped to cyan */ + --color-accent-50: #d4ffff; + --color-accent-100: #a8ffff; + --color-accent-200: #7cffff; + --color-accent-300: #50e5ff; + --color-accent-400: var(--color-retro-cyan); + --color-accent-500: var(--color-retro-cyan-dim); + --color-accent-600: #008fa3; + --color-accent-700: #006b7a; + --color-accent-800: #004752; + --color-accent-900: #002329; + --color-accent-950: #001214; + + /* Enhanced CRT Effects */ + --crt-scanline: rgba(57, 255, 20, 0.04); + --crt-glow: 0 0 8px rgba(57, 255, 20, 0.4), 0 0 16px rgba(57, 255, 20, 0.2), 0 0 32px rgba(57, 255, 20, 0.1); + --crt-text-glow: 0 0 2px rgba(57, 255, 20, 0.8), 0 0 4px rgba(57, 255, 20, 0.4), 0 0 8px rgba(57, 255, 20, 0.2); + --crt-amber-glow: 0 0 4px rgba(255, 176, 0, 0.6), 0 0 8px rgba(255, 176, 0, 0.3); + --crt-cyan-glow: 0 0 4px rgba(0, 229, 255, 0.6), 0 0 8px rgba(0, 229, 255, 0.3); + + /* Retro UI chrome */ + --retro-border: 2px solid var(--color-retro-green-muted); + --retro-border-glow: 0 0 4px rgba(57, 255, 20, 0.3); + + /* Typography - pixelated monospace feel */ + --font-story: 'VT323', 'Share Tech Mono', 'JetBrains Mono', 'Fira Code', 'Courier New', monospace; + + /* Shadcn Variables (Retro) */ + --background: hsl(180 30% 2%); + --foreground: hsl(110 100% 54%); + --card: hsl(168 29% 5%); + --card-foreground: hsl(110 100% 54%); + --popover: hsl(168 29% 5%); + --popover-foreground: hsl(110 100% 54%); + --primary: hsl(186 100% 50%); + --primary-foreground: hsl(180 30% 2%); + --secondary: hsl(158 44% 8%); + --secondary-foreground: hsl(110 100% 54%); + --muted: hsl(158 44% 8%); + --muted-foreground: hsl(144 48% 20%); + --accent: hsl(158 44% 8%); + --accent-foreground: hsl(186 100% 50%); + --destructive: hsl(0 100% 59%); + --destructive-foreground: hsl(180 30% 2%); + --border: hsl(144 48% 20%); + --input: hsl(144 48% 20%); + --ring: hsl(186 100% 50%); + --radius: 0; +} + +/* ============================================= + FALLEN DOWN THEME + Undertale/Deltarune inspired pixel aesthetic + ============================================= */ +[data-theme="fallen-down"] { + /* Undertale color palette */ + --color-ut-black: #000000; + --color-ut-white: #FFFFFF; + --color-ut-yellow: #FFFF00; + --color-ut-red: #FF0000; + --color-ut-orange: #FFA500; + --color-ut-gray: #808080; + --color-ut-dark-gray: #333333; + + /* Surface colors - pure black for authentic Undertale void */ + --color-surface-50: #FFFFFF; + --color-surface-100: #E0E0E0; + --color-surface-200: #C0C0C0; + --color-surface-300: #A0A0A0; + --color-surface-400: #808080; + --color-surface-500: #404040; + --color-surface-600: #1a1a1a; + --color-surface-700: #0a0a0a; + --color-surface-800: #000000; + --color-surface-850: #000000; + --color-surface-900: #000000; + --color-surface-950: #000000; + + /* Accent colors (yellow scale) */ + --color-accent-50: #FFFFF0; + --color-accent-100: #FFFFE0; + --color-accent-200: #FFFFC0; + --color-accent-300: #FFFF80; + --color-accent-400: #FFFF00; + --color-accent-500: #E6E600; + --color-accent-600: #CCCC00; + --color-accent-700: #999900; + --color-accent-800: #666600; + --color-accent-900: #333300; + --color-accent-950: #1A1A00; + + /* Semantic colors */ + --bg-primary: var(--color-ut-black); + --bg-secondary: var(--color-ut-black); + --bg-tertiary: var(--color-ut-dark-gray); + --text-primary: var(--color-ut-white); + --text-secondary: #C0C0C0; + --text-muted: var(--color-ut-gray); + --text-accent: var(--color-ut-yellow); + --border-primary: var(--color-ut-white); + --border-secondary: var(--color-ut-gray); + + /* Scrollbar */ + --scrollbar-track: var(--color-ut-black); + --scrollbar-thumb: var(--color-ut-white); + --scrollbar-thumb-hover: var(--color-ut-yellow); + + /* Special undertale effects */ + --ut-border: 4px solid var(--color-ut-white); + --ut-heart-color: var(--color-ut-red); + --ut-action-color: var(--color-ut-orange); + + /* Typography - VT323 pixel font */ + --font-story: 'VT323', 'Share Tech Mono', monospace; + + /* Shadcn Variables (Fallen Down) */ + --background: hsl(0 0% 0%); + --foreground: hsl(0 0% 100%); + --card: hsl(0 0% 0%); + --card-foreground: hsl(0 0% 100%); + --popover: hsl(0 0% 0%); + --popover-foreground: hsl(0 0% 100%); + --primary: hsl(60 100% 50%); + --primary-foreground: hsl(0 0% 0%); + --secondary: hsl(0 0% 10%); + --secondary-foreground: hsl(0 0% 100%); + --muted: hsl(0 0% 20%); + --muted-foreground: hsl(0 0% 75%); + --accent: hsl(60 100% 50%); + --accent-foreground: hsl(0 0% 0%); + --destructive: hsl(0 100% 50%); + --destructive-foreground: hsl(0 0% 100%); + --border: hsl(0 0% 100%); + --input: hsl(0 0% 100%); + --ring: hsl(60 100% 50%); + --radius: 0; +} + +/* Duplicate @theme block removed */ /* ============================================= BASE STYLES ============================================= */ @layer base { - html { - @apply antialiased; + * { + @apply border-border; } body { - background-color: var(--bg-primary); - color: var(--text-primary); + @apply bg-background text-foreground; } /* Scrollbar styling */ ::-webkit-scrollbar { - @apply w-2; + width: 4px; } ::-webkit-scrollbar-track { - background-color: var(--scrollbar-track); + background-color: transparent; } ::-webkit-scrollbar-thumb { background-color: var(--scrollbar-thumb); - @apply rounded-full; + border-radius: 2px; } ::-webkit-scrollbar-thumb:hover { @@ -710,152 +736,702 @@ } /* ============================================= - COMPONENT STYLES + RETRO CONSOLE THEME ENHANCEMENTS ============================================= */ -@layer components { - .btn { - @apply px-4 py-2 rounded-lg font-medium transition-colors duration-200; + +/* Digital noise texture (subtle static effect) */ +[data-theme="retro-console"] { + background-image: url("data:image/svg+xml,%3Csvg viewBox='0 0 256 256' xmlns='http://www.w3.org/2000/svg'%3E%3Cfilter id='noise'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='0.8' numOctaves='3' stitchTiles='stitch'/%3E%3C/filter%3E%3Crect width='100%25' height='100%25' filter='url(%23noise)' opacity='0.015'/%3E%3C/svg%3E"); +} + +/* Subtle glitch effect on hover */ +[data-theme="retro-console"] a:hover, +[data-theme="retro-console"] button:hover:not(:disabled) { + animation: retro-glitch 0.2s ease-in-out; +} + +@keyframes retro-glitch { + + 0%, + 100% { + transform: translateX(0); + filter: none; } - .btn-primary { - @apply h-9 flex items-center justify-center gap-2 px-4 rounded-lg bg-accent-600 text-surface-100 text-sm font-medium; + 20% { + transform: translateX(-1px); + filter: hue-rotate(10deg); } - .btn-primary:hover { - @apply bg-accent-500; + 40% { + transform: translateX(1px); + filter: hue-rotate(-10deg); } - .btn-primary:active { - @apply bg-accent-700; + 60% { + transform: translateX(-1px); } - .btn-primary:disabled { - @apply bg-surface-700 text-surface-500 cursor-not-allowed; + 80% { + transform: translateX(1px); + } +} + +/* Terminal cursor blink */ +[data-theme="retro-console"] input:focus, +[data-theme="retro-console"] textarea:focus { + caret-color: var(--color-retro-green); +} + +/* Blinking cursor animation */ +@keyframes cursor-blink { + + 0%, + 50% { + opacity: 1; } - .btn-secondary { - @apply h-9 flex items-center justify-center gap-2 px-3 rounded-lg border border-surface-600 bg-surface-800 text-sm text-surface-300 font-medium; + 51%, + 100% { + opacity: 0; + } +} + +/* Override Tailwind classes for retro theme */ +[data-theme="retro-console"] .bg-surface-900 { + background-color: var(--color-surface-900); +} + +[data-theme="retro-console"] .bg-surface-800 { + background-color: var(--color-surface-800); +} + +[data-theme="retro-console"] .bg-surface-700 { + background-color: var(--color-surface-700); +} + +[data-theme="retro-console"] .bg-surface-600 { + background-color: var(--color-surface-600); +} + +[data-theme="retro-console"] .text-surface-100 { + color: var(--color-surface-100); +} + +[data-theme="retro-console"] .text-surface-200 { + color: var(--color-surface-200); +} + +[data-theme="retro-console"] .text-surface-300 { + color: var(--color-surface-300); +} + +[data-theme="retro-console"] .text-surface-400 { + color: var(--color-surface-400); +} + +[data-theme="retro-console"] .text-surface-500 { + color: var(--color-surface-500); +} + +[data-theme="retro-console"] .border-surface-700 { + border-color: var(--color-surface-700); +} + +[data-theme="retro-console"] .border-surface-600 { + border-color: var(--color-surface-600); +} + +[data-theme="retro-console"] .bg-accent-600 { + background-color: var(--color-accent-600); +} + +[data-theme="retro-console"] .bg-accent-700 { + background-color: var(--color-accent-700); +} + +[data-theme="retro-console"] .text-accent-400 { + color: var(--color-accent-400); +} + +[data-theme="retro-console"] .text-accent-500 { + color: var(--color-accent-500); +} + +[data-theme="retro-console"] .text-accent-600 { + color: var(--color-accent-600); +} + +[data-theme="retro-console"] .ring-accent-500 { + --tw-ring-color: var(--color-accent-500); +} + +[data-theme="retro-console"] .focus\:ring-accent-500:focus { + --tw-ring-color: var(--color-accent-500); +} + +/* Hover states */ +[data-theme="retro-console"] .hover\:bg-surface-600:hover { + background-color: var(--color-surface-600); +} + +[data-theme="retro-console"] .hover\:bg-surface-700:hover { + background-color: var(--color-surface-700); +} + +[data-theme="retro-console"] .hover\:bg-surface-800:hover { + background-color: var(--color-surface-800); +} + +[data-theme="retro-console"] .hover\:bg-accent-700:hover { + background-color: var(--color-accent-700); +} + +[data-theme="retro-console"] .hover\:text-surface-100:hover { + color: var(--color-surface-100); +} + +/* Special retro status colors */ +[data-theme="retro-console"] .text-green-400 { + color: var(--color-retro-green); + text-shadow: var(--crt-text-glow); +} + +[data-theme="retro-console"] .text-amber-400 { + color: var(--color-retro-amber); + text-shadow: var(--crt-amber-glow); +} + +[data-theme="retro-console"] .text-red-400 { + color: var(--color-retro-red); + text-shadow: 0 0 4px rgba(255, 45, 45, 0.5); +} + +[data-theme="retro-console"] .text-blue-400 { + color: var(--color-retro-cyan); + text-shadow: var(--crt-cyan-glow); +} + +[data-theme="retro-console"] .text-purple-400 { + color: var(--color-retro-purple); + text-shadow: 0 0 4px rgba(191, 0, 255, 0.5); +} + +[data-theme="retro-console"] .text-yellow-400 { + color: var(--color-retro-amber); + text-shadow: var(--crt-amber-glow); +} + +[data-theme="retro-console"] .text-pink-400 { + color: #ff69b4; + text-shadow: 0 0 4px rgba(255, 105, 180, 0.5); +} + +/* ============================================= + FALLEN DOWN THEME COMPONENT OVERRIDES + Undertale/Deltarune inspired pixel aesthetic + ============================================= */ + +/* Undertale soul float animation */ +@keyframes ut-soul-float { + + 0%, + 100% { + transform: translateY(0px); } - .btn-secondary:hover { - @apply border-surface-500 text-surface-100; + 50% { + transform: translateY(-5px); + } +} + +/* Undertale heart blink animation */ +@keyframes ut-heart-blink { + + 0%, + 100% { + opacity: 1; } - .btn-secondary:disabled { - @apply bg-surface-800 text-surface-600 border-surface-700 cursor-not-allowed; + 50% { + opacity: 0; } +} - .btn-ghost { - background-color: transparent; - color: var(--text-secondary); - } +[data-theme="fallen-down"] .ut-soul-float { + animation: ut-soul-float 2s infinite ease-in-out; +} - .btn-ghost:hover { - background-color: var(--bg-secondary); - color: var(--text-primary); - } +[data-theme="fallen-down"] .ut-heart-blink { + animation: ut-heart-blink 1s step-end infinite; +} - .nav-tab-active { - background-color: var(--color-surface-700); - } +/* Pixel border overrides for cards and panels */ +[data-theme="fallen-down"] .card, +[data-theme="fallen-down"] .panel { + border: 4px solid white; + border-radius: 0; + background-color: black; +} - .input { - @apply w-full px-3 py-2 rounded-lg transition-colors duration-200; - background-color: var(--bg-secondary); - border: 1px solid var(--border-primary); - color: var(--text-primary); - } +/* Input styling */ +[data-theme="fallen-down"] .input, +[data-theme="fallen-down"] select.input { + border: 2px solid white; + border-radius: 0; + background-color: black; + color: white; +} - .input::placeholder { - color: var(--text-muted); - } +[data-theme="fallen-down"] .input:focus, +[data-theme="fallen-down"] select.input:focus { + border-color: #FFFF00; + outline: none; + box-shadow: none; + --tw-ring-shadow: none; +} - .input:focus { - @apply outline-none; - border: 1px solid var(--color-accent-500); - } +[data-theme="fallen-down"] .input::placeholder { + color: #808080; +} - /* Minimal scrollbar for textareas */ - textarea.input::-webkit-scrollbar { - @apply w-1.5; - } +/* Button styling */ +[data-theme="fallen-down"] .btn { + border: 2px solid white; + border-radius: 0; + background-color: black; + color: white; + text-transform: uppercase; + letter-spacing: 0.1em; +} - textarea.input::-webkit-scrollbar-track { - background: transparent; - } +[data-theme="fallen-down"] .btn:hover { + background-color: white; + color: black; +} - textarea.input::-webkit-scrollbar-thumb { - background-color: var(--scrollbar-thumb); - @apply rounded-full; - } +[data-theme="fallen-down"] .btn-primary { + border-color: #FFFF00; + color: #FFFF00; +} - textarea.input::-webkit-scrollbar-thumb:hover { - background-color: var(--scrollbar-thumb-hover); - } +[data-theme="fallen-down"] .btn-primary:hover { + background-color: #FFFF00; + color: black; +} - /* Select dropdown styling */ - select.input { - cursor: pointer; - -webkit-appearance: none; - -moz-appearance: none; - appearance: none; - background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='16' height='16' viewBox='0 0 24 24' fill='none' stroke='%2394a3b8' 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.75rem center; - background-size: 16px 16px; - padding-right: 2.5rem; - } +/* Sidebar styling */ +[data-theme="fallen-down"] .sidebar { + border-right: 4px solid white !important; + background-color: #000000 !important; +} - /* Hide native arrow in IE/Edge */ - select.input::-ms-expand { - display: none; - } +[data-theme="fallen-down"] .sidebar-container { + background-color: #000000 !important; +} - select.input option { - background-color: var(--bg-secondary); - color: var(--text-primary); - padding: 0.5rem; - } +/* Modal styling */ +[data-theme="fallen-down"] .modal-content { + border: 4px solid white; + border-radius: 0; + background-color: black; +} - select.input option:hover, - select.input option:focus, - select.input option:checked { - background-color: var(--color-accent-600); - color: white; - } +/* Selection styling */ +[data-theme="fallen-down"] ::selection { + background-color: #FFFF00; + color: black; +} - /* Checkbox styling */ - input[type="checkbox"] { - @apply appearance-none cursor-pointer; - background-color: var(--bg-tertiary); - border: 1px solid var(--border-primary); - transition: all 0.2s ease; - } +/* Scrollbar styling */ +[data-theme="fallen-down"] ::-webkit-scrollbar { + width: 12px; +} - input[type="checkbox"]:checked { - background-color: var(--color-accent-600); - border-color: var(--color-accent-600); - background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='16' height='16' viewBox='0 0 24 24' fill='none' stroke='white' stroke-width='3' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpolyline points='20 6 9 17 4 12'%3E%3C/polyline%3E%3C/svg%3E"); - background-size: 80%; - background-position: center; - background-repeat: no-repeat; - } +[data-theme="fallen-down"] ::-webkit-scrollbar-track { + background: black; + border-left: 2px solid white; +} - input[type="checkbox"]:focus { - @apply outline-none ring-2; - --tw-ring-color: var(--color-accent-500); - } +[data-theme="fallen-down"] ::-webkit-scrollbar-thumb { + background: white; + border: 2px solid black; +} - .card { - @apply rounded-xl p-4; - background-color: var(--bg-secondary); - border: 1px solid var(--border-primary); - } +[data-theme="fallen-down"] ::-webkit-scrollbar-thumb:hover { + background: #FFFF00; +} - .panel { - background-color: var(--bg-secondary); - border-right: 1px solid var(--border-primary); - } +/* Story text styling */ +[data-theme="fallen-down"] .story-text, +[data-theme="fallen-down"] .narration { + font-family: 'VT323', 'Share Tech Mono', monospace; +} + +/* Select dropdown styling */ +[data-theme="fallen-down"] select.input { + background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='16' height='16' viewBox='0 0 24 24' fill='none' stroke='%23FFFF00' 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"); +} + +[data-theme="fallen-down"] select.input option { + background-color: black; + color: white; +} + +[data-theme="fallen-down"] select.input option:checked { + background-color: #FFFF00; + color: black; +} + +/* Override Tailwind classes for fallen-down theme */ +[data-theme="fallen-down"] .bg-surface-950, +[data-theme="fallen-down"] .bg-surface-900, +[data-theme="fallen-down"] .bg-surface-850, +[data-theme="fallen-down"] .bg-surface-800, +[data-theme="fallen-down"] .bg-surface-700 { + background-color: #000000 !important; +} + +[data-theme="fallen-down"] .bg-surface-600 { + background-color: #0a0a0a !important; +} + +[data-theme="fallen-down"] .bg-surface-500 { + background-color: #1a1a1a !important; +} + +[data-theme="fallen-down"] .text-surface-50 { + color: #FFFFFF !important; +} + +[data-theme="fallen-down"] .text-surface-100 { + color: #FFFFFF !important; +} + +[data-theme="fallen-down"] .text-surface-200 { + color: #E0E0E0 !important; +} + +[data-theme="fallen-down"] .text-surface-300 { + color: #C0C0C0 !important; +} + +[data-theme="fallen-down"] .text-surface-400 { + color: #808080 !important; +} + +[data-theme="fallen-down"] .text-surface-500 { + color: #606060 !important; +} + +[data-theme="fallen-down"] .border-surface-700 { + border-color: #FFFFFF !important; +} + +[data-theme="fallen-down"] .border-surface-600 { + border-color: #808080 !important; +} + +/* Accent colors - all yellow, no blue */ +[data-theme="fallen-down"] .bg-accent-500 { + background-color: #FFFF00; +} + +[data-theme="fallen-down"] .bg-accent-600 { + background-color: #FFFF00; +} + +[data-theme="fallen-down"] .bg-accent-700 { + background-color: #E6E600; +} + +[data-theme="fallen-down"] .text-accent-400 { + color: #FFFF00; +} + +[data-theme="fallen-down"] .text-accent-500 { + color: #FFFF00; +} + +[data-theme="fallen-down"] .text-accent-600 { + color: #FFFF00; +} + +/* Focus rings - yellow instead of blue */ +[data-theme="fallen-down"] .ring-accent-500 { + --tw-ring-color: #FFFF00; +} + +[data-theme="fallen-down"] .focus\:ring-accent-500:focus { + --tw-ring-color: #FFFF00; +} + +[data-theme="fallen-down"] *:focus { + outline-color: #FFFF00; +} + +[data-theme="fallen-down"] [class*="focus:ring"] { + --tw-ring-color: #FFFF00 !important; +} + +/* Override ALL blue colors to yellow (Undertale has no blue UI) */ +[data-theme="fallen-down"] .text-blue-400, +[data-theme="fallen-down"] .text-blue-500, +[data-theme="fallen-down"] .text-blue-600 { + color: #FFFF00; +} + +[data-theme="fallen-down"] .bg-blue-400, +[data-theme="fallen-down"] .bg-blue-500, +[data-theme="fallen-down"] .bg-blue-600 { + background-color: #FFFF00; + color: #000000; +} + +[data-theme="fallen-down"] .border-blue-400, +[data-theme="fallen-down"] .border-blue-500, +[data-theme="fallen-down"] .border-blue-600 { + border-color: #FFFF00; +} + +/* Override indigo/purple to yellow as well */ +[data-theme="fallen-down"] .text-indigo-400, +[data-theme="fallen-down"] .text-indigo-500, +[data-theme="fallen-down"] .bg-indigo-900 { + color: #FFFF00; + background-color: transparent; +} + +[data-theme="fallen-down"] .border-indigo-400 { + border-color: #FFFF00; +} + +/* Links - yellow like Undertale's save points */ +[data-theme="fallen-down"] a { + color: #FFFF00; +} + +[data-theme="fallen-down"] a:hover { + color: #FFFFFF; +} + +/* Hover states */ +[data-theme="fallen-down"] .hover\:bg-surface-600:hover { + background-color: #0a0a0a !important; +} + +[data-theme="fallen-down"] .hover\:bg-surface-700:hover { + background-color: #0a0a0a !important; +} + +[data-theme="fallen-down"] .hover\:bg-surface-800:hover { + background-color: #000000 !important; +} + +[data-theme="fallen-down"] .hover\:bg-accent-700:hover { + background-color: #FFFF00 !important; + color: #000000 !important; +} + +[data-theme="fallen-down"] .hover\:text-surface-100:hover { + color: #FFFFFF !important; +} + +[data-theme="fallen-down"] .hover\:text-accent-400:hover { + color: #FFFF00 !important; +} + +/* Ensure body and root backgrounds are pure black */ +[data-theme="fallen-down"], +[data-theme="fallen-down"] body, +[data-theme="fallen-down"] .app-shell, +[data-theme="fallen-down"] main, +[data-theme="fallen-down"] .main-content { + background-color: #000000 !important; +} + +/* Override any remaining slate/blue-tinted backgrounds */ +[data-theme="fallen-down"] [class*="bg-slate"], +[data-theme="fallen-down"] [class*="bg-gray"] { + background-color: #000000 !important; +} + +/* Prose/narrative content area - pure black */ +[data-theme="fallen-down"] .prose, +[data-theme="fallen-down"] .prose-content, +[data-theme="fallen-down"] article, +[data-theme="fallen-down"] .story-container { + background-color: #000000 !important; +} + +/* Any divs with background colors should be black */ +[data-theme="fallen-down"] div[class*="bg-surface"] { + background-color: #000000 !important; +} + +/* Override opacity-modified backgrounds (like bg-surface-800/50) */ +[data-theme="fallen-down"] [class*="bg-surface-800\/"], +[data-theme="fallen-down"] [class*="bg-surface-700\/"], +[data-theme="fallen-down"] [class*="bg-surface-900\/"] { + background-color: rgba(0, 0, 0, 0.5) !important; +} + +/* Story entry backgrounds - darker with slight visibility */ +[data-theme="fallen-down"] .group.rounded-lg { + background-color: rgba(20, 20, 20, 0.5) !important; + border-left-color: #FFFFFF !important; +} + +/* Undertale status colors - limited palette */ +[data-theme="fallen-down"] .text-green-400 { + color: #00FF00; +} + +[data-theme="fallen-down"] .text-amber-400 { + color: #FFA500; +} + +[data-theme="fallen-down"] .text-red-400 { + color: #FF0000; +} + +[data-theme="fallen-down"] .text-yellow-400 { + color: #FFFF00; +} + +/* Primary button - yellow like FIGHT/ACT buttons */ +[data-theme="fallen-down"] .btn-primary { + background-color: transparent; + border: 2px solid #FFFF00; + color: #FFFF00; +} + +[data-theme="fallen-down"] .btn-primary:hover { + background-color: #FFFF00; + color: #000000; +} + +/* Tags and badges - white/yellow only */ +[data-theme="fallen-down"] [class*="bg-indigo"], +[data-theme="fallen-down"] [class*="bg-blue"], +[data-theme="fallen-down"] [class*="bg-purple"] { + background-color: #1a1a1a; + border: 1px solid #FFFF00; + color: #FFFF00; +} + +/* Checkboxes and toggles */ +[data-theme="fallen-down"] input[type="checkbox"]:checked { + background-color: #FFFF00; + border-color: #FFFF00; +} + +/* Range inputs */ +[data-theme="fallen-down"] input[type="range"]::-webkit-slider-thumb { + background-color: #FFFF00; +} + +[data-theme="fallen-down"] input[type="range"]::-moz-range-thumb { + background-color: #FFFF00; +} + +/* ============================================= + LIGHT THEME TAILWIND OVERRIDES + Override Tailwind classes for light theme + ============================================= */ + +/* Background overrides - INVERT for light theme (dark numbers = light colors) */ +[data-theme="light"] .bg-surface-900 { + background-color: var(--color-surface-50); +} + +[data-theme="light"] .bg-surface-850 { + background-color: var(--color-surface-100); +} + +[data-theme="light"] .bg-surface-800 { + background-color: var(--color-surface-100); +} + +[data-theme="light"] .bg-surface-700 { + background-color: var(--color-surface-200); +} + +[data-theme="light"] .bg-surface-600 { + background-color: var(--color-surface-300); +} + +[data-theme="light"] .bg-surface-500 { + background-color: var(--color-surface-400); +} + +[data-theme="light"] .bg-surface-400 { + background-color: var(--color-surface-400); +} + +[data-theme="light"] .bg-surface-300 { + background-color: var(--color-surface-300); +} + +[data-theme="light"] .bg-surface-200 { + background-color: var(--color-surface-200); +} + +[data-theme="light"] .bg-surface-100 { + background-color: var(--color-surface-100); +} + +[data-theme="light"] .bg-surface-50 { + background-color: var(--color-surface-50); +} + +/* Text color overrides - INVERT for light theme (light numbers = dark colors) */ +[data-theme="light"] .text-surface-50 { + color: var(--color-surface-950); +} + +[data-theme="light"] .text-surface-100 { + color: var(--color-surface-900); +} + +[data-theme="light"] .text-surface-200 { + color: var(--color-surface-800); +} + +[data-theme="light"] .text-surface-300 { + color: var(--color-surface-700); +} + +[data-theme="light"] .text-surface-400 { + color: var(--color-surface-500); +} + +[data-theme="light"] .text-surface-500 { + color: var(--color-surface-500); +} + +/* Border color overrides */ +[data-theme="light"] .border-surface-700 { + border-color: var(--color-surface-300); +} + +[data-theme="light"] .border-surface-600 { + border-color: var(--color-surface-400); +} + +/* Select dropdown styling */ +[data-theme="light"] select.input { + background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='16' height='16' viewBox='0 0 24 24' fill='none' stroke='%23475569' 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"); +} + +[data-theme="light"] select.input option { + background-color: var(--color-surface-100); + color: var(--color-surface-900); +} + +[data-theme="light"] select.input option:checked { + background-color: var(--color-accent-600); + color: white; } /* ============================================= @@ -898,7 +1474,6 @@ ============================================= */ .prose-content { - /* Paragraphs */ p { @apply mb-4 last:mb-0; @@ -1095,7 +1670,6 @@ /* Retro Console theme prose overrides */ [data-theme="retro-console"] .prose-content { - h1, h2, h3, @@ -1130,2055 +1704,20 @@ } } -/* ============================================= - RETRO CONSOLE THEME ENHANCEMENTS - ============================================= */ - -/* Digital noise texture (subtle static effect) */ -[data-theme="retro-console"] { - background-image: url("data:image/svg+xml,%3Csvg viewBox='0 0 256 256' xmlns='http://www.w3.org/2000/svg'%3E%3Cfilter id='noise'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='0.8' numOctaves='3' stitchTiles='stitch'/%3E%3C/filter%3E%3Crect width='100%25' height='100%25' filter='url(%23noise)' opacity='0.015'/%3E%3C/svg%3E"); -} - -/* Subtle glitch effect on hover */ -[data-theme="retro-console"] a:hover, -[data-theme="retro-console"] button:hover:not(:disabled) { - animation: retro-glitch 0.2s ease-in-out; -} - -@keyframes retro-glitch { - - 0%, - 100% { - transform: translateX(0); - filter: none; +@keyframes collapsible-down { + from { + height: 0; } - - 20% { - transform: translateX(-1px); - filter: hue-rotate(10deg); - } - - 40% { - transform: translateX(1px); - filter: hue-rotate(-10deg); - } - - 60% { - transform: translateX(-1px); - } - - 80% { - transform: translateX(1px); - } -} - -/* Terminal cursor blink */ -[data-theme="retro-console"] input:focus, -[data-theme="retro-console"] textarea:focus { - caret-color: var(--color-retro-green); -} - -/* Blinking cursor animation */ -@keyframes cursor-blink { - - 0%, - 50% { - opacity: 1; - } - - 51%, - 100% { - opacity: 0; - } -} - -/* Override Tailwind classes for retro theme */ -[data-theme="retro-console"] .bg-surface-900 { - background-color: var(--color-surface-900); -} - -[data-theme="retro-console"] .bg-surface-800 { - background-color: var(--color-surface-800); -} - -[data-theme="retro-console"] .bg-surface-700 { - background-color: var(--color-surface-700); -} - -[data-theme="retro-console"] .bg-surface-600 { - background-color: var(--color-surface-600); -} - -[data-theme="retro-console"] .text-surface-100 { - color: var(--color-surface-100); -} - -[data-theme="retro-console"] .text-surface-200 { - color: var(--color-surface-200); -} - -[data-theme="retro-console"] .text-surface-300 { - color: var(--color-surface-300); -} - -[data-theme="retro-console"] .text-surface-400 { - color: var(--color-surface-400); -} - -[data-theme="retro-console"] .text-surface-500 { - color: var(--color-surface-500); -} - -[data-theme="retro-console"] .border-surface-700 { - border-color: var(--color-surface-700); -} - -[data-theme="retro-console"] .border-surface-600 { - border-color: var(--color-surface-600); -} - -[data-theme="retro-console"] .bg-accent-600 { - background-color: var(--color-accent-600); -} - -[data-theme="retro-console"] .bg-accent-700 { - background-color: var(--color-accent-700); -} - -[data-theme="retro-console"] .text-accent-400 { - color: var(--color-accent-400); -} - -[data-theme="retro-console"] .text-accent-500 { - color: var(--color-accent-500); -} - -[data-theme="retro-console"] .text-accent-600 { - color: var(--color-accent-600); -} - -[data-theme="retro-console"] .ring-accent-500 { - --tw-ring-color: var(--color-accent-500); -} - -[data-theme="retro-console"] .focus\:ring-accent-500:focus { - --tw-ring-color: var(--color-accent-500); -} - -/* Hover states */ -[data-theme="retro-console"] .hover\:bg-surface-600:hover { - background-color: var(--color-surface-600); -} - -[data-theme="retro-console"] .hover\:bg-surface-700:hover { - background-color: var(--color-surface-700); -} - -[data-theme="retro-console"] .hover\:bg-surface-800:hover { - background-color: var(--color-surface-800); -} - -[data-theme="retro-console"] .hover\:bg-accent-700:hover { - background-color: var(--color-accent-700); -} - -[data-theme="retro-console"] .hover\:text-surface-100:hover { - color: var(--color-surface-100); -} - -/* Special retro status colors */ -[data-theme="retro-console"] .text-green-400 { - color: var(--color-retro-green); - text-shadow: var(--crt-text-glow); -} - -[data-theme="retro-console"] .text-amber-400 { - color: var(--color-retro-amber); - text-shadow: var(--crt-amber-glow); -} - -[data-theme="retro-console"] .text-red-400 { - color: var(--color-retro-red); - text-shadow: 0 0 4px rgba(255, 45, 45, 0.5); -} - -[data-theme="retro-console"] .text-blue-400 { - color: var(--color-retro-cyan); - text-shadow: var(--crt-cyan-glow); -} - -[data-theme="retro-console"] .text-purple-400 { - color: var(--color-retro-purple); - text-shadow: 0 0 4px rgba(191, 0, 255, 0.5); -} - -[data-theme="retro-console"] .text-yellow-400 { - color: var(--color-retro-amber); - text-shadow: var(--crt-amber-glow); -} - -[data-theme="retro-console"] .text-pink-400 { - color: #ff69b4; - text-shadow: 0 0 4px rgba(255, 105, 180, 0.5); -} - -/* Select styling for Retro theme */ -[data-theme="retro-console"] select.input { - background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='16' height='16' viewBox='0 0 24 24' fill='none' stroke='%2339ff14' 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"); -} - -[data-theme="retro-console"] select.input option { - background-color: var(--color-retro-dark); - color: var(--color-retro-green); -} - -[data-theme="retro-console"] select.input option:checked { - background-color: var(--color-retro-green-muted); - color: var(--color-retro-green); -} - -/* ============================================= - FALLEN DOWN THEME COMPONENT OVERRIDES - Undertale/Deltarune inspired pixel aesthetic - ============================================= */ - -/* Undertale soul float animation */ -@keyframes ut-soul-float { - - 0%, - 100% { - transform: translateY(0px); - } - - 50% { - transform: translateY(-5px); - } -} - -/* Undertale heart blink animation */ -@keyframes ut-heart-blink { - - 0%, - 100% { - opacity: 1; - } - - 50% { - opacity: 0; - } -} - -[data-theme="fallen-down"] .ut-soul-float { - animation: ut-soul-float 2s infinite ease-in-out; -} - -[data-theme="fallen-down"] .ut-heart-blink { - animation: ut-heart-blink 1s step-end infinite; -} - -/* Pixel border overrides for cards and panels */ -[data-theme="fallen-down"] .card, -[data-theme="fallen-down"] .panel { - border: 4px solid white; - border-radius: 0; - background-color: black; -} - -/* Input styling */ -[data-theme="fallen-down"] .input, -[data-theme="fallen-down"] select.input { - border: 2px solid white; - border-radius: 0; - background-color: black; - color: white; -} - -[data-theme="fallen-down"] .input:focus, -[data-theme="fallen-down"] select.input:focus { - border-color: #FFFF00; - outline: none; - box-shadow: none; - --tw-ring-shadow: none; -} - -[data-theme="fallen-down"] .input::placeholder { - color: #808080; -} - -/* Button styling */ -[data-theme="fallen-down"] .btn { - border: 2px solid white; - border-radius: 0; - background-color: black; - color: white; - text-transform: uppercase; - letter-spacing: 0.1em; -} - -[data-theme="fallen-down"] .btn:hover { - background-color: white; - color: black; -} - -[data-theme="fallen-down"] .btn-primary { - border-color: #FFFF00; - color: #FFFF00; -} - -[data-theme="fallen-down"] .btn-primary:hover { - background-color: #FFFF00; - color: black; -} - -/* Sidebar styling */ -[data-theme="fallen-down"] .sidebar { - border-right: 4px solid white !important; - background-color: #000000 !important; -} - -[data-theme="fallen-down"] .sidebar-container { - background-color: #000000 !important; -} - -/* Modal styling */ -[data-theme="fallen-down"] .modal-content { - border: 4px solid white; - border-radius: 0; - background-color: black; -} - -/* Selection styling */ -[data-theme="fallen-down"] ::selection { - background-color: #FFFF00; - color: black; -} - -/* Scrollbar styling */ -[data-theme="fallen-down"] ::-webkit-scrollbar { - width: 12px; -} - -[data-theme="fallen-down"] ::-webkit-scrollbar-track { - background: black; - border-left: 2px solid white; -} - -[data-theme="fallen-down"] ::-webkit-scrollbar-thumb { - background: white; - border: 2px solid black; -} - -[data-theme="fallen-down"] ::-webkit-scrollbar-thumb:hover { - background: #FFFF00; -} - -/* Story text styling */ -[data-theme="fallen-down"] .story-text, -[data-theme="fallen-down"] .narration { - font-family: 'VT323', 'Share Tech Mono', monospace; -} - -/* Select dropdown styling */ -[data-theme="fallen-down"] select.input { - background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='16' height='16' viewBox='0 0 24 24' fill='none' stroke='%23FFFF00' 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"); -} - -[data-theme="fallen-down"] select.input option { - background-color: black; - color: white; -} - -[data-theme="fallen-down"] select.input option:checked { - background-color: #FFFF00; - color: black; -} - -/* Override Tailwind classes for fallen-down theme - !important needed to override static Tailwind values */ -[data-theme="fallen-down"] .bg-surface-950, -[data-theme="fallen-down"] .bg-surface-900, -[data-theme="fallen-down"] .bg-surface-850, -[data-theme="fallen-down"] .bg-surface-800, -[data-theme="fallen-down"] .bg-surface-700 { - background-color: #000000 !important; -} - -[data-theme="fallen-down"] .bg-surface-600 { - background-color: #0a0a0a !important; -} - -[data-theme="fallen-down"] .bg-surface-500 { - background-color: #1a1a1a !important; -} - -[data-theme="fallen-down"] .text-surface-50 { - color: #FFFFFF !important; -} - -[data-theme="fallen-down"] .text-surface-100 { - color: #FFFFFF !important; -} - -[data-theme="fallen-down"] .text-surface-200 { - color: #E0E0E0 !important; -} - -[data-theme="fallen-down"] .text-surface-300 { - color: #C0C0C0 !important; -} - -[data-theme="fallen-down"] .text-surface-400 { - color: #808080 !important; -} - -[data-theme="fallen-down"] .text-surface-500 { - color: #606060 !important; -} - -[data-theme="fallen-down"] .border-surface-700 { - border-color: #FFFFFF !important; -} - -[data-theme="fallen-down"] .border-surface-600 { - border-color: #808080 !important; -} - -/* Accent colors - all yellow, no blue */ -[data-theme="fallen-down"] .bg-accent-500 { - background-color: #FFFF00; -} - -[data-theme="fallen-down"] .bg-accent-600 { - background-color: #FFFF00; -} - -[data-theme="fallen-down"] .bg-accent-700 { - background-color: #E6E600; -} - -[data-theme="fallen-down"] .text-accent-400 { - color: #FFFF00; -} - -[data-theme="fallen-down"] .text-accent-500 { - color: #FFFF00; -} - -[data-theme="fallen-down"] .text-accent-600 { - color: #FFFF00; -} - -/* Focus rings - yellow instead of blue */ -[data-theme="fallen-down"] .ring-accent-500 { - --tw-ring-color: #FFFF00; -} - -[data-theme="fallen-down"] .focus\:ring-accent-500:focus { - --tw-ring-color: #FFFF00; -} - -[data-theme="fallen-down"] *:focus { - outline-color: #FFFF00; -} - -[data-theme="fallen-down"] [class*="focus:ring"] { - --tw-ring-color: #FFFF00 !important; -} - -/* Override ALL blue colors to yellow (Undertale has no blue UI) */ -[data-theme="fallen-down"] .text-blue-400, -[data-theme="fallen-down"] .text-blue-500, -[data-theme="fallen-down"] .text-blue-600 { - color: #FFFF00; -} - -[data-theme="fallen-down"] .bg-blue-400, -[data-theme="fallen-down"] .bg-blue-500, -[data-theme="fallen-down"] .bg-blue-600 { - background-color: #FFFF00; - color: #000000; -} - -[data-theme="fallen-down"] .border-blue-400, -[data-theme="fallen-down"] .border-blue-500, -[data-theme="fallen-down"] .border-blue-600 { - border-color: #FFFF00; -} - -/* Override indigo/purple to yellow as well */ -[data-theme="fallen-down"] .text-indigo-400, -[data-theme="fallen-down"] .text-indigo-500, -[data-theme="fallen-down"] .bg-indigo-900 { - color: #FFFF00; - background-color: transparent; -} - -[data-theme="fallen-down"] .border-indigo-400 { - border-color: #FFFF00; -} - -/* Links - yellow like Undertale's save points */ -[data-theme="fallen-down"] a { - color: #FFFF00; -} - -[data-theme="fallen-down"] a:hover { - color: #FFFFFF; -} - -/* Hover states */ -[data-theme="fallen-down"] .hover\:bg-surface-600:hover { - background-color: #1a1a1a !important; -} - -[data-theme="fallen-down"] .hover\:bg-surface-700:hover { - background-color: #0a0a0a !important; -} - -[data-theme="fallen-down"] .hover\:bg-surface-800:hover { - background-color: #000000 !important; -} - -[data-theme="fallen-down"] .hover\:bg-accent-700:hover { - background-color: #FFFF00 !important; - color: #000000 !important; -} - -[data-theme="fallen-down"] .hover\:text-surface-100:hover { - color: #FFFFFF !important; -} - -[data-theme="fallen-down"] .hover\:text-accent-400:hover { - color: #FFFF00 !important; -} - -/* Ensure body and root backgrounds are pure black */ -[data-theme="fallen-down"], -[data-theme="fallen-down"] body, -[data-theme="fallen-down"] .app-shell, -[data-theme="fallen-down"] main, -[data-theme="fallen-down"] .main-content { - background-color: #000000 !important; -} - -/* Override any remaining slate/blue-tinted backgrounds */ -[data-theme="fallen-down"] [class*="bg-slate"], -[data-theme="fallen-down"] [class*="bg-gray"] { - background-color: #000000 !important; -} - -/* Prose/narrative content area - pure black */ -[data-theme="fallen-down"] .prose, -[data-theme="fallen-down"] .prose-content, -[data-theme="fallen-down"] article, -[data-theme="fallen-down"] .story-container { - background-color: #000000 !important; -} - -/* Any divs with background colors should be black */ -[data-theme="fallen-down"] div[class*="bg-surface"] { - background-color: #000000 !important; -} - -/* Override opacity-modified backgrounds (like bg-surface-800/50) */ -[data-theme="fallen-down"] [class*="bg-surface-800\/"], -[data-theme="fallen-down"] [class*="bg-surface-700\/"], -[data-theme="fallen-down"] [class*="bg-surface-900\/"] { - background-color: rgba(0, 0, 0, 0.5) !important; -} - -/* Story entry backgrounds - darker with slight visibility */ -[data-theme="fallen-down"] .group.rounded-lg { - background-color: rgba(20, 20, 20, 0.5) !important; - border-left-color: #FFFFFF !important; -} - -/* Undertale status colors - limited palette */ -[data-theme="fallen-down"] .text-green-400 { - color: #00FF00; -} - -[data-theme="fallen-down"] .text-amber-400 { - color: #FFA500; -} - -[data-theme="fallen-down"] .text-red-400 { - color: #FF0000; -} - -[data-theme="fallen-down"] .text-yellow-400 { - color: #FFFF00; -} - -/* Primary button - yellow like FIGHT/ACT buttons */ -[data-theme="fallen-down"] .btn-primary { - background-color: transparent; - border: 2px solid #FFFF00; - color: #FFFF00; -} - -[data-theme="fallen-down"] .btn-primary:hover { - background-color: #FFFF00; - color: #000000; -} - -/* Tags and badges - white/yellow only */ -[data-theme="fallen-down"] [class*="bg-indigo"], -[data-theme="fallen-down"] [class*="bg-blue"], -[data-theme="fallen-down"] [class*="bg-purple"] { - background-color: #1a1a1a; - border: 1px solid #FFFF00; - color: #FFFF00; -} - -/* Checkboxes and toggles */ -[data-theme="fallen-down"] input[type="checkbox"]:checked { - background-color: #FFFF00; - border-color: #FFFF00; -} - -/* Range inputs */ -[data-theme="fallen-down"] input[type="range"]::-webkit-slider-thumb { - background-color: #FFFF00; -} - -[data-theme="fallen-down"] input[type="range"]::-moz-range-thumb { - background-color: #FFFF00; -} - -/* Select styling for Light theme */ -[data-theme="light"] select.input { - background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='16' height='16' viewBox='0 0 24 24' fill='none' stroke='%23475569' 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"); -} - -[data-theme="light"] select.input option { - background-color: var(--color-surface-100); - color: var(--color-surface-900); -} - -[data-theme="light"] select.input option:checked { - background-color: var(--color-accent-600); - color: white; -} - -/* ============================================= - LIGHT THEME TAILWIND OVERRIDES - Override Tailwind classes for light theme - ============================================= */ - -/* Background overrides - INVERT for light theme (dark numbers = light colors) */ -[data-theme="light"] .bg-surface-900 { - background-color: var(--color-surface-50); -} - -[data-theme="light"] .bg-surface-850 { - background-color: var(--color-surface-100); -} - -[data-theme="light"] .bg-surface-800 { - background-color: var(--color-surface-100); -} - -[data-theme="light"] .bg-surface-700 { - background-color: var(--color-surface-200); -} - -[data-theme="light"] .bg-surface-600 { - background-color: var(--color-surface-300); -} - -[data-theme="light"] .bg-surface-500 { - background-color: var(--color-surface-400); -} - -[data-theme="light"] .bg-surface-400 { - background-color: var(--color-surface-400); -} - -[data-theme="light"] .bg-surface-300 { - background-color: var(--color-surface-300); -} - -[data-theme="light"] .bg-surface-200 { - background-color: var(--color-surface-200); -} - -[data-theme="light"] .bg-surface-100 { - background-color: var(--color-surface-100); -} - -[data-theme="light"] .bg-surface-50 { - background-color: var(--color-surface-50); -} - -/* Text color overrides - INVERT for light theme (light numbers = dark colors) */ -[data-theme="light"] .text-surface-50 { - color: var(--color-surface-950); -} - -[data-theme="light"] .text-surface-100 { - color: var(--color-surface-900); -} - -[data-theme="light"] .text-surface-200 { - color: var(--color-surface-800); -} - -[data-theme="light"] .text-surface-300 { - color: var(--color-surface-700); -} - -[data-theme="light"] .text-surface-400 { - color: var(--color-surface-500); -} - -[data-theme="light"] .text-surface-500 { - color: var(--color-surface-500); -} - -[data-theme="light"] .text-surface-600 { - color: var(--color-surface-400); -} - -[data-theme="light"] .text-surface-700 { - color: var(--color-surface-300); -} - -[data-theme="light"] .text-surface-800 { - color: var(--color-surface-200); -} - -[data-theme="light"] .text-surface-900 { - color: var(--color-surface-100); -} - -/* Border color overrides */ -[data-theme="light"] .border-surface-700 { - border-color: var(--color-surface-300); -} - -[data-theme="light"] .border-surface-600 { - border-color: var(--color-surface-400); -} - -[data-theme="light"] .border-surface-500 { - border-color: var(--color-surface-400); -} - -/* Accent color overrides */ -[data-theme="light"] .bg-accent-600 { - background-color: var(--color-accent-600); -} - -[data-theme="light"] .bg-accent-700 { - background-color: var(--color-accent-700); -} - -[data-theme="light"] .text-accent-400 { - color: var(--color-accent-400); -} - -[data-theme="light"] .text-accent-500 { - color: var(--color-accent-500); -} - -[data-theme="light"] .text-accent-600 { - color: var(--color-accent-600); -} - -[data-theme="light"] .border-accent-500 { - border-color: var(--color-accent-500); -} - -[data-theme="light"] .ring-accent-500 { - --tw-ring-color: var(--color-accent-500); -} - -[data-theme="light"] .focus\:ring-accent-500:focus { - --tw-ring-color: var(--color-accent-500); -} - -/* Hover state overrides - backgrounds get lighter, text gets darker */ -[data-theme="light"] .hover\:bg-surface-600:hover { - background-color: var(--color-surface-300); -} - -[data-theme="light"] .hover\:bg-surface-700:hover { - background-color: var(--color-surface-200); -} - -[data-theme="light"] .hover\:bg-surface-800:hover { - background-color: var(--color-surface-200); -} - -[data-theme="light"] .hover\:bg-accent-700:hover { - background-color: var(--color-accent-400); -} - -[data-theme="light"] .hover\:text-surface-100:hover { - color: var(--color-surface-950); -} - -[data-theme="light"] .hover\:text-surface-200:hover { - color: var(--color-surface-900); -} - -[data-theme="light"] .hover\:text-surface-300:hover { - color: var(--color-surface-800); -} - -[data-theme="light"] .hover\:text-accent-400:hover { - color: var(--color-accent-700); -} - -/* Nav tab active state */ -[data-theme="light"] .nav-tab-active { - background-color: var(--color-surface-300); -} - -/* Light theme status colors (high contrast on paper) */ -[data-theme="light"] .text-green-400 { - color: #15803d; -} - -[data-theme="light"] .text-amber-400 { - color: #b45309; -} - -[data-theme="light"] .text-red-400 { - color: #dc2626; -} - -[data-theme="light"] .text-blue-400 { - color: #1d4ed8; -} - -[data-theme="light"] .text-purple-400 { - color: #7c3aed; -} - -[data-theme="light"] .text-yellow-400 { - color: #a16207; -} - -[data-theme="light"] .text-pink-400 { - color: #be185d; -} - -/* Light theme component overrides */ -[data-theme="light"] .sidebar { - background-color: var(--color-surface-100) !important; -} - -[data-theme="light"] .panel { - background-color: var(--color-surface-100); - border-right-color: var(--color-surface-300); -} - -[data-theme="light"] .card { - background-color: var(--color-surface-100); - border-color: var(--color-surface-300); -} - -[data-theme="light"] .btn-secondary { - background-color: var(--color-surface-200); - color: var(--color-surface-900); -} - -[data-theme="light"] .btn-secondary:hover { - background-color: var(--color-surface-300); -} - -[data-theme="light"] .btn-ghost { - color: var(--color-surface-700); -} - -[data-theme="light"] .btn-ghost:hover { - background-color: var(--color-surface-200); - color: var(--color-surface-900); -} - -[data-theme="light"] .input { - background-color: var(--color-surface-50); - border-color: var(--color-surface-300); - color: var(--color-surface-900); -} - -[data-theme="light"] .input::placeholder { - color: var(--color-surface-500); -} - -[data-theme="light"] .input:focus { - border-color: var(--color-accent-500); -} - -/* Light theme checkbox */ -[data-theme="light"] input[type="checkbox"] { - background-color: var(--color-surface-50); - border-color: var(--color-surface-400); -} - -[data-theme="light"] input[type="checkbox"]:checked { - background-color: var(--color-accent-600); - border-color: var(--color-accent-600); -} - -/* Light theme modal overrides */ -[data-theme="light"] .modal-backdrop { - background: rgba(0, 0, 0, 0.4) !important; -} - -[data-theme="light"] .modal { - background: var(--color-surface-50) !important; - border-color: var(--color-surface-300) !important; - box-shadow: 0 8px 32px rgba(0, 0, 0, 0.15), 0 0 0 1px var(--color-surface-300) !important; -} - -/* Light theme prose/markdown overrides */ -[data-theme="light"] .prose-content code { - background-color: var(--color-surface-200); - color: var(--color-accent-700); -} - -[data-theme="light"] .prose-content pre { - background-color: var(--color-surface-200); - border: 1px solid var(--color-surface-300); -} - -[data-theme="light"] .prose-content blockquote { - border-color: var(--color-surface-400); - color: var(--color-surface-600); -} - -/* Light theme dropdown overrides (ModelSelector, etc) */ -[data-theme="light"] .model-dropdown { - background: var(--color-surface-50) !important; - border-color: var(--color-surface-300) !important; - box-shadow: 0 4px 12px rgba(0, 0, 0, 0.15) !important; -} - -[data-theme="light"] .dropdown-item:hover, -[data-theme="light"] .dropdown-item:active { - background: var(--color-surface-200) !important; -} - -/* Light theme provider/profile card overrides */ -[data-theme="light"] .provider-card.selected, -[data-theme="light"] .profile-card.active { - background: rgba(166, 107, 31, 0.08) !important; - border-color: var(--color-accent-500) !important; -} - -/* Light theme story entry backgrounds (opacity variants) */ -[data-theme="light"] .bg-surface-800\/50 { - background-color: rgba(222, 218, 211, 0.5) !important; - /* warm paper with opacity */ -} - -[data-theme="light"] .bg-surface-800\/30 { - background-color: rgba(222, 218, 211, 0.3) !important; -} - -[data-theme="light"] .bg-surface-900\/50 { - background-color: rgba(236, 234, 229, 0.5) !important; -} - -[data-theme="light"] .bg-accent-500\/5 { - background-color: rgba(166, 107, 31, 0.08) !important; -} - -[data-theme="light"] .bg-accent-500\/20 { - background-color: rgba(166, 107, 31, 0.15) !important; -} - -/* Light theme error/warning backgrounds */ -[data-theme="light"] .bg-red-500\/20 { - background-color: rgba(220, 38, 38, 0.12) !important; -} - -[data-theme="light"] .bg-red-500\/30 { - background-color: rgba(220, 38, 38, 0.18) !important; -} - -[data-theme="light"] .bg-amber-500\/5 { - background-color: rgba(180, 83, 9, 0.08) !important; -} - -[data-theme="light"] .bg-primary-500\/20 { - background-color: rgba(166, 107, 31, 0.15) !important; -} - -/* Light theme border colors for story entries */ -[data-theme="light"] .border-l-surface-600 { - border-left-color: var(--color-surface-400) !important; -} - -[data-theme="light"] .border-l-surface-500 { - border-left-color: var(--color-surface-400) !important; -} - -[data-theme="light"] .border-l-accent-500 { - border-left-color: var(--color-accent-500) !important; -} - -/* Light theme touch device nav tab */ -@media (hover: none) and (pointer: coarse) { - [data-theme="light"] .nav-tab::before { - background-color: var(--color-surface-200); - } - - [data-theme="light"] .nav-tab.nav-tab-active::before { - background-color: var(--color-surface-300); - } -} - -/* ============================================= - LIGHT-SOLARIZED THEME TAILWIND OVERRIDES - Same inversions as Paper theme but for Solarized - ============================================= */ - -/* Background overrides - INVERT for light theme */ -[data-theme="light-solarized"] .bg-surface-900 { - background-color: var(--color-surface-50); -} - -[data-theme="light-solarized"] .bg-surface-850 { - background-color: var(--color-surface-100); -} - -[data-theme="light-solarized"] .bg-surface-800 { - background-color: var(--color-surface-100); -} - -[data-theme="light-solarized"] .bg-surface-700 { - background-color: var(--color-surface-200); -} - -[data-theme="light-solarized"] .bg-surface-600 { - background-color: var(--color-surface-300); -} - -[data-theme="light-solarized"] .bg-surface-500 { - background-color: var(--color-surface-400); -} - -[data-theme="light-solarized"] .bg-surface-400 { - background-color: var(--color-surface-400); -} - -[data-theme="light-solarized"] .bg-surface-300 { - background-color: var(--color-surface-300); -} - -[data-theme="light-solarized"] .bg-surface-200 { - background-color: var(--color-surface-200); -} - -[data-theme="light-solarized"] .bg-surface-100 { - background-color: var(--color-surface-100); -} - -[data-theme="light-solarized"] .bg-surface-50 { - background-color: var(--color-surface-50); -} - -/* Text color overrides - INVERT for light theme */ -[data-theme="light-solarized"] .text-surface-50 { - color: var(--color-surface-950); -} - -[data-theme="light-solarized"] .text-surface-100 { - color: var(--color-surface-900); -} - -[data-theme="light-solarized"] .text-surface-200 { - color: var(--color-surface-800); -} - -[data-theme="light-solarized"] .text-surface-300 { - color: var(--color-surface-700); -} - -[data-theme="light-solarized"] .text-surface-400 { - color: var(--color-surface-500); -} - -[data-theme="light-solarized"] .text-surface-500 { - color: var(--color-surface-500); -} - -[data-theme="light-solarized"] .text-surface-600 { - color: var(--color-surface-400); -} - -[data-theme="light-solarized"] .text-surface-700 { - color: var(--color-surface-300); -} - -[data-theme="light-solarized"] .text-surface-800 { - color: var(--color-surface-200); -} - -[data-theme="light-solarized"] .text-surface-900 { - color: var(--color-surface-100); -} - -/* Border color overrides */ -[data-theme="light-solarized"] .border-surface-700 { - border-color: var(--color-surface-300); -} - -[data-theme="light-solarized"] .border-surface-600 { - border-color: var(--color-surface-400); -} - -[data-theme="light-solarized"] .border-surface-500 { - border-color: var(--color-surface-400); -} - -/* Accent color overrides */ -[data-theme="light-solarized"] .bg-accent-600 { - background-color: var(--color-accent-600); -} - -[data-theme="light-solarized"] .bg-accent-700 { - background-color: var(--color-accent-700); -} - -[data-theme="light-solarized"] .text-accent-400 { - color: var(--color-accent-400); -} - -[data-theme="light-solarized"] .text-accent-500 { - color: var(--color-accent-500); -} - -[data-theme="light-solarized"] .text-accent-600 { - color: var(--color-accent-600); -} - -[data-theme="light-solarized"] .border-accent-500 { - border-color: var(--color-accent-500); -} - -[data-theme="light-solarized"] .ring-accent-500 { - --tw-ring-color: var(--color-accent-500); -} - -[data-theme="light-solarized"] .focus\:ring-accent-500:focus { - --tw-ring-color: var(--color-accent-500); -} - -/* Hover state overrides */ -[data-theme="light-solarized"] .hover\:bg-surface-600:hover { - background-color: var(--color-surface-300); -} - -[data-theme="light-solarized"] .hover\:bg-surface-700:hover { - background-color: var(--color-surface-200); -} - -[data-theme="light-solarized"] .hover\:bg-surface-800:hover { - background-color: var(--color-surface-200); -} - -[data-theme="light-solarized"] .hover\:bg-accent-700:hover { - background-color: var(--color-accent-400); -} - -[data-theme="light-solarized"] .hover\:text-surface-100:hover { - color: var(--color-surface-950); -} - -[data-theme="light-solarized"] .hover\:text-surface-200:hover { - color: var(--color-surface-900); -} - -[data-theme="light-solarized"] .hover\:text-surface-300:hover { - color: var(--color-surface-800); -} - -[data-theme="light-solarized"] .hover\:text-accent-400:hover { - color: var(--color-accent-700); -} - -/* Nav tab active state */ -[data-theme="light-solarized"] .nav-tab-active { - background-color: var(--color-surface-300); -} - -/* Solarized status colors */ -[data-theme="light-solarized"] .text-green-400 { - color: #859900; -} - -/* Solarized green */ -[data-theme="light-solarized"] .text-amber-400 { - color: #b58900; -} - -/* Solarized yellow */ -[data-theme="light-solarized"] .text-red-400 { - color: #dc322f; -} - -/* Solarized red */ -[data-theme="light-solarized"] .text-blue-400 { - color: #268bd2; -} - -/* Solarized blue */ -[data-theme="light-solarized"] .text-purple-400 { - color: #6c71c4; -} - -/* Solarized violet */ -[data-theme="light-solarized"] .text-yellow-400 { - color: #b58900; -} - -/* Solarized yellow */ -[data-theme="light-solarized"] .text-pink-400 { - color: #d33682; -} - -/* Solarized magenta */ - -/* Solarized component overrides */ -[data-theme="light-solarized"] .sidebar { - background-color: var(--color-surface-100) !important; -} - -[data-theme="light-solarized"] .panel { - background-color: var(--color-surface-100); - border-right-color: var(--color-surface-300); -} - -[data-theme="light-solarized"] .card { - background-color: var(--color-surface-100); - border-color: var(--color-surface-300); -} - -[data-theme="light-solarized"] .btn-secondary { - background-color: var(--color-surface-200); - color: var(--color-surface-900); -} - -[data-theme="light-solarized"] .btn-secondary:hover { - background-color: var(--color-surface-300); -} - -[data-theme="light-solarized"] .btn-ghost { - color: var(--color-surface-700); -} - -[data-theme="light-solarized"] .btn-ghost:hover { - background-color: var(--color-surface-200); - color: var(--color-surface-900); -} - -[data-theme="light-solarized"] .input { - background-color: var(--color-surface-50); - border-color: var(--color-surface-300); - color: var(--color-surface-900); -} - -[data-theme="light-solarized"] .input::placeholder { - color: var(--color-surface-500); -} - -[data-theme="light-solarized"] .input:focus { - border-color: var(--color-accent-500); -} - -/* Solarized checkbox */ -[data-theme="light-solarized"] input[type="checkbox"] { - background-color: var(--color-surface-50); - border-color: var(--color-surface-400); -} - -[data-theme="light-solarized"] input[type="checkbox"]:checked { - background-color: var(--color-accent-500); - border-color: var(--color-accent-500); -} - -/* Solarized modal overrides */ -[data-theme="light-solarized"] .modal-backdrop { - background: rgba(0, 0, 0, 0.4) !important; -} - -[data-theme="light-solarized"] .modal { - background: var(--color-surface-50) !important; - border-color: var(--color-surface-300) !important; - box-shadow: 0 8px 32px rgba(0, 0, 0, 0.15), 0 0 0 1px var(--color-surface-300) !important; -} - -/* Solarized prose/markdown overrides */ -[data-theme="light-solarized"] .prose-content code { - background-color: var(--color-surface-200); - color: var(--color-accent-600); -} - -[data-theme="light-solarized"] .prose-content pre { - background-color: var(--color-surface-200); - border: 1px solid var(--color-surface-300); -} - -[data-theme="light-solarized"] .prose-content blockquote { - border-color: var(--color-surface-400); - color: var(--color-surface-600); -} - -/* Solarized dropdown overrides */ -[data-theme="light-solarized"] .model-dropdown { - background: var(--color-surface-50) !important; - border-color: var(--color-surface-300) !important; - box-shadow: 0 4px 12px rgba(0, 0, 0, 0.15) !important; -} - -[data-theme="light-solarized"] .dropdown-item:hover, -[data-theme="light-solarized"] .dropdown-item:active { - background: var(--color-surface-200) !important; -} - -/* Solarized provider/profile card overrides */ -[data-theme="light-solarized"] .provider-card.selected, -[data-theme="light-solarized"] .profile-card.active { - background: rgba(42, 161, 152, 0.1) !important; - border-color: var(--color-accent-500) !important; -} - -/* Solarized story entry backgrounds */ -[data-theme="light-solarized"] .bg-surface-800\/50 { - background-color: rgba(238, 232, 213, 0.5) !important; -} - -[data-theme="light-solarized"] .bg-surface-800\/30 { - background-color: rgba(238, 232, 213, 0.3) !important; -} - -[data-theme="light-solarized"] .bg-surface-900\/50 { - background-color: rgba(253, 246, 227, 0.5) !important; -} - -[data-theme="light-solarized"] .bg-accent-500\/5 { - background-color: rgba(42, 161, 152, 0.08) !important; -} - -[data-theme="light-solarized"] .bg-accent-500\/20 { - background-color: rgba(42, 161, 152, 0.15) !important; -} - -/* Solarized error/warning backgrounds */ -[data-theme="light-solarized"] .bg-red-500\/20 { - background-color: rgba(220, 50, 47, 0.12) !important; -} - -[data-theme="light-solarized"] .bg-red-500\/30 { - background-color: rgba(220, 50, 47, 0.18) !important; -} - -[data-theme="light-solarized"] .bg-amber-500\/5 { - background-color: rgba(181, 137, 0, 0.08) !important; -} - -[data-theme="light-solarized"] .bg-primary-500\/20 { - background-color: rgba(42, 161, 152, 0.15) !important; -} - -/* Solarized border colors for story entries */ -[data-theme="light-solarized"] .border-l-surface-600 { - border-left-color: var(--color-surface-400) !important; -} - -[data-theme="light-solarized"] .border-l-surface-500 { - border-left-color: var(--color-surface-400) !important; -} - -[data-theme="light-solarized"] .border-l-accent-500 { - border-left-color: var(--color-accent-500) !important; -} - -/* Solarized select styling */ -[data-theme="light-solarized"] select.input { - background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='16' height='16' viewBox='0 0 24 24' fill='none' stroke='%235c5850' 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"); -} - -[data-theme="light-solarized"] select.input option { - background-color: var(--color-surface-100); - color: var(--color-surface-900); -} - -[data-theme="light-solarized"] select.input option:checked { - background-color: var(--color-accent-500); - color: white; -} - -/* Solarized touch device nav tab */ -@media (hover: none) and (pointer: coarse) { - [data-theme="light-solarized"] .nav-tab::before { - background-color: var(--color-surface-200); - } - - [data-theme="light-solarized"] .nav-tab.nav-tab-active::before { - background-color: var(--color-surface-300); - } -} - -/* Checkbox styling for Retro theme */ -[data-theme="retro-console"] input[type="checkbox"] { - border: 2px solid var(--color-retro-green-muted); - background: rgba(5, 8, 8, 0.9); -} - -[data-theme="retro-console"] input[type="checkbox"]:checked { - background-color: var(--color-retro-green-muted); - border-color: var(--color-retro-green); - background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='16' height='16' viewBox='0 0 24 24' fill='none' stroke='%2339ff14' stroke-width='3' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpolyline points='20 6 9 17 4 12'%3E%3C/polyline%3E%3C/svg%3E"); - box-shadow: var(--retro-border-glow); -} - -[data-theme="retro-console"] input[type="checkbox"]:focus { - --tw-ring-color: var(--color-retro-green); -} - -/* ============================================= - MOBILE & TOUCH FRIENDLY STYLES - ============================================= */ - -/* Hide all scrollbars on mobile devices */ -@media (max-width: 640px) { - * { - scrollbar-width: none; - -ms-overflow-style: none; - } - - *::-webkit-scrollbar { - display: none; - } -} - -/* Scrollbar hide utility */ -.scrollbar-hide { - scrollbar-width: none; - -ms-overflow-style: none; -} - -.scrollbar-hide::-webkit-scrollbar { - display: none; -} - -/* Extra slim scrollbar for tabs and compact UI elements */ -.scrollbar-slim { - scrollbar-width: thin; -} - -.scrollbar-slim::-webkit-scrollbar { - height: 4px; - width: 4px; -} - -.scrollbar-slim::-webkit-scrollbar-track { - background: transparent; -} - -.scrollbar-slim::-webkit-scrollbar-thumb { - background-color: var(--scrollbar-thumb); - border-radius: 2px; -} - -.scrollbar-slim::-webkit-scrollbar-thumb:hover { - background-color: var(--scrollbar-thumb-hover); -} - -/* Safe area padding utilities */ -.pt-safe { - padding-top: env(safe-area-inset-top, 0); -} - -.pb-safe { - padding-bottom: env(safe-area-inset-bottom, 0); -} - -/* Safe area positioning for fixed elements (adjusts position, not padding) */ -.bottom-safe-4 { - bottom: calc(1rem + env(safe-area-inset-bottom, 0)); -} - -.bottom-safe-20 { - bottom: calc(5rem + env(safe-area-inset-bottom, 0)); -} - -.left-safe-4 { - left: calc(1rem + env(safe-area-inset-left, 0)); -} - -.right-safe-4 { - right: calc(1rem + env(safe-area-inset-right, 0)); -} - -/* Bottom sheet modal footers - adds safe area inset on mobile only */ -.pb-modal-safe { - padding-bottom: calc(1rem + env(safe-area-inset-bottom, 0px)); -} - -@media (min-width: 640px) { - .pb-modal-safe { - padding-bottom: 1rem; - } -} - -/* Edge-to-edge support for Android */ -html, -body { - /* Ensure the app fills the full viewport including system bars */ - min-height: 100vh; - min-height: 100dvh; - /* Dynamic viewport height for mobile */ -} - -/* Touch-friendly tap targets (minimum 44px per Apple/Google guidelines) */ -@media (max-width: 768px) { - - /* Larger buttons on mobile */ - .btn { - @apply min-h-[44px]; - } - - /* Larger icon buttons */ - .btn-ghost { - @apply min-h-[44px] min-w-[44px]; - } - - /* Larger input areas */ - .input { - @apply min-h-[44px] text-base; - /* Prevent zoom on focus on iOS */ - font-size: 16px !important; - } - - textarea.input { - @apply min-h-[70px]; - } - - /* Story entries - more compact on mobile */ - .story-text { - @apply text-base leading-relaxed; - } - - /* Prevent text selection on interactive elements */ - button, - .btn, - a { - -webkit-tap-highlight-color: transparent; - -webkit-touch-callout: none; - user-select: none; - } - - /* Smooth scrolling for touch */ - .scroll-container { - -webkit-overflow-scrolling: touch; - scroll-behavior: smooth; - } - - /* Full-width story view on mobile */ - .max-w-3xl { - @apply max-w-full; - } -} - -/* Extra small screens (phones in portrait) */ -@media (max-width: 475px) { - - /* Slightly smaller text for very small screens */ - .story-text { - @apply text-[15px]; - } -} - -/* Safe area insets for notched devices */ -@supports (padding-bottom: env(safe-area-inset-bottom)) { - .pb-safe { - padding-bottom: max(0.75rem, env(safe-area-inset-bottom)); - } -} - -/* Touch feedback */ -@media (hover: none) and (pointer: coarse) { - - /* Add touch ripple effect */ - .btn:active, - button:active { - transform: scale(0.98); - opacity: 0.9; - } - - /* Faster transitions for touch */ - .btn, - button { - transition-duration: 100ms; - } - - /* Remove hover states on touch devices (they cause sticky hover) */ - .btn-ghost:hover { - background-color: transparent; - } - - .btn-ghost:active { - background-color: var(--bg-secondary); - } - - .nav-tab { - position: relative; - overflow: hidden; - -webkit-tap-highlight-color: transparent; - } - - .nav-tab::before { - content: ""; - position: absolute; - inset: 4px; - border-radius: calc(0.5rem - 2px); - background-color: var(--bg-secondary); - opacity: 0; - transition: opacity 100ms ease; - pointer-events: none; - } - - .nav-tab>* { - position: relative; - z-index: 1; - } - - .nav-tab.nav-tab-active { - background-color: transparent; - } - - .nav-tab.nav-tab-active::before { - background-color: var(--color-surface-700); - opacity: 1; - } - - .nav-tab:active { - background-color: transparent; - } - - .nav-tab:active::before { - opacity: 1; - } -} - -/* Landscape mode adjustments */ -@media (max-height: 500px) and (orientation: landscape) { - - /* Reduce header height */ - header { - @apply h-10; - } - - /* Smaller text */ - .story-text { - @apply text-sm; - } -} - -/* Prevent zoom on input focus (iOS) */ -@media screen and (-webkit-min-device-pixel-ratio: 0) { - - input, - textarea, - select { - font-size: 16px !important; - } -} - -/* Disable pull-to-refresh on Android when in app */ -body { - overscroll-behavior-y: contain; -} - -/* ============================================= - VISUAL PROSE MODE STYLES - Rich HTML/CSS output from AI for enhanced narrative presentation - ============================================= */ - -/* Container for Visual Prose entries - prevents style leakage */ -.visual-prose-container { - overflow: hidden; - contain: layout style; - isolation: isolate; -} - -/* Base styles for Visual Prose entry content */ -.visual-prose-entry { - line-height: 1.6; -} - -/* Ensure all Visual Prose elements stay within bounds */ -.visual-prose-entry * { - max-width: 100%; - box-sizing: border-box; -} - -/* Reset prose-content styles for Visual Prose - AI controls spacing */ -.prose-content.visual-prose-container .visual-prose-entry p, -.visual-prose-container .visual-prose-entry p { - margin-top: 0; - margin-bottom: 0.75em; - /* Tighter paragraph spacing */ -} - -.prose-content.visual-prose-container .visual-prose-entry p:last-child, -.visual-prose-container .visual-prose-entry p:last-child { - margin-bottom: 0; -} - -/* Reset div margins - AI should use padding/margin in styles if needed */ -.prose-content.visual-prose-container .visual-prose-entry>div, -.visual-prose-container .visual-prose-entry>div { - margin-top: 0.75em; - margin-bottom: 0.75em; -} - -.prose-content.visual-prose-container .visual-prose-entry>div:first-child, -.visual-prose-container .visual-prose-entry>div:first-child { - margin-top: 0; -} - -.prose-content.visual-prose-container .visual-prose-entry>div:last-child, -.visual-prose-container .visual-prose-entry>div:last-child { - margin-bottom: 0; -} - -/* Reset heading margins */ -:is(.prose-content.visual-prose-container, .visual-prose-container) .visual-prose-entry :is(h1, h2, h3, h4, h5, h6) { - margin-top: 0; - margin-bottom: 0; - color: inherit; -} - -/* Streaming indicator for Visual Prose */ -.visual-prose-streaming { - position: relative; -} - -.visual-prose-streaming::after { - content: ''; - display: inline-block; - width: 8px; - height: 16px; - background-color: var(--color-accent-400); - margin-left: 2px; - animation: visual-prose-cursor 1s step-end infinite; -} - -@keyframes visual-prose-cursor { - - 0%, - 50% { - opacity: 1; - } - - 51%, - 100% { - opacity: 0; - } -} - -/* ========================================== - INLINE IMAGE GENERATION STYLES - ========================================== */ - -/* Inline image placeholder (loading/pending state) */ -.inline-image-placeholder { - display: flex; - flex-direction: column; - align-items: center; - justify-content: center; - gap: 1rem; - padding: 3rem 2rem; - background: linear-gradient(135deg, var(--color-surface-800) 0%, var(--color-surface-900) 100%); - border: 2px solid var(--color-surface-600); - border-radius: 0.75rem; - min-height: 250px; - width: 100%; - text-align: center; -} - -.inline-image-placeholder.pending { - border-color: var(--color-accent-500); -} - -.inline-image-placeholder.generating { - border-color: var(--color-amber-500); -} - -.inline-image-placeholder.failed { - border-color: var(--color-red-500); - background: linear-gradient(135deg, rgba(239, 68, 68, 0.1) 0%, var(--color-surface-900) 100%); -} - -/* Placeholder spinner */ -.inline-image-placeholder .placeholder-spinner { - width: 3rem; - height: 3rem; - border: 3px solid var(--color-surface-600); - border-top-color: var(--color-accent-500); - border-radius: 50%; - animation: inline-spin 1s linear infinite; -} - -.inline-image-placeholder.pending .placeholder-spinner { - border-top-color: var(--color-accent-500); -} - -.inline-image-placeholder.generating .placeholder-spinner { - border-top-color: var(--color-amber-500); -} - -@keyframes inline-spin { to { - transform: rotate(360deg); + height: var(--bits-collapsible-content-height); } } -/* Placeholder icon (for failed state) */ -.inline-image-placeholder .placeholder-icon { - font-size: 2.5rem; - line-height: 1; -} - -/* Placeholder text (prompt preview) */ -.inline-image-placeholder .placeholder-text { - font-size: 0.875rem; - max-width: 80%; - overflow: hidden; - text-overflow: ellipsis; - white-space: nowrap; - color: var(--color-surface-400); -} - -/* Placeholder status */ -.inline-image-placeholder .placeholder-status { - font-size: 0.875rem; - font-weight: 600; - color: var(--color-surface-300); - text-transform: uppercase; - letter-spacing: 0.05em; -} - -.inline-image-placeholder.pending .placeholder-status { - color: var(--color-accent-400); -} - -.inline-image-placeholder.generating .placeholder-status { - color: var(--color-amber-400); - animation: status-pulse 1.5s ease-in-out infinite; -} - -.inline-image-placeholder.failed .placeholder-status { - color: var(--color-red-400); -} - -@keyframes status-pulse { - - 0%, - 100% { - opacity: 0.6; +@keyframes collapsible-up { + from { + height: var(--bits-collapsible-content-height); } - - 50% { - opacity: 1; + to { + height: 0; } } - -/* Generated inline image container */ -.inline-generated-image { - position: relative; - border-radius: 0.75rem; - overflow: visible; - width: 100%; - border: 2px solid var(--color-surface-600); - background: var(--color-surface-900); - line-height: 0; - font-size: 0; -} - -.inline-generated-image img { - width: 100%; - display: block; - vertical-align: bottom; - margin: 0; - border-radius: 0.75rem; -} - -/* In Visual Prose mode, center inline images */ -.visual-prose-entry .inline-generated-image { - margin-left: auto; - margin-right: auto; -} - -.visual-prose-entry .inline-image-placeholder { - margin-left: auto; - margin-right: auto; -} - -/* Inline image action buttons - overlay on bottom right */ -.inline-image-actions { - position: absolute; - bottom: 0.75rem; - right: 0.75rem; - display: flex; - gap: 0.5rem; - opacity: 0; - visibility: hidden; - transition: opacity 0.2s ease, visibility 0.2s ease; - font-size: 1rem; - line-height: normal; - z-index: 10; -} - -.inline-generated-image:hover .inline-image-actions, -.prose-content .inline-generated-image:hover .inline-image-actions { - opacity: 1; - visibility: visible; -} - -/* Action button base styles */ -.inline-image-btn { - display: inline-flex; - align-items: center; - gap: 0.375rem; - padding: 0.5rem 0.75rem; - font-size: 0.8125rem; - font-weight: 500; - border: none; - border-radius: 0.5rem; - cursor: pointer; - transition: all 0.15s ease; - background: rgba(0, 0, 0, 0.7); - backdrop-filter: blur(8px); - color: var(--color-surface-100); - box-shadow: 0 2px 8px rgba(0, 0, 0, 0.3); -} - -.inline-image-btn:hover { - background: rgba(0, 0, 0, 0.85); - color: white; -} - -.inline-image-btn svg { - flex-shrink: 0; -} - -/* Edit button */ -.inline-image-btn.edit-btn:hover { - background: var(--color-blue-600); - color: white; -} - -/* Regenerate button */ -.inline-image-btn.regenerate-btn:hover { - background: var(--color-accent-600); - color: white; -} - -/* Retry button (in failed state) */ -.inline-image-btn.retry-btn { - margin-top: 0.75rem; - background: var(--color-surface-700); -} - -.inline-image-btn.retry-btn:hover { - background: var(--color-amber-600); - color: white; -} - -/* Hide actions by default, show on hover */ -.inline-generated-image .inline-image-actions { - opacity: 0; - transition: opacity 0.2s ease; -} - -.inline-generated-image:hover .inline-image-actions { - opacity: 1; -} - -/* Prompt edit modal overlay */ -.inline-image-edit-overlay { - position: fixed; - inset: 0; - background: rgba(0, 0, 0, 0.7); - display: flex; - align-items: center; - justify-content: center; - z-index: 1000; - padding: 1rem; -} - -.inline-image-edit-modal { - background: var(--color-surface-800); - border-radius: 0.75rem; - padding: 1.5rem; - max-width: 600px; - width: 100%; - box-shadow: 0 25px 50px -12px rgba(0, 0, 0, 0.5); -} - -.inline-image-edit-modal h3 { - margin: 0 0 1rem; - font-size: 1.125rem; - font-weight: 600; - color: var(--color-surface-100); -} - -.inline-image-edit-modal textarea { - width: 100%; - min-height: 120px; - padding: 0.75rem; - border: 1px solid var(--color-surface-600); - border-radius: 0.5rem; - background: var(--color-surface-900); - color: var(--color-surface-100); - font-size: 0.875rem; - resize: vertical; -} - -.inline-image-edit-modal textarea:focus { - outline: none; - border-color: var(--color-accent-500); -} - -.inline-image-edit-actions { - display: flex; - gap: 0.5rem; - justify-content: flex-end; - margin-top: 1rem; -} - -.inline-image-edit-actions button { - padding: 0.5rem 1rem; - font-size: 0.875rem; - font-weight: 500; - border: none; - border-radius: 0.5rem; - cursor: pointer; - transition: all 0.15s ease; -} - -.inline-image-edit-actions .cancel-btn { - background: var(--color-surface-700); - color: var(--color-surface-200); -} - -.inline-image-edit-actions .cancel-btn:hover { - background: var(--color-surface-600); -} - -.inline-image-edit-actions .generate-btn { - background: var(--color-accent-600); - color: white; -} - -.inline-image-edit-actions .generate-btn:hover { - background: var(--color-accent-500); -} \ No newline at end of file diff --git a/src/lib/components/discovery/DiscoveryCard.svelte b/src/lib/components/discovery/DiscoveryCard.svelte index 918d2d9..fa59eb3 100644 --- a/src/lib/components/discovery/DiscoveryCard.svelte +++ b/src/lib/components/discovery/DiscoveryCard.svelte @@ -1,17 +1,21 @@ {#if !isHidden} -
- {#if !imageError && card.avatarUrl} + {#if !imageError && (card.imageUrl || card.avatarUrl)} {card.name} {:else} -
+
?
{/if} @@ -57,52 +66,63 @@ {#if card.nsfw} -
+ NSFW -
+ {/if} -
+ {card.source} -
+ {#if isImported} -
-
- - Imported -
+
+ + + Imported +
{/if} {#if !isImported} -
- + + +
{/if}
-
-

+ +

{card.name}

{#if card.creator} -

+

by {card.creator}

{/if} {#if card.description} -

+

{card.description}

{/if} @@ -111,17 +131,17 @@ {#if card.tags.length > 0}
{#each card.tags.slice(0, 3) as tag} - + {tag} - + {/each} {#if card.tags.length > 3} - + +{card.tags.length - 3} - + {/if}
{/if} -

-
+ + {/if} diff --git a/src/lib/components/discovery/DiscoveryCardDetails.svelte b/src/lib/components/discovery/DiscoveryCardDetails.svelte new file mode 100644 index 0000000..db8e0de --- /dev/null +++ b/src/lib/components/discovery/DiscoveryCardDetails.svelte @@ -0,0 +1,304 @@ + + +
+ +
+ +

+ {card.name} +

+ {#if isImported} + + {/if} +
+ + +
+
+ +
+
+
+ {#if !imageError && (card.imageUrl || card.avatarUrl)} + {card.name} + {:else} +
+ ? +
+ {/if} +
+ + {#if card.nsfw} + + NSFW + + {/if} + + + {card.source} + +
+ + +
+ +
+
+ + +
+ +
+
+

{card.name}

+
+ {#if card.creator} + By {card.creator} + {/if} + {#if card.stats} +
+ {#if card.stats.downloads} + + + {card.stats.downloads} + + {/if} + {#if card.stats.views} + + + {card.stats.views} + + {/if} +
+ {/if} +
+
+ + + {#if card.tags.length > 0} +
+ {#each card.tags as tag} + + {tag} + + {/each} +
+ {/if} +
+ + +
+

+ Description +

+
+ {card.description || "No description provided."} +
+
+ + +
+ + + {#if isRawDataOpen} +
+ + + Import Context Warning + + This is the raw data associated with the card. During import, + some fields might be remapped or formatted to fit the local + schema. This data serves as the source of truth for the import + process. + + + +
+ {#if isLoadingDetails} +
+ + Fetching full details... +
+ {:else} +
{JSON.stringify(
+                      detailedCard,
+                      null,
+                      2,
+                    )}
+ {/if} +
+
+ {/if} +
+
+
+
+ + + +
diff --git a/src/lib/components/discovery/DiscoveryModal.svelte b/src/lib/components/discovery/DiscoveryModal.svelte index 462a67e..311cc4c 100644 --- a/src/lib/components/discovery/DiscoveryModal.svelte +++ b/src/lib/components/discovery/DiscoveryModal.svelte @@ -3,13 +3,13 @@ X, Search, Loader2, - ChevronDown, - Tag, Filter, Check, EyeOff, Eye, Blend, + Globe, + Tag, } from "lucide-svelte"; import { discoveryService, @@ -17,10 +17,21 @@ type SearchResult, } from "$lib/services/discovery"; import DiscoveryCardComponent from "./DiscoveryCard.svelte"; + import DiscoveryCardDetails from "./DiscoveryCardDetails.svelte"; import { characterVault } from "$lib/stores/characterVault.svelte"; import { lorebookVault } from "$lib/stores/lorebookVault.svelte"; import { scenarioVault } from "$lib/stores/scenarioVault.svelte"; + import * as ResponsiveModal from "$lib/components/ui/responsive-modal"; + import { Button } from "$lib/components/ui/button"; + import { Input } from "$lib/components/ui/input"; + import { Badge } from "$lib/components/ui/badge"; + import * as Select from "$lib/components/ui/select"; + import * as ToggleGroup from "$lib/components/ui/toggle-group"; + import * as Popover from "$lib/components/ui/popover"; + import * as Command from "$lib/components/ui/command"; + import { cn } from "$lib/utils/cn"; + interface Props { isOpen: boolean; mode: "character" | "lorebook" | "scenario"; @@ -29,11 +40,9 @@ let { isOpen, mode, onClose }: Props = $props(); - // NSFW mode type type NsfwMode = "disable" | "blur" | "enable"; const NSFW_MODE_STORAGE_KEY = "aventura:discovery:nsfwMode"; - // Load persisted NSFW mode function loadNsfwMode(): NsfwMode { if (typeof localStorage !== "undefined") { const stored = localStorage.getItem(NSFW_MODE_STORAGE_KEY); @@ -44,9 +53,8 @@ return "disable"; } - // State let searchQuery = $state(""); - let activeProviderId = $state("all"); // 'all' for Search All, or provider id + let activeProviderId = $state("all"); let results = $state([]); let isLoading = $state(false); let hasMore = $state(false); @@ -54,8 +62,8 @@ let errorMessage = $state(null); let nsfwMode = $state(loadNsfwMode()); let hasInitialSearched = $state(false); + let selectedCard = $state(null); - // Track known imported items (URLs) let importedUrls = $derived.by(() => { const urls = new Set(); if (mode === "character") { @@ -74,30 +82,20 @@ return urls; }); - // Persist settings $effect(() => { if (typeof localStorage !== "undefined") { localStorage.setItem(NSFW_MODE_STORAGE_KEY, nsfwMode); } }); - // Tag filtering let selectedTags = $state([]); let tagInput = $state(""); let showTagDropdown = $state(false); - let showProviderDropdown = $state(false); let availableTags = $state([]); let isLoadingTags = $state(false); - // Derived let providers = $derived(discoveryService.getProviders(mode)); - let activeProviderName = $derived( - activeProviderId === "all" - ? "All Sources" - : providers.find((p) => p.id === activeProviderId)?.name || "Unknown", - ); - // Filter suggestions from available tags based on input let tagSuggestions = $derived( tagInput.trim() ? availableTags @@ -106,14 +104,14 @@ t.toLowerCase().includes(tagInput.toLowerCase()) && !selectedTags.includes(t), ) - .slice(0, 15) + .slice(0, 30) : [], ); - // Popular tags (subset of available tags for quick selection) - let popularTags = $derived(availableTags.slice(0, 18)); + let popularTags = $derived( + availableTags.slice(0, 20).filter((t) => !selectedTags.includes(t)), + ); - // Fetch tags when modal opens or provider changes async function loadTags() { isLoadingTags = true; try { @@ -131,33 +129,26 @@ } } - // Load tags when modal opens and trigger initial search $effect(() => { if (isOpen) { loadTags(); - // Trigger initial search when modal first opens if (!hasInitialSearched) { hasInitialSearched = true; handleSearch(); } } else { - // Reset when modal closes hasInitialSearched = false; } }); - // Reload tags when provider changes $effect(() => { - // Create dependency on activeProviderId const _providerId = activeProviderId; if (isOpen) { loadTags(); } }); - // Reset state when mode changes $effect(() => { - // Access mode to create dependency const _mode = mode; results = []; currentPage = 1; @@ -211,7 +202,6 @@ let result: SearchResult; if (activeProviderId === "all") { - // Use loadMoreAll for aggregated pagination result = await discoveryService.loadMoreAll(mode, 48); } else { const searchOptions = { @@ -260,29 +250,6 @@ } } - function handleKeyDown(e: KeyboardEvent) { - if (e.key === "Enter") { - handleSearch(); - } - if (e.key === "Escape") { - if (showProviderDropdown) { - showProviderDropdown = false; - } else if (showTagDropdown) { - showTagDropdown = false; - } else { - onClose(); - } - } - } - - function selectProvider(providerId: string) { - activeProviderId = providerId; - showProviderDropdown = false; - results = []; - hasMore = false; - errorMessage = null; - } - function toggleTag(tag: string) { if (selectedTags.includes(tag)) { selectedTags = selectedTags.filter((t) => t !== tag); @@ -306,431 +273,344 @@ function clearTags() { selectedTags = []; } + + function handleViewDetails(card: DiscoveryCard) { + selectedCard = card; + } -{#if isOpen} - - - -
!v && onClose()}> + - -
e.stopPropagation()} - > - -
(selectedCard = null)} + onImport={handleImport} + isImported={selectedCard && + importedUrls.has(selectedCard.imageUrl || selectedCard.avatarUrl)} + {nsfwMode} + /> + {:else} + -

Browse {mode === "character" ? "Characters" : mode === "lorebook" ? "Lorebooks" : "Scenarios"} -

- -
+ + + Find and import new {mode}s from online sources. + + - -
- -
-
- - -
- -
- - -
- -
- - - {#if showProviderDropdown} -
- - - -
- - {#each providers as provider} - - {/each} -
- {/if} -
- - -
- - - {#if showTagDropdown} -
- -
-
- { - if (e.key === "Enter") { - e.preventDefault(); - if (tagSuggestions.length > 0) { - toggleTag(tagSuggestions[0]); - tagInput = ""; - } else { - addCustomTag(); - } - } - }} - placeholder="Type to search tags..." - class="w-full rounded-lg border border-surface-600 bg-surface-900 px-3 py-2 pr-10 text-sm text-surface-200 placeholder-surface-500 focus:border-primary-500 focus:outline-none focus:ring-1 focus:ring-primary-500" - /> - - - - {#if tagSuggestions.length > 0} +
+ + + {#if activeProviderId === "all"}
- {#each tagSuggestions as suggestion} - - {/each} + + All Sources +
+ {:else} + {@const p = providers.find( + (p) => p.id === activeProviderId, + )} +
+ {#if p?.icon} + + {:else} + + {/if} + {p?.name || "Unknown"}
{/if} -
-
- - - {#if selectedTags.length > 0} -
-
- Selected - -
-
- {#each selectedTags as tag} - - {/each} -
-
- {/if} - - -
-
- Popular Tags - {#if isLoadingTags} - - {/if} -
- {#if popularTags.length > 0} -
- {#each popularTags as tag} - - {/each} -
- {:else if !isLoadingTags} -

No tags available

- {/if} -
+ + + + + All Sources + + {#each providers as provider} + + {#if provider.icon} + + {:else} + + {/if} + {provider.name} + + {/each} + +
- {/if} -
- - +
+ + + {#snippet child({ props })} + + {/snippet} + + + + { + if (e.key === "Enter") { + e.preventDefault(); + if (tagSuggestions.length > 0) { + toggleTag(tagSuggestions[0]); + tagInput = ""; + } else { + addCustomTag(); + } + } + }} + /> + + + {#if tagInput} + + {:else} + No tags found. + {/if} + + {#if tagSuggestions.length > 0} + + {#each tagSuggestions as tag} + { + toggleTag(tag); + tagInput = ""; + }} + > +
+ +
+ {tag} +
+ {/each} +
+ {/if} + + {#if popularTags.length > 0 && !tagInput} + + {#each popularTags as tag} + toggleTag(tag)} + > +
+ +
+ {tag} +
+ {/each} +
+ {/if} +
+
+
+
+
+ + + +
+ NSFW: + + + + + + + + + + + + + + +
+
- -
- NSFW:
- - - -
-
- - - - - - + +
+
+ e.key === "Enter" && handleSearch()} + class="h-9 rounded-r-none border-r-0 focus-visible:ring-0 focus-visible:border-primary focus-visible:z-10" + /> + +
+
+ + {#if selectedTags.length > 0} +
+ {#each selectedTags as tag} + + {tag} + + + {/each} + +
+ {/if}
-
- - {#if selectedTags.length > 0} -
- Filtering by: -
- {#each selectedTags as tag} - - - {tag} - - - {/each} -
- + {#if errorMessage} +
-
- {/if} + {errorMessage} +
+ {/if} - - {#if errorMessage} -
- {errorMessage} -
- {/if} - - -
{#if results.length === 0 && !isLoading}
- -

- Search to discover {mode === "character" - ? "characters" - : mode === "lorebook" - ? "lorebooks" - : "scenarios"} + +

No results found

+

+ Try adjusting your search terms or filters.

- {#if activeProviderId === "all"} -

- Searching across all available sources -

- {/if}
{:else}
{/each}
- {#if hasMore} -
- +
{/if} {/if}
-
-
-{/if} + {/if} + + diff --git a/src/lib/components/tags/TagManager.svelte b/src/lib/components/tags/TagManager.svelte index 90a4761..743c0c8 100644 --- a/src/lib/components/tags/TagManager.svelte +++ b/src/lib/components/tags/TagManager.svelte @@ -1,37 +1,68 @@ -
{ if (e.target === e.currentTarget) onClose(); }} - role="dialog" - aria-modal="true" -> -
- -
-

Manage Tags

- -
+ + + - -
- - - -
+ + Characters + Lorebooks + Scenarios + + - -
-
+ +
- - e.key === 'Enter' && handleCreate()} + onkeydown={(e) => e.key === "Enter" && handleCreate()} />
- + /> +
+ + +
+ {#if filteredTags.length > 0} +
+ {#each filteredTags as tag (tag.id)} +
+ {#if editingId === tag.id} + +
+ +
+
+ +
+ + e.key === "Enter" && saveEdit()} + /> + +
+ + +
+
+ {:else} + +
+
+ {tag.name} +
+ +
+ + +
+ {/if} +
+ {/each} +
+ {:else} +
+

No tags found.

+

Create one above to get started.

+
+ {/if}
- - -
- {#each filteredTags as tag (tag.id)} -
- {#if editingId === tag.id} - -
- -
-
- -
- - e.key === 'Enter' && saveEdit()} - /> - -
- - -
-
- {:else} - -
-
- {tag.name} -
- -
- - -
- {/if} -
- {:else} -
-

No tags found.

-

Create one above to get started.

-
- {/each} -
-
-
+ + diff --git a/src/lib/components/ui/alert/alert-description.svelte b/src/lib/components/ui/alert/alert-description.svelte new file mode 100644 index 0000000..b413b5f --- /dev/null +++ b/src/lib/components/ui/alert/alert-description.svelte @@ -0,0 +1,16 @@ + + +
+ {@render children?.()} +
diff --git a/src/lib/components/ui/alert/alert-title.svelte b/src/lib/components/ui/alert/alert-title.svelte new file mode 100644 index 0000000..094669e --- /dev/null +++ b/src/lib/components/ui/alert/alert-title.svelte @@ -0,0 +1,25 @@ + + +
+ {@render children?.()} +
diff --git a/src/lib/components/ui/alert/alert.svelte b/src/lib/components/ui/alert/alert.svelte new file mode 100644 index 0000000..f9327d6 --- /dev/null +++ b/src/lib/components/ui/alert/alert.svelte @@ -0,0 +1,39 @@ + + + + + diff --git a/src/lib/components/ui/alert/index.ts b/src/lib/components/ui/alert/index.ts new file mode 100644 index 0000000..97e21b4 --- /dev/null +++ b/src/lib/components/ui/alert/index.ts @@ -0,0 +1,14 @@ +import Root from "./alert.svelte"; +import Description from "./alert-description.svelte"; +import Title from "./alert-title.svelte"; +export { alertVariants, type AlertVariant } from "./alert.svelte"; + +export { + Root, + Description, + Title, + // + Root as Alert, + Description as AlertDescription, + Title as AlertTitle, +}; diff --git a/src/lib/components/ui/button/button.svelte b/src/lib/components/ui/button/button.svelte index 2aaefcb..ad4f404 100644 --- a/src/lib/components/ui/button/button.svelte +++ b/src/lib/components/ui/button/button.svelte @@ -13,13 +13,14 @@ default: "bg-primary text-primary-foreground hover:bg-primary/90", destructive: - "bg-destructive text-destructive-foreground hover:bg-destructive/90", + "text-foreground hover:text-destructive", outline: "border-input bg-background hover:bg-accent hover:text-accent-foreground border", secondary: "bg-secondary text-secondary-foreground hover:bg-secondary/80", ghost: "hover:bg-accent hover:text-accent-foreground", link: "text-primary underline-offset-4 hover:underline", + text: "text-foreground hover:text-accent", }, size: { default: "h-10 px-4 py-2", diff --git a/src/lib/components/ui/collapsible/collapsible-content.svelte b/src/lib/components/ui/collapsible/collapsible-content.svelte new file mode 100644 index 0000000..078c151 --- /dev/null +++ b/src/lib/components/ui/collapsible/collapsible-content.svelte @@ -0,0 +1,22 @@ + + + + + diff --git a/src/lib/components/ui/collapsible/collapsible-trigger.svelte b/src/lib/components/ui/collapsible/collapsible-trigger.svelte new file mode 100644 index 0000000..ad47c8c --- /dev/null +++ b/src/lib/components/ui/collapsible/collapsible-trigger.svelte @@ -0,0 +1,22 @@ + + +text-accent-400]", + className + )} + {...restProps} +> + + diff --git a/src/lib/components/ui/collapsible/collapsible.svelte b/src/lib/components/ui/collapsible/collapsible.svelte new file mode 100644 index 0000000..97d7b6d --- /dev/null +++ b/src/lib/components/ui/collapsible/collapsible.svelte @@ -0,0 +1,17 @@ + + + diff --git a/src/lib/components/ui/collapsible/index.ts b/src/lib/components/ui/collapsible/index.ts new file mode 100644 index 0000000..be175f7 --- /dev/null +++ b/src/lib/components/ui/collapsible/index.ts @@ -0,0 +1,12 @@ +import Root from "./collapsible.svelte"; +import Trigger from "./collapsible-trigger.svelte"; +import Content from "./collapsible-content.svelte"; + +export { + Root, + Trigger, + Content, + Root as Collapsible, + Trigger as CollapsibleTrigger, + Content as CollapsibleContent, +}; diff --git a/src/lib/components/ui/dialog/dialog-content.svelte b/src/lib/components/ui/dialog/dialog-content.svelte index 9f1a33b..92d2c19 100644 --- a/src/lib/components/ui/dialog/dialog-content.svelte +++ b/src/lib/components/ui/dialog/dialog-content.svelte @@ -1,5 +1,8 @@ + + + {#snippet children({ checked, indeterminate })} + + {#if indeterminate} + + {:else} + + {/if} + + {@render childrenProp?.()} + {/snippet} + diff --git a/src/lib/components/ui/dropdown-menu/dropdown-menu-content.svelte b/src/lib/components/ui/dropdown-menu/dropdown-menu-content.svelte new file mode 100644 index 0000000..1986371 --- /dev/null +++ b/src/lib/components/ui/dropdown-menu/dropdown-menu-content.svelte @@ -0,0 +1,26 @@ + + + + + diff --git a/src/lib/components/ui/dropdown-menu/dropdown-menu-group-heading.svelte b/src/lib/components/ui/dropdown-menu/dropdown-menu-group-heading.svelte new file mode 100644 index 0000000..56be80d --- /dev/null +++ b/src/lib/components/ui/dropdown-menu/dropdown-menu-group-heading.svelte @@ -0,0 +1,19 @@ + + + diff --git a/src/lib/components/ui/dropdown-menu/dropdown-menu-item.svelte b/src/lib/components/ui/dropdown-menu/dropdown-menu-item.svelte new file mode 100644 index 0000000..b0a3314 --- /dev/null +++ b/src/lib/components/ui/dropdown-menu/dropdown-menu-item.svelte @@ -0,0 +1,23 @@ + + + diff --git a/src/lib/components/ui/dropdown-menu/dropdown-menu-label.svelte b/src/lib/components/ui/dropdown-menu/dropdown-menu-label.svelte new file mode 100644 index 0000000..e2b074c --- /dev/null +++ b/src/lib/components/ui/dropdown-menu/dropdown-menu-label.svelte @@ -0,0 +1,23 @@ + + +
+ {@render children?.()} +
diff --git a/src/lib/components/ui/dropdown-menu/dropdown-menu-radio-item.svelte b/src/lib/components/ui/dropdown-menu/dropdown-menu-radio-item.svelte new file mode 100644 index 0000000..9c5b20c --- /dev/null +++ b/src/lib/components/ui/dropdown-menu/dropdown-menu-radio-item.svelte @@ -0,0 +1,30 @@ + + + + {#snippet children({ checked })} + + {#if checked} + + {/if} + + {@render childrenProp?.({ checked })} + {/snippet} + diff --git a/src/lib/components/ui/dropdown-menu/dropdown-menu-separator.svelte b/src/lib/components/ui/dropdown-menu/dropdown-menu-separator.svelte new file mode 100644 index 0000000..cf22641 --- /dev/null +++ b/src/lib/components/ui/dropdown-menu/dropdown-menu-separator.svelte @@ -0,0 +1,16 @@ + + + diff --git a/src/lib/components/ui/dropdown-menu/dropdown-menu-shortcut.svelte b/src/lib/components/ui/dropdown-menu/dropdown-menu-shortcut.svelte new file mode 100644 index 0000000..6cd24ff --- /dev/null +++ b/src/lib/components/ui/dropdown-menu/dropdown-menu-shortcut.svelte @@ -0,0 +1,20 @@ + + + + {@render children?.()} + diff --git a/src/lib/components/ui/dropdown-menu/dropdown-menu-sub-content.svelte b/src/lib/components/ui/dropdown-menu/dropdown-menu-sub-content.svelte new file mode 100644 index 0000000..1173db4 --- /dev/null +++ b/src/lib/components/ui/dropdown-menu/dropdown-menu-sub-content.svelte @@ -0,0 +1,19 @@ + + + diff --git a/src/lib/components/ui/dropdown-menu/dropdown-menu-sub-trigger.svelte b/src/lib/components/ui/dropdown-menu/dropdown-menu-sub-trigger.svelte new file mode 100644 index 0000000..b229955 --- /dev/null +++ b/src/lib/components/ui/dropdown-menu/dropdown-menu-sub-trigger.svelte @@ -0,0 +1,28 @@ + + + + {@render children?.()} + + diff --git a/src/lib/components/ui/dropdown-menu/index.ts b/src/lib/components/ui/dropdown-menu/index.ts new file mode 100644 index 0000000..40c4502 --- /dev/null +++ b/src/lib/components/ui/dropdown-menu/index.ts @@ -0,0 +1,50 @@ +import { DropdownMenu as DropdownMenuPrimitive } from "bits-ui"; +import CheckboxItem from "./dropdown-menu-checkbox-item.svelte"; +import Content from "./dropdown-menu-content.svelte"; +import GroupHeading from "./dropdown-menu-group-heading.svelte"; +import Item from "./dropdown-menu-item.svelte"; +import Label from "./dropdown-menu-label.svelte"; +import RadioItem from "./dropdown-menu-radio-item.svelte"; +import Separator from "./dropdown-menu-separator.svelte"; +import Shortcut from "./dropdown-menu-shortcut.svelte"; +import SubContent from "./dropdown-menu-sub-content.svelte"; +import SubTrigger from "./dropdown-menu-sub-trigger.svelte"; + +const Sub = DropdownMenuPrimitive.Sub; +const Root = DropdownMenuPrimitive.Root; +const Trigger = DropdownMenuPrimitive.Trigger; +const Group = DropdownMenuPrimitive.Group; +const RadioGroup = DropdownMenuPrimitive.RadioGroup; + +export { + CheckboxItem, + Content, + Root as DropdownMenu, + CheckboxItem as DropdownMenuCheckboxItem, + Content as DropdownMenuContent, + Group as DropdownMenuGroup, + GroupHeading as DropdownMenuGroupHeading, + Item as DropdownMenuItem, + Label as DropdownMenuLabel, + RadioGroup as DropdownMenuRadioGroup, + RadioItem as DropdownMenuRadioItem, + Separator as DropdownMenuSeparator, + Shortcut as DropdownMenuShortcut, + Sub as DropdownMenuSub, + SubContent as DropdownMenuSubContent, + SubTrigger as DropdownMenuSubTrigger, + Trigger as DropdownMenuTrigger, + Group, + GroupHeading, + Item, + Label, + RadioGroup, + RadioItem, + Root, + Separator, + Shortcut, + Sub, + SubContent, + SubTrigger, + Trigger, +}; diff --git a/src/lib/components/ui/index.ts b/src/lib/components/ui/index.ts new file mode 100644 index 0000000..83c0198 --- /dev/null +++ b/src/lib/components/ui/index.ts @@ -0,0 +1,15 @@ +import { Collapsible as CollapsiblePrimitive } from "bits-ui"; + +const Root = CollapsiblePrimitive.Root; +const Trigger = CollapsiblePrimitive.Trigger; +const Content = CollapsiblePrimitive.Content; + +export { + Root, + Content, + Trigger, + // + Root as Collapsible, + Content as CollapsibleContent, + Trigger as CollapsibleTrigger, +}; diff --git a/src/lib/components/ui/input/input.svelte b/src/lib/components/ui/input/input.svelte index 5e333a1..325f921 100644 --- a/src/lib/components/ui/input/input.svelte +++ b/src/lib/components/ui/input/input.svelte @@ -14,7 +14,10 @@ | { type: "file"; files?: FileList } | { type?: InputType; files?: undefined } ) - >; + > & { + leftIcon?: typeof import("lucide-svelte").Search; + rightIcon?: typeof import("lucide-svelte").Search; + }; let { ref = $bindable(null), @@ -22,6 +25,8 @@ type, files = $bindable(), class: className, + leftIcon, + rightIcon, ...restProps }: Props = $props(); @@ -30,7 +35,7 @@ {:else} - +
+ {#if leftIcon} +
+ +
+ {/if} + + {#if rightIcon} +
+ +
+ {/if} +
{/if} diff --git a/src/lib/components/ui/responsive-modal/responsive-modal-content.svelte b/src/lib/components/ui/responsive-modal/responsive-modal-content.svelte index e195dd8..596b893 100644 --- a/src/lib/components/ui/responsive-modal/responsive-modal-content.svelte +++ b/src/lib/components/ui/responsive-modal/responsive-modal-content.svelte @@ -8,15 +8,15 @@ const { isMobile } = getResponsiveModalContext(); -{#if isMobile.current} + {#if isMobile.current} {@render children?.()} -{:else} + {:else} {@render children?.()} -{/if} + {/if} diff --git a/src/lib/components/ui/responsive-modal/responsive-modal-footer.svelte b/src/lib/components/ui/responsive-modal/responsive-modal-footer.svelte index 458469f..6aacbe6 100644 --- a/src/lib/components/ui/responsive-modal/responsive-modal-footer.svelte +++ b/src/lib/components/ui/responsive-modal/responsive-modal-footer.svelte @@ -9,11 +9,17 @@ {#if isMobile.current} - + {@render children?.()} {:else} - + {@render children?.()} {/if} diff --git a/src/lib/components/ui/responsive-modal/responsive-modal-header.svelte b/src/lib/components/ui/responsive-modal/responsive-modal-header.svelte index a5a5848..7431621 100644 --- a/src/lib/components/ui/responsive-modal/responsive-modal-header.svelte +++ b/src/lib/components/ui/responsive-modal/responsive-modal-header.svelte @@ -4,25 +4,39 @@ import { getResponsiveModalContext } from "./context"; import { cn } from "$lib/utils/cn"; import { X } from "lucide-svelte"; + import { Button } from "$lib/components/ui/button"; - let { children, class: className, ...props } = $props(); + let { title, class: className, children, ...props } = $props(); const { isMobile } = getResponsiveModalContext(); {#if isMobile.current} - - {@render children?.()} + + {#if title} +

{title}

+ {:else} + {@render children?.()} + {/if}
{:else} -
+
- {@render children?.()} + {#if title} +

{title}

+ {:else} + {@render children?.()} + {/if}
- - - Close + +
{/if} diff --git a/src/lib/components/ui/responsive-modal/responsive-modal-title.svelte b/src/lib/components/ui/responsive-modal/responsive-modal-title.svelte index b3e8265..a966d88 100644 --- a/src/lib/components/ui/responsive-modal/responsive-modal-title.svelte +++ b/src/lib/components/ui/responsive-modal/responsive-modal-title.svelte @@ -9,7 +9,7 @@ {#if isMobile.current} - + {@render children?.()} {:else} diff --git a/src/lib/components/ui/scroll-area/scroll-area-scrollbar.svelte b/src/lib/components/ui/scroll-area/scroll-area-scrollbar.svelte index a130b97..e6eb722 100644 --- a/src/lib/components/ui/scroll-area/scroll-area-scrollbar.svelte +++ b/src/lib/components/ui/scroll-area/scroll-area-scrollbar.svelte @@ -24,6 +24,6 @@ > {@render children?.()} diff --git a/src/lib/components/ui/scroll-area/scroll-area.svelte b/src/lib/components/ui/scroll-area/scroll-area.svelte index fed796a..379b865 100644 --- a/src/lib/components/ui/scroll-area/scroll-area.svelte +++ b/src/lib/components/ui/scroll-area/scroll-area.svelte @@ -23,10 +23,10 @@ {@render children?.()} {#if orientation === "vertical" || orientation === "both"} - + {/if} {#if orientation === "horizontal" || orientation === "both"} - + {/if} diff --git a/src/lib/components/ui/tabs/tabs-content.svelte b/src/lib/components/ui/tabs/tabs-content.svelte index 02aa7f8..ac885a1 100644 --- a/src/lib/components/ui/tabs/tabs-content.svelte +++ b/src/lib/components/ui/tabs/tabs-content.svelte @@ -13,7 +13,7 @@ bind:ref class={cn( "ring-offset-background focus-visible:ring-ring mt-2 focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-offset-2", - className + className, )} {...restProps} /> diff --git a/src/lib/components/ui/toggle-group/index.ts b/src/lib/components/ui/toggle-group/index.ts new file mode 100644 index 0000000..12b14b9 --- /dev/null +++ b/src/lib/components/ui/toggle-group/index.ts @@ -0,0 +1,10 @@ +import Root from "./toggle-group.svelte"; +import Item from "./toggle-group-item.svelte"; + +export { + Root, + Item, + // + Root as ToggleGroup, + Item as ToggleGroupItem, +}; diff --git a/src/lib/components/ui/toggle-group/toggle-group-item.svelte b/src/lib/components/ui/toggle-group/toggle-group-item.svelte new file mode 100644 index 0000000..f4db3ee --- /dev/null +++ b/src/lib/components/ui/toggle-group/toggle-group-item.svelte @@ -0,0 +1,30 @@ + + + diff --git a/src/lib/components/ui/toggle-group/toggle-group.svelte b/src/lib/components/ui/toggle-group/toggle-group.svelte new file mode 100644 index 0000000..16c7552 --- /dev/null +++ b/src/lib/components/ui/toggle-group/toggle-group.svelte @@ -0,0 +1,41 @@ + + + + + + diff --git a/src/lib/components/ui/toggle/index.ts b/src/lib/components/ui/toggle/index.ts new file mode 100644 index 0000000..8cb2936 --- /dev/null +++ b/src/lib/components/ui/toggle/index.ts @@ -0,0 +1,13 @@ +import Root from "./toggle.svelte"; +export { + toggleVariants, + type ToggleSize, + type ToggleVariant, + type ToggleVariants, +} from "./toggle.svelte"; + +export { + Root, + // + Root as Toggle, +}; diff --git a/src/lib/components/ui/toggle/toggle.svelte b/src/lib/components/ui/toggle/toggle.svelte new file mode 100644 index 0000000..c81cb0f --- /dev/null +++ b/src/lib/components/ui/toggle/toggle.svelte @@ -0,0 +1,51 @@ + + + + + diff --git a/src/lib/components/vault/InteractiveLorebookChat.svelte b/src/lib/components/vault/InteractiveLorebookChat.svelte index 9daece8..63c3502 100644 --- a/src/lib/components/vault/InteractiveLorebookChat.svelte +++ b/src/lib/components/vault/InteractiveLorebookChat.svelte @@ -8,7 +8,7 @@ type StreamEvent } from '$lib/services/ai/interactiveLorebook'; import { OpenAIProvider } from '$lib/services/ai/openrouter'; - import { settings, getDefaultInteractiveLorebookSettings } from '$lib/stores/settings.svelte'; + import { settings } from '$lib/stores/settings.svelte'; import DiffView from './DiffView.svelte'; import { X, Send, Loader2, Bot, User, ChevronDown, ChevronUp, @@ -17,6 +17,10 @@ import { fade, slide } from 'svelte/transition'; import { onMount, onDestroy, tick } from 'svelte'; import { parseMarkdown } from '$lib/utils/markdown'; + import { Button } from '$lib/components/ui/button'; + import { Textarea } from '$lib/components/ui/textarea'; + import { Badge } from '$lib/components/ui/badge'; + import { cn } from '$lib/utils/cn'; // AbortController for cancelling ongoing requests let abortController: AbortController | null = null; @@ -368,34 +372,20 @@
- -
-
- - AI Assistant -
- -
- {#if pendingCount >= 2} -
- +
{/if} @@ -406,34 +396,43 @@ > {#each messages as message (message.id)}
-
+
{#if message.role === 'assistant'} - + {:else} - + {/if}
-
{@html parseMarkdown(message.content)}
+
{@html parseMarkdown(message.content)}
{#if message.role === 'assistant' && formatReasoning(message)} {@const reasoning = formatReasoning(message)} -
+
{#if expandedReasoning.has(message.id)} -
+
{reasoning}
{/if} @@ -457,11 +456,11 @@ {#if message.toolCalls && message.toolCalls.length > 0}
{#each message.toolCalls as toolCall (toolCall.id)} -
- - {formatToolCallName(toolCall.name)} +
+ + {formatToolCallName(toolCall.name)} {#if toolCall.args && Object.keys(toolCall.args).length > 0} - + {#if toolCall.name === 'list_entries' && toolCall.args.type} (type: {toolCall.args.type}) {:else if toolCall.name === 'get_entry' && toolCall.args.index !== undefined} @@ -495,9 +494,12 @@ {:else}
{#if change.status === 'approved'} @@ -514,7 +516,10 @@ {/if} -
+
{new Date(message.timestamp).toLocaleTimeString()}
@@ -525,23 +530,23 @@ {#if isGenerating}
-
+
- +
{#if activeToolCalls.length > 0}
{#each activeToolCalls as toolCall (toolCall.id)} -
+
{#if toolCall.result === '...'} - + {:else} - + {/if} - {formatToolCallName(toolCall.name)} + {formatToolCallName(toolCall.name)} {#if toolCall.args && Object.keys(toolCall.args).length > 0} - + {#if toolCall.name === 'create_entry' && toolCall.args.name} ({toolCall.args.name}) {:else if toolCall.name === 'list_entries' && toolCall.args.type} @@ -555,7 +560,7 @@ {/each}
{:else if isThinking} -
+
Thinking...
@@ -570,8 +575,8 @@ {#if error} -
-
+
+
{error}
@@ -579,18 +584,19 @@ {/if} -
-
- - +
- diff --git a/src/lib/components/vault/TagFilter.svelte b/src/lib/components/vault/TagFilter.svelte index 4db1dbf..aeb17dd 100644 --- a/src/lib/components/vault/TagFilter.svelte +++ b/src/lib/components/vault/TagFilter.svelte @@ -64,7 +64,7 @@ {/snippet} - +
- import type { VaultCharacter, VaultLorebook, VaultScenario } from "$lib/types"; + import type { + VaultCharacter, + VaultLorebook, + VaultScenario, + } from "$lib/types"; import { normalizeImageDataUrl } from "$lib/utils/image"; import { Badge } from "$lib/components/ui/badge"; - import { - User, - Users, - Book, - MapPin, - MessageSquare, + import { + User, + Users, + Book, + MapPin, + MessageSquare, Archive, Box, Flag, Brain, - Calendar + Calendar, } from "lucide-svelte"; import TagBadge from "$lib/components/tags/TagBadge.svelte"; import { tagStore } from "$lib/stores/tags.svelte"; @@ -39,13 +43,19 @@ onDelete, onToggleFavorite, selectable = false, - onSelect + onSelect, }: Props = $props(); // Type Guards & Casters - const asCharacter = $derived(type === "character" ? (item as VaultCharacter) : null); - const asLorebook = $derived(type === "lorebook" ? (item as VaultLorebook) : null); - const asScenario = $derived(type === "scenario" ? (item as VaultScenario) : null); + const asCharacter = $derived( + type === "character" ? (item as VaultCharacter) : null, + ); + const asLorebook = $derived( + type === "lorebook" ? (item as VaultLorebook) : null, + ); + const asScenario = $derived( + type === "scenario" ? (item as VaultScenario) : null, + ); let isImporting = $derived(item.metadata?.importing === true); @@ -88,16 +98,22 @@ class="h-32 w-24 rounded-md object-cover ring-1 ring-border" /> {:else} -
+
{/if} {:else if asLorebook} -
+
{:else if asScenario} -
+
{/if} @@ -108,9 +124,9 @@ {asLorebook.entries.length} entries - {#if asLorebook.source === 'story' || asLorebook.source === 'import'} + {#if asLorebook.source === "story" || asLorebook.source === "import"} - {asLorebook.source === 'story' ? 'Story' : 'Imported'} + {asLorebook.source === "story" ? "Story" : "Imported"} {/if} {:else if asScenario} @@ -138,7 +154,7 @@ {#snippet description()} {#if item.description} -

+

{item.description}

{/if} @@ -168,7 +184,10 @@
{#each lorebookEntryCounts.slice(0, 4) as { type, count }} {@const Icon = entryTypeIcons[type]} -
+
{#if Icon} {/if} diff --git a/src/lib/components/vault/VaultCharacterForm.svelte b/src/lib/components/vault/VaultCharacterForm.svelte index b2b3313..ae6fed3 100644 --- a/src/lib/components/vault/VaultCharacterForm.svelte +++ b/src/lib/components/vault/VaultCharacterForm.svelte @@ -124,15 +124,13 @@ }} > - - {isEditing ? "Edit Character" : "New Character"} - + -
+
{ @@ -276,7 +274,7 @@ class="w-full" > {#if saving} - + {/if} {isEditing ? "Save Changes" : "Create Character"} diff --git a/src/lib/components/vault/VaultLorebookEditor.svelte b/src/lib/components/vault/VaultLorebookEditor.svelte index cf6d485..e3b0438 100644 --- a/src/lib/components/vault/VaultLorebookEditor.svelte +++ b/src/lib/components/vault/VaultLorebookEditor.svelte @@ -1,15 +1,44 @@ - { if (!open) onClose(); }}> - - - -
-
-
- -
- {entries.length} entries -
+ { + if (!open) onClose(); + }} +> + + + Edit Lorebook + {#if error} +
+ {error} +
+ {/if} +
+ + +
+ + + + Entries ({entries.length}) + + + + Settings + + + +
+ {#if name.trim()} + + {/if}
-
- {#if error} - - {/if} + +
+ +
+ +
+
+
+ + +
- - +
+ + -
- -
- - tags = newTags} - placeholder="Add tags..." - /> -
- -
-

Statistics

-
-
- Total Entries - {entries.length} -
-
- Active Entries - {entries.filter(e => !e.disabled).length} +
+

Statistics

+
+
+ Total Entries + {entries.length} +
+
+ Active Entries + {entries.filter((e) => !e.disabled).length} +
-
-
+ - {:else} - - - -
- -
-
- - -
- -
+
+
+ + +
+ +
- -
- {#if filteredEntries.length === 0} -
- {#if searchQuery} - No matches found +
+ {#if filteredEntries.length === 0} +
+ {#if searchQuery} + No matches found + {:else} + No entries yet + {/if} +
{:else} - No entries yet + {#each filteredEntries as { entry, index }} + {@const Icon = typeIcons[entry.type]} + + {/each} {/if}
- {:else} - {#each filteredEntries as { entry, index }} - {@const Icon = typeIcons[entry.type]} - - {/each} - {/if} -
-
- - -
- {#if selectedEntry !== null && selectedIndex !== null} - -
-
- - - -
-
- - -
- -
-
- - -
- -
- -
- -
- -
-
-
- - -
- - +
+ {#if selectedEntry !== null && selectedIndex !== null} +
+
+ +
+
+ + +
- -
- - selectedEntry!.keywords = e.currentTarget.value.split(',').map(k => k.trim()).filter(Boolean)} - placeholder="Comma-separated keywords for activation" - class="w-full rounded-lg border border-surface-600 bg-surface-800 px-4 py-2.5 text-surface-100 placeholder-surface-500 focus:border-accent-500 focus:outline-none" - /> -

- Terms that trigger this entry when using 'Keyword' injection mode. -

-
+
+
+
+
+ + +
- -
- - -
- - -
-

Injection Settings

- -
- -
- - +
+ + +
- -
- - + + + (selectedEntry!.keywords = e.currentTarget.value + .split(",") + .map((k) => k.trim()) + .filter(Boolean))} + placeholder="Comma-separated keywords..." + /> +

+ Terms that trigger this entry when using 'Keyword' + injection mode. +

+
+ +
+ + + class="resize-none" + />
-
- -

The core setting information used to generate the story world.

- +
+ +
+ -
- -
-
- - -
-
- - npc.traits = e.currentTarget.value.split(',').map(t => t.trim()).filter(Boolean)} - class="w-full rounded bg-surface-700/50 border border-surface-600 px-3 py-1.5 text-sm text-surface-100 focus:border-accent-500 focus:outline-none" - /> -
-
-
- {/if} + +
{/each} {/if}
-
- {/if} + - - {#if activeTab === 'opening'} -
-
-
- - The initial message displayed when starting the story. -
- + rows={6} + class="font-mono text-sm leading-relaxed" + placeholder="The opening scene..." + /> +

+ Shown when the story begins. +

-
-
-
-

Alternate Greetings

-

Variations of the opening scene.

+
+
+ + +
+ + {#each alternateGreetings as greeting, i} +
+ - -
- {/each} - {#if alternateGreetings.length === 0} -

No alternate greetings defined.

- {/if} -
+ No variations added. +

+ {/if}
-
- {/if} - -
-
- - - -
- {#if error} -
- - {error} -
- {:else} - - {/if} - -
- - +
+ + + +
+ + +
+ - - {#if showCharacterSelector} -
{ e.stopPropagation(); showCharacterSelector = false; }} - role="dialog" - aria-modal="true" - > -
e.stopPropagation()} - role="document" - tabindex="-1" - > - -
-

Select Character

- -
+ +{#if showCharacterSelector} + (showCharacterSelector = open)} + > + + +

Import Character

+
- -
-
- - -
-
- - -
- {#if filteredCharacters.length === 0} -
- -

No matching characters found.

-
- {:else} - {#each filteredCharacters as char (char.id)} - addNpcFromCharacter(char)} - class="hover:bg-surface-800 border-transparent bg-transparent" - > - {#snippet icon()} - - - - - - - {/snippet} - - {#snippet end()} - - {/snippet} - - {/each} - {/if} +
+
+ +
-
- {/if} -
\ No newline at end of file + +
+ {#if filteredCharacters.length === 0} +
+ +

No characters found

+
+ {:else} + {#each filteredCharacters as char} + + {/each} + {/if} +
+ + +{/if} diff --git a/src/lib/components/vault/shared/VaultCard.svelte b/src/lib/components/vault/shared/VaultCard.svelte index 543cdfe..4e0005b 100644 --- a/src/lib/components/vault/shared/VaultCard.svelte +++ b/src/lib/components/vault/shared/VaultCard.svelte @@ -116,14 +116,17 @@
-
+
-

+

{title}

-
+
{#if badges} {@render badges()} {/if} @@ -216,7 +219,7 @@
{#if description} -
+
{@render description()}
{/if} diff --git a/src/lib/services/discovery/index.ts b/src/lib/services/discovery/index.ts index 9bacd90..b4aa707 100644 --- a/src/lib/services/discovery/index.ts +++ b/src/lib/services/discovery/index.ts @@ -229,9 +229,24 @@ class DiscoveryService { return provider.getTags(); } + async getCardDetails(card: DiscoveryCard): Promise { + const provider = this.providers.get(card.source); + if (!provider) { + // If provider not found or doesn't support fetching details, return original card + return card; + } + + if (provider.getCardDetails) { + return provider.getCardDetails(card); + } + + return card; + } + /** * Get tags from all providers (combined and deduplicated) */ + async getAllTags(type?: 'character' | 'lorebook' | 'scenario'): Promise { const providers = this.getProviders(type); diff --git a/src/lib/services/discovery/providers/chub.ts b/src/lib/services/discovery/providers/chub.ts index 87c8967..1dfb2d4 100644 --- a/src/lib/services/discovery/providers/chub.ts +++ b/src/lib/services/discovery/providers/chub.ts @@ -139,7 +139,49 @@ export class ChubProvider implements DiscoveryProvider { return await response.blob(); } + async getCardDetails(card: DiscoveryCard): Promise { + if (card.type === 'lorebook') { + // Lorebooks might have a different structure, but we can try fetching the project definition + return card; + } + + try { + const url = `${CHUB_API_BASE}/api/characters/${card.id}?full=true`; + console.log('[Chub] Fetching full details:', url); + + const response = await corsFetch(url, { + method: 'GET', + headers: { Accept: 'application/json' } + }); + + if (!response.ok) { + console.warn(`[Chub] Failed to fetch details for ${card.id}: ${response.status}`); + return card; + } + + const data = await response.json(); + + // Update the raw data with the full definition + // We assume data.node contains the character definition or data itself is the node + const fullNode = data.node || data; + + return { + ...card, + // Update specific fields if they were missing/truncated in search + description: fullNode.description || fullNode.tagline || card.description, + raw: { + ...card.raw, + ...fullNode + } + }; + } catch (error) { + console.error('[Chub] Error fetching details:', error); + return card; + } + } + async getTags(): Promise { + // Return cached tags if available if (cachedTags) { return cachedTags; diff --git a/src/lib/services/discovery/types.ts b/src/lib/services/discovery/types.ts index b185c25..01650f7 100644 --- a/src/lib/services/discovery/types.ts +++ b/src/lib/services/discovery/types.ts @@ -43,4 +43,7 @@ export interface DiscoveryProvider { downloadCard(card: DiscoveryCard): Promise; // Get available tags for filtering (provider-specific) getTags(): Promise; + // Fetch full details for a card (e.g. including alternate greetings, scenario, etc.) + getCardDetails?(card: DiscoveryCard): Promise; } + diff --git a/tailwind.config.js b/tailwind.config.js deleted file mode 100644 index a9cbfb1..0000000 --- a/tailwind.config.js +++ /dev/null @@ -1,105 +0,0 @@ -import { fontFamily } from "tailwindcss/defaultTheme"; -import tailwindcssAnimate from "tailwindcss-animate"; - -/** @type {import('tailwindcss').Config} */ -export default { - darkMode: ["class"], - content: ['./src/**/*.{html,js,svelte,ts}'], - safelist: ["dark"], - theme: { - container: { - center: true, - padding: "2rem", - screens: { - "2xl": "1400px", - }, - }, - screens: { - 'xs': '475px', - 'sm': '640px', - 'md': '768px', - 'lg': '1024px', - 'xl': '1280px', - '2xl': '1536px', - }, - extend: { - colors: { - border: "hsl(var(--border) / )", - input: "hsl(var(--input) / )", - ring: "hsl(var(--ring) / )", - background: "hsl(var(--background) / )", - foreground: "hsl(var(--foreground) / )", - primary: { - DEFAULT: "hsl(var(--primary) / )", - foreground: "hsl(var(--primary-foreground) / )", - }, - secondary: { - DEFAULT: "hsl(var(--secondary) / )", - foreground: "hsl(var(--secondary-foreground) / )", - }, - destructive: { - DEFAULT: "hsl(var(--destructive) / )", - foreground: "hsl(var(--destructive-foreground) / )", - }, - muted: { - DEFAULT: "hsl(var(--muted) / )", - foreground: "hsl(var(--muted-foreground) / )", - }, - accent: { - DEFAULT: "hsl(var(--accent) / )", - foreground: "hsl(var(--accent-foreground) / )", - 50: '#eff6ff', - 100: '#dbeafe', - 200: '#bfdbfe', - 300: '#93c5fd', - 400: '#60a5fa', - 500: '#3b82f6', - 600: '#2563eb', - 700: '#1d4ed8', - 800: '#1e40af', - 900: '#1e3a8a', - 950: '#172554', - }, - popover: { - DEFAULT: "hsl(var(--popover) / )", - foreground: "hsl(var(--popover-foreground) / )", - }, - card: { - DEFAULT: "hsl(var(--card) / )", - foreground: "hsl(var(--card-foreground) / )", - }, - surface: { - 50: '#f8fafc', - 100: '#f1f5f9', - 200: '#e2e8f0', - 300: '#cbd5e1', - 400: '#94a3b8', - 500: '#64748b', - 600: '#475569', - 700: '#334155', - 800: '#1e293b', - 850: '#141b25', - 900: '#0f172a', - 950: '#020617', - }, - }, - borderColor: { - DEFAULT: "hsl(var(--border) / )", - }, - ringColor: { - DEFAULT: "hsl(var(--ring) / )", - }, - borderRadius: { - lg: "var(--radius)", - md: "calc(var(--radius) - 2px)", - sm: "calc(var(--radius) - 4px)", - }, - fontFamily: { - sans: ['Inter', 'system-ui', 'sans-serif', ...fontFamily.sans], - mono: ['JetBrains Mono', 'Fira Code', 'monospace', ...fontFamily.mono], - story: ['Georgia', 'Cambria', 'serif'], - }, - }, - }, - plugins: [tailwindcssAnimate], -}; diff --git a/tailwind.config.ts b/tailwind.config.ts new file mode 100644 index 0000000..a2e90e7 --- /dev/null +++ b/tailwind.config.ts @@ -0,0 +1,11 @@ +import type { Config } from "tailwindcss"; + +const config: Config = { + content: ["./src/**/*.{html,js,svelte,ts}"], + theme: { + extend: {}, + }, + plugins: [], +}; + +export default config; \ No newline at end of file diff --git a/vite.config.js b/vite.config.js index bed9095..244ac2f 100644 --- a/vite.config.js +++ b/vite.config.js @@ -1,11 +1,12 @@ import { defineConfig } from "vite"; import { sveltekit } from "@sveltejs/kit/vite"; +import tailwindcss from "@tailwindcss/vite"; const host = process.env.TAURI_DEV_HOST; // https://vite.dev/config/ -export default defineConfig(async () => ({ - plugins: [sveltekit()], +export default defineConfig(async () =>({ + plugins: [tailwindcss(), sveltekit()], // Vite options tailored for Tauri development and only applied in `tauri dev` or `tauri build` //