diff --git a/package.json b/package.json index 9a190456..fc9f9288 100644 --- a/package.json +++ b/package.json @@ -26,6 +26,8 @@ "css-coverage": "css-coverage ./css-coverage --min-coverage=.95 --min-file-coverage=.85 --show-uncovered=all" }, "dependencies": { + "@csstools/css-syntax-patches-for-csstree": "^1.1.4", + "@csstools/css-tokenizer": "^4.0.0", "@melt-ui/pp": "^0.3.2", "@melt-ui/svelte": "^0.86.6", "@oddbird/popover-polyfill": "^0.6.1", @@ -39,17 +41,21 @@ "@projectwallace/format-css": "catalog:", "@projectwallace/stylelint-plugin": "catalog:", "color-sorter": "catalog:", + "css-tree": "^3.2.1", "diff": "^9.0.0", + "fastest-levenshtein": "^1.0.16", "github-slugger": "^2.0.0", "lightningcss": "1.32.0", "linkedom": "^0.18.13", "mdsvex": "^0.12.8", "paneforge": "^1.0.2", + "postcss": "^8.5.30", "prism-svelte": "^0.5.0", "prismjs": "^1.30.0", "rehype-autolink-headings": "^7.1.0", "rehype-slug": "^6.0.0", "runed": "^0.37.1", + "stylelint": "~17.16.0", "svelte": "^5.56.8", "typescript": "^6.0.3", "vite": "catalog:", @@ -68,7 +74,6 @@ "oxlint": "^1.75.0", "oxlint-tsgolint": "^0.23.0", "postcss-html": "^1.8.1", - "stylelint": "~17.15.0", "stylelint-config-standard": "~40.0.0", "svelte-check": "^4.7.5", "vitest": "^4.1.11" diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 6a6b9d9b..4d1eeac6 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -29,6 +29,12 @@ importers: .: dependencies: + '@csstools/css-syntax-patches-for-csstree': + specifier: ^1.1.4 + version: 1.1.14(css-tree@3.2.1) + '@csstools/css-tokenizer': + specifier: ^4.0.0 + version: 4.0.0 '@melt-ui/pp': specifier: ^0.3.2 version: 0.3.2(@melt-ui/svelte@0.86.6(svelte@5.56.8))(svelte@5.56.8) @@ -64,13 +70,19 @@ importers: version: 3.2.0 '@projectwallace/stylelint-plugin': specifier: 'catalog:' - version: 0.7.0(stylelint@17.15.0(supports-color@10.2.2)(typescript@6.0.3)) + version: 0.7.0(stylelint@17.16.0(supports-color@10.2.2)(typescript@6.0.3)) color-sorter: specifier: ^8.0.2 version: 8.0.2 + css-tree: + specifier: ^3.2.1 + version: 3.2.1 diff: specifier: ^9.0.0 version: 9.0.0 + fastest-levenshtein: + specifier: ^1.0.16 + version: 1.0.16 github-slugger: specifier: ^2.0.0 version: 2.0.0 @@ -85,7 +97,10 @@ importers: version: 0.12.8(svelte@5.56.8) paneforge: specifier: ^1.0.2 - version: 1.0.2(@sveltejs/kit@3.0.0-next.27(@sveltejs/vite-plugin-svelte@7.3.0(svelte@5.56.8)(vite@8.2.1(@types/node@25.9.5)(esbuild@0.28.1)))(svelte@5.56.8)(typescript@6.0.3)(vite@8.2.1(@types/node@25.9.5)(esbuild@0.28.1)))(svelte@5.56.8) + version: 1.0.2(@sveltejs/kit@3.0.0-next.32(@sveltejs/vite-plugin-svelte@7.3.0(svelte@5.56.8)(vite@8.2.1(@types/node@25.9.5)(esbuild@0.28.1)))(svelte@5.56.8)(typescript@6.0.3)(vite@8.2.1(@types/node@25.9.5)(esbuild@0.28.1)))(svelte@5.56.8) + postcss: + specifier: ^8.5.30 + version: 8.5.30 prism-svelte: specifier: ^0.5.0 version: 0.5.0 @@ -100,7 +115,10 @@ importers: version: 6.0.0 runed: specifier: ^0.37.1 - version: 0.37.1(@sveltejs/kit@3.0.0-next.27(@sveltejs/vite-plugin-svelte@7.3.0(svelte@5.56.8)(vite@8.2.1(@types/node@25.9.5)(esbuild@0.28.1)))(svelte@5.56.8)(typescript@6.0.3)(vite@8.2.1(@types/node@25.9.5)(esbuild@0.28.1)))(svelte@5.56.8) + version: 0.37.1(@sveltejs/kit@3.0.0-next.32(@sveltejs/vite-plugin-svelte@7.3.0(svelte@5.56.8)(vite@8.2.1(@types/node@25.9.5)(esbuild@0.28.1)))(svelte@5.56.8)(typescript@6.0.3)(vite@8.2.1(@types/node@25.9.5)(esbuild@0.28.1)))(svelte@5.56.8) + stylelint: + specifier: ~17.16.0 + version: 17.16.0(supports-color@10.2.2)(typescript@6.0.3) svelte: specifier: ^5.56.8 version: 5.56.8 @@ -122,13 +140,13 @@ importers: version: 0.0.11(oxlint@1.75.0(oxlint-tsgolint@0.23.0)) '@sveltejs/adapter-netlify': specifier: next - version: 7.0.0-next.11(@sveltejs/kit@3.0.0-next.27(@sveltejs/vite-plugin-svelte@7.3.0(svelte@5.56.8)(vite@8.2.1(@types/node@25.9.5)(esbuild@0.28.1)))(svelte@5.56.8)(typescript@6.0.3)(vite@8.2.1(@types/node@25.9.5)(esbuild@0.28.1))) + version: 7.0.0-next.12(@sveltejs/kit@3.0.0-next.32(@sveltejs/vite-plugin-svelte@7.3.0(svelte@5.56.8)(vite@8.2.1(@types/node@25.9.5)(esbuild@0.28.1)))(svelte@5.56.8)(typescript@6.0.3)(vite@8.2.1(@types/node@25.9.5)(esbuild@0.28.1))) '@sveltejs/enhanced-img': specifier: ^0.11.0 version: 0.11.0(@sveltejs/vite-plugin-svelte@7.3.0(svelte@5.56.8)(vite@8.2.1(@types/node@25.9.5)(esbuild@0.28.1)))(@types/node@25.9.5)(svelte@5.56.8)(vite@8.2.1(@types/node@25.9.5)(esbuild@0.28.1)) '@sveltejs/kit': specifier: next - version: 3.0.0-next.27(@sveltejs/vite-plugin-svelte@7.3.0(svelte@5.56.8)(vite@8.2.1(@types/node@25.9.5)(esbuild@0.28.1)))(svelte@5.56.8)(typescript@6.0.3)(vite@8.2.1(@types/node@25.9.5)(esbuild@0.28.1)) + version: 3.0.0-next.32(@sveltejs/vite-plugin-svelte@7.3.0(svelte@5.56.8)(vite@8.2.1(@types/node@25.9.5)(esbuild@0.28.1)))(svelte@5.56.8)(typescript@6.0.3)(vite@8.2.1(@types/node@25.9.5)(esbuild@0.28.1)) '@sveltejs/vite-plugin-svelte': specifier: ^7.3.0 version: 7.3.0(svelte@5.56.8)(vite@8.2.1(@types/node@25.9.5)(esbuild@0.28.1)) @@ -147,12 +165,9 @@ importers: postcss-html: specifier: ^1.8.1 version: 1.8.1 - stylelint: - specifier: ~17.15.0 - version: 17.15.0(supports-color@10.2.2)(typescript@6.0.3) stylelint-config-standard: specifier: ~40.0.0 - version: 40.0.0(stylelint@17.15.0(supports-color@10.2.2)(typescript@6.0.3)) + version: 40.0.0(stylelint@17.16.0(supports-color@10.2.2)(typescript@6.0.3)) svelte-check: specifier: ^4.7.5 version: 4.7.6(picomatch@4.0.5)(svelte@5.56.8)(typescript@6.0.3) @@ -179,18 +194,18 @@ packages: '@colordx/core@5.5.0': resolution: {integrity: sha512-3PxTH8itZzltK0U9jTwVVnjLXvnDYuq3m+QXsHkENxWiPRh4WaoLcs1SQjqgZ55kS+QyirpH5BVwzP2gMVG6EQ==} - '@csstools/css-calc@3.3.0': - resolution: {integrity: sha512-c5ihYsPkdG6JCkU2zTMm4+k6r7RXuGxtWYhu5DHMIiF1FHzrfmHL5so11AoFpUv/tu61xfcmT4AmKoFfMPoqdQ==} + '@csstools/css-calc@3.4.3': + resolution: {integrity: sha512-iex20d8CHVkyvg6B7UKV7uHnI2Bqo9g+EFfT9E0y+GvTvhZ/DwONJ+9aKb1dlqm0ZiGsL5RXjp0fCoJYnkeDjA==} engines: {node: '>=20.19.0'} peerDependencies: - '@csstools/css-parser-algorithms': ^4.0.0 - '@csstools/css-tokenizer': ^4.0.0 + '@csstools/css-parser-algorithms': ^4.0.2 + '@csstools/css-tokenizer': ^4.0.2 - '@csstools/css-parser-algorithms@4.0.0': - resolution: {integrity: sha512-+B87qS7fIG3L5h3qwJ/IFbjoVoOe/bpOdh9hAjXbvx0o8ImEmUsGXN0inFOnk2ChCFgqkkGFQ+TpM5rbhkKe4w==} + '@csstools/css-parser-algorithms@4.0.2': + resolution: {integrity: sha512-40cSKyMvK+tq4qz6Awrlye2WGuOKt3FwPgtGg6KTfbHOWNw+Rk1rzbAtZnZ6IBhsY491HLRnDXwoyBAijmmILA==} engines: {node: '>=20.19.0'} peerDependencies: - '@csstools/css-tokenizer': ^4.0.0 + '@csstools/css-tokenizer': ^4.0.2 '@csstools/css-syntax-patches-for-csstree@1.1.14': resolution: {integrity: sha512-HpbVXyrofRXpHpgkNIjU/3EWR4WJvOkO3emNK/L6X/mTJU7bGUI3AkkpoTNXznQLp0KRjLHELTGeKI5dIkI9JQ==} @@ -200,25 +215,37 @@ packages: css-tree: optional: true + '@csstools/css-syntax-patches-for-csstree@1.1.15': + resolution: {integrity: sha512-J0u7HkVl2nzSlhsiTOp4AmwcUQ3D+mGEEKfBy/7To5/y7F2OHwyLrXfrhR0SMgr4p5Lo+eaMVSeai24zUcBIxA==} + peerDependencies: + css-tree: ^3.2.1 + peerDependenciesMeta: + css-tree: + optional: true + '@csstools/css-tokenizer@4.0.0': resolution: {integrity: sha512-QxULHAm7cNu72w97JUNCBFODFaXpbDg+dP8b/oWFAZ2MTRppA3U00Y2L1HqaS4J6yBqxwa/Y3nMBaxVKbB/NsA==} engines: {node: '>=20.19.0'} - '@csstools/media-query-list-parser@5.0.0': - resolution: {integrity: sha512-T9lXmZOfnam3eMERPsszjY5NK0jX8RmThmmm99FZ8b7z8yMaFZWKwLWGZuTwdO3ddRY5fy13GmmEYZXB4I98Eg==} + '@csstools/css-tokenizer@4.0.2': + resolution: {integrity: sha512-OoKoR0f76dCY666JlcbhmVTs2drYj1GUXZTYTcbUgJjh9Nv41aFfZ21bPQTERm5+L5cBDo466NltB2lplS5GBw==} + engines: {node: '>=20.19.0'} + + '@csstools/media-query-list-parser@5.0.2': + resolution: {integrity: sha512-qx19O8AbbLLbDSAcI6YOby/Vq8rV51psgIvlF5OZT/L8fQJDCyQifL6k+kYU4a8ySpzJ4RBzZkIs530bAn8y4Q==} engines: {node: '>=20.19.0'} peerDependencies: - '@csstools/css-parser-algorithms': ^4.0.0 - '@csstools/css-tokenizer': ^4.0.0 + '@csstools/css-parser-algorithms': ^4.0.2 + '@csstools/css-tokenizer': ^4.0.2 - '@csstools/selector-resolve-nested@4.0.1': - resolution: {integrity: sha512-j3vdQu0XwLME5qOTWxm8cnmvsf423R2YL6DbKklCHZwkDm7UdKNu6RPlw4REIJhSlKBICY3B70/7QZdicLqZgg==} + '@csstools/selector-resolve-nested@4.0.2': + resolution: {integrity: sha512-JpjNBJFA+4OnAHKRK4AMp8xrYyLhI9XapOeBlP2PhRU/IylSw+1ep3BFNTksBJnrTS3KT6kqKNVfpzLLwZUW5Q==} engines: {node: '>=20.19.0'} peerDependencies: postcss-selector-parser: ^7.1.1 - '@csstools/selector-specificity@6.0.0': - resolution: {integrity: sha512-4sSgl78OtOXEX/2d++8A83zHNTgwCJMaR24FvsYL7Uf/VS8HZk9PTwR51elTbGqMuwH3szLvvOXEaVnqn0Z3zA==} + '@csstools/selector-specificity@6.0.1': + resolution: {integrity: sha512-MBuqFIIvqk4S593MGAskTkPpEUUzZNvGzh8mMxEwl3oHwjQlXmqHEDxNbN3Y0Tsh+xjmem4GZjeg7I0qkwBivg==} engines: {node: '>=20.19.0'} peerDependencies: postcss-selector-parser: ^7.1.1 @@ -569,6 +596,9 @@ packages: '@jridgewell/sourcemap-codec@1.5.5': resolution: {integrity: sha512-cYQ9310grqxueWbl+WuIUIaiUaDcj7WOq5fVhEljNVgRfOUhY9fy2zTvfoqWsnebh8Sl70VScFbICvJnLKB0Og==} + '@jridgewell/sourcemap-codec@1.6.0': + resolution: {integrity: sha512-T7jf+5zgsZHwNJ4lvQ7/aezbyk0nNX+zJVWpmHA7VYsEx7a7qr5Rg5IbtJFqkgze5Y2sruq1RUY8Q837Od7iFw==} + '@jridgewell/trace-mapping@0.3.31': resolution: {integrity: sha512-zzNR+SdQSDJzc8joaeP8QQoCQr8NuYx2dIIytl1QeBEZHJ9uW6hebsrYgbz8hJwUQao3TWCMtmfV8Nu1twOLAw==} @@ -1055,8 +1085,8 @@ packages: peerDependencies: acorn: ^8.9.0 - '@sveltejs/adapter-netlify@7.0.0-next.11': - resolution: {integrity: sha512-kDMM3oQ791j0pIdv27IxRsrfyl+ItrpBbnGZU/glVh7Hr3/VTbTBNopeP20TZgbJd+xLJKoWdLRDlzyfm1PVxA==} + '@sveltejs/adapter-netlify@7.0.0-next.12': + resolution: {integrity: sha512-AiRCUyFys4SneiNwJpN4l4KMUgbLYXb1AJYc73u7KWJnJz8jZ7jVWUlEC+zsW24+eoD0oCkIHAW6uPnq8ebQVA==} peerDependencies: '@sveltejs/kit': ^3.0.0-next.0 @@ -1067,14 +1097,14 @@ packages: svelte: ^5.0.0 vite: 8.2.1 - '@sveltejs/kit@3.0.0-next.27': - resolution: {integrity: sha512-m2R6GvcMhiAbYVKhzRf5mzLSvcXEuy/H0Va72XvxfEl1ZglrSC/321GKYa6idDHPojuRzkyh9EB0jBZmAwf6+Q==} + '@sveltejs/kit@3.0.0-next.32': + resolution: {integrity: sha512-uzv31kY1++WXeQ18jFKlZ2D/Rr+tkvUH56WEzG8QeGLznEAkIIqSRkZbexHvJ8BdEHW4dJLmjSfDUVrw39rqxw==} engines: {node: '>=22.17'} hasBin: true peerDependencies: '@opentelemetry/api': ^1.0.0 '@sveltejs/vite-plugin-svelte': ^7.0.0 - svelte: ^5.56.4 + svelte: ^5.57.1 typescript: ^6.0.0 vite: 8.2.1 peerDependenciesMeta: @@ -1168,8 +1198,8 @@ packages: resolution: {integrity: sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==} engines: {node: '>=8'} - ansi-regex@6.2.2: - resolution: {integrity: sha512-Bq3SmSpyFHaWjPk8If9yc6svM8c56dB5BAtW4Qbw5jHTwwXXcTLoRMkpDJp6VL0XzlWaCHTXrkFURMYmD0sLqg==} + ansi-regex@6.4.0: + resolution: {integrity: sha512-KzTVk2tCWAHtYrvvvaP8bJKJq2pVinhLcGEQdtLIYPbmNGNyYe8QwNaTUYQp2J7/vIsUKt5QCqAfUkYyG9DkOw==} engines: {node: '>=12'} ansi-styles@4.3.0: @@ -1303,6 +1333,9 @@ packages: devalue@5.9.2: resolution: {integrity: sha512-po4PAY5c53tw5XMocSnf8A/5OHhbbUftpr93aEN6BBoAdntUmK7vu7wOATqvt7cXO7m1Cl4gMVn6p7n6n4mj0w==} + devalue@5.9.4: + resolution: {integrity: sha512-sPAT4pztbu6586/hrhOnMKS17IJrvg12mXiSPSS3W5qDeN2RGgvZ0diZCm31dBbnevfVmujNO3IM2wrS4Y2Rhg==} + devlop@1.1.0: resolution: {integrity: sha512-RWmIqhcFf1lRYBvNmr7qTNuyCt/7/ns2jbpp1+PalgE/rDQcBT0fioSMUpJ93irlUhC5hrg4cYqe6U+0ImW0rA==} @@ -1400,15 +1433,15 @@ packages: resolution: {integrity: sha512-7MptL8U0cqcFdzIzwOTHoilX9x5BrNqye7Z/LuC7kCMRio1EMSyqRK3BEAUD7sXRq4iT4AzTVuZdhgQ2TCvYLg==} engines: {node: '>=8.6.0'} - fast-uri@4.1.5: - resolution: {integrity: sha512-vZeoMRB4epNr7QfdHxel7te/RcX16CxyXI07JCCTFWZA2s4v1azGNESRj+2EoaHSaWFL/Z3GmKT2jF6A202jLg==} + fast-uri@4.2.2: + resolution: {integrity: sha512-EwVpUMzLVNOmcWW0zi5G3JJwkopB6XXjnVvNBGfqrMMsVew2hkQWl5e/pe/CfYUeS6jt4cIO2MnamEW7v/7wPw==} fastest-levenshtein@1.0.16: resolution: {integrity: sha512-eRnCtTTtGZFpQCwhJiUOuxPQWRXVKYDn0b2PeHfXL6/Zi53SLAzAHfVhVWK2AryC/WH05kGfxhFIPvTF0SXQzg==} engines: {node: '>= 4.9.1'} - fastq@1.20.1: - resolution: {integrity: sha512-GGToxJ/w1x32s/D2EKND7kTil4n8OVk/9mycTc4VDza13lOvpUZTGX3mFSCtV9ksdGBVzvsyAVLM6mHFThxXxw==} + fastq@1.20.3: + resolution: {integrity: sha512-XKv5nnLs6nLF71NgiKJLIZFLkPyIEuOselLG7ujZnGrRfQK8HpvY+WqKhAJUAdLomwVHErVS4LfxFlPq0/FTAw==} fdir@6.5.0: resolution: {integrity: sha512-tIbYtZbucOs0BRGqPJkshJUYdL+SDH7dVM8gjy+ERp3WAUjLEFJE+02kanyHtwjWOnwrKYBiwAmM0p4kLJAnXg==} @@ -1445,8 +1478,8 @@ packages: engines: {node: ^8.16.0 || ^10.6.0 || >=11.0.0} os: [darwin] - get-east-asian-width@1.6.0: - resolution: {integrity: sha512-QRbvDIbx6YklUe6RxeTeleMR0yv3cYH6PsPZHcnVn7xv7zO1BHN8r0XETu8n6Ye3Q+ahtSarc3WgtNWmehIBfA==} + get-east-asian-width@1.7.0: + resolution: {integrity: sha512-XjH1AECxf0giL2V1aU8vKyRR2ppRUb5c0EvT7zuJTokQ74bNo52zOtghqdWIqrhUD79fo3x0WfKZdOqxF6LG1Q==} engines: {node: '>=18'} github-slugger@2.0.0: @@ -1507,8 +1540,8 @@ packages: htmlparser2@8.0.2: resolution: {integrity: sha512-GYdjWKDkbRLkZ5geuHs5NY1puJ+PXwP7+fHPRz06Eirsb9ugf6d8kkXav6ADhcODhFFPMIXyxkxSuMf3D6NCFA==} - ignore@7.0.6: - resolution: {integrity: sha512-BAg6QkE8W+TuQLrrw0Ugr7HegXduRuuj8/ti2kSOc+jz1dmx8/WNcjr6XGnq5YpDWxFwwaavqD0+jIUOKelTsw==} + ignore@7.0.12: + resolution: {integrity: sha512-/8UvqAPU9DGTI9k4mxtf49U37Isfwr8Uts96+SBHIkFxPJnHS0Ew4f00sM4Scd8V8EjM0jUNtVDdv1kPdt35lg==} engines: {node: '>= 4'} imagetools-core@9.1.0: @@ -1686,6 +1719,9 @@ packages: magic-string@1.1.0: resolution: {integrity: sha512-kS3VHe0nEPST2saQV4Rbkchcd3UBRkVTQHo1D3h/ZTwFDhai/mfKkmtPAtD129EOI7K3HlHIsFOt0WrI2/oU9g==} + magic-string@1.4.3: + resolution: {integrity: sha512-z12OxmaPGE0F4xlpGdjuAUckipLpQlTAuAmyGhNoD7ODpYUzvDfvtxUbjM/jwznyP178oju/KDdyi220wNJ0RQ==} + mathml-tag-names@4.0.0: resolution: {integrity: sha512-aa6AU2Pcx0VP/XWnh8IGL0SYSgQHDT6Ucror2j2mXeFAlN3ahaNs8EZtG1YiticMkSLj3Gt6VPFfZogt7G5iFQ==} @@ -1720,8 +1756,8 @@ packages: ms@2.1.3: resolution: {integrity: sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==} - nanoid@3.3.18: - resolution: {integrity: sha512-DTg4MJbGMWkfi6VZFdNt2/caMbQy4Ou+Op/hJQvGEWcnVfoA1QA+xzRKAzw9jD6+GVOOeYr/mIcuDSdug6F6+w==} + nanoid@3.3.20: + resolution: {integrity: sha512-uKdg2G3GNCKQn9byYOpxbGqrT2fGO5KRt5J/8b3pok8rT6qxGWF6hxMyJiEYtAf+FVyYuD9hRaDqX5uPFYJ4ZQ==} engines: {node: ^10 || ^12 || ^13.7 || ^14 || >=15.0.1} hasBin: true @@ -1799,6 +1835,10 @@ packages: resolution: {integrity: sha512-RvwwcruNjI1ncT5xRakeyS9Lf8lcItv34KD+aif+VH9kduAyfYBipGh12274xtenIPZ119/R9BdTBa8gAwSh0A==} engines: {node: '>=12'} + picomatch@4.0.7: + resolution: {integrity: sha512-qcJu88Q2IWqJsDD529JKMdwGm/dvInW4HvQnRwiH9JtihJvzGOscDtHE3x1pBKeUOTysQ8kVmLnJ2kJu7yhcGA==} + engines: {node: '>=12'} + playwright-core@1.62.0: resolution: {integrity: sha512-nsNRyq0r2zsG8AcRHWknc9QRA5XCueC7gWMrs+Gx2tlZn9hcl8zudfh00lhJPY1DE7NmZ6bDsT9g2yey8mXljA==} engines: {node: '>=20'} @@ -1819,25 +1859,21 @@ packages: peerDependencies: postcss: ^8.3.3 - postcss-safe-parser@7.0.1: - resolution: {integrity: sha512-0AioNCJZ2DPYz5ABT6bddIqlhgwhpHZ/l65YAYo0BCIn0xiDpsnTHz0gnoTGk0OXZW0JRs+cDwL8u/teRdz+8A==} + postcss-safe-parser@7.1.0: + resolution: {integrity: sha512-1WzZxRLaAFwEh6Do+zyGpjWV3nGJNxxhuh7Ubu/q1ICImMgZJnLwhoaEpRbG4pJppp2Y1ncL9ffA2f+LhrefQg==} engines: {node: '>=18.0'} peerDependencies: postcss: ^8.4.31 - postcss-selector-parser@7.1.5: - resolution: {integrity: sha512-KvvtD7SrlBP7dlgkBghEE3r84CABm5SmV2aNcG4oCA+qDnJ/tvKonFVvwWAyyWUEwxuNawdfEAZKP9zM3oZ2Uw==} + postcss-selector-parser@7.1.6: + resolution: {integrity: sha512-7qASPzhKF2l2KLboRZux8CCTRMdGiV08vWmyKzPz22qZ7ZjQBOeY7rNzNoCLSUiftJ7HUq0GERHmxw/t0dCdMw==} engines: {node: '>=4'} postcss-value-parser@4.2.0: resolution: {integrity: sha512-1NNCs6uurfkVbeXG4S8JFT9t19m45ICnif8zWLd5oPSZ50QnwMfK+H3jv408d4jw/7Bttv5axS5IiHoLaVNHeQ==} - postcss@8.5.23: - resolution: {integrity: sha512-g50586zr4bZmwFiTlflMu8E0bDTb5I5gertgwAKmsdUlTQIhZtunzUlD1WSzwcVWPoAVpsrA6vlfCD7oXvRwgg==} - engines: {node: ^10 || ^12 || >=14} - - postcss@8.5.26: - resolution: {integrity: sha512-u82N74LFzG8ca+dD8puPnplTXoGH4fTPpVGuIbt36G3qvNlkvfD0lEAZSxaly3KX8TS/L1A1gsCEmvKmBcVbkQ==} + postcss@8.5.30: + resolution: {integrity: sha512-zkd+e9S1AQHhmaBKye9zlFHWjOwVgqXl1q3ECYy8561K7qxR2cREf/STLskulBFd78k6AOFeA+ff1TtEzk9bAA==} engines: {node: ^10 || ^12 || >=14} prism-svelte@0.4.7: @@ -1936,14 +1972,14 @@ packages: resolution: {integrity: sha512-qMCMfhY040cVHT43K9BFygqYbUPFZKHOg7K73mtTWJRb8pyP3fzf4Ixd5SzdEJQ6MRUg/WBnOLxghZtKKurENQ==} engines: {node: '>=10'} - smol-toml@1.8.0: - resolution: {integrity: sha512-kCZr2V3ch9i00x8zXRhjUNVcjG9ijES5dDudkXvUVCT5QlJNQWElSJdZqyPemffHoLNUYwOcou0Fy+ojN0uHSQ==} - engines: {node: '>= 18'} - source-map-js@1.2.1: resolution: {integrity: sha512-UXWMKhLOwVKb728IUtQPXxfYU+usdybtUrK/8uGE8CQMvrhOpwvzDBwj0QhSL7MQc7vIsISBG8VQ8+IDQxpfQA==} engines: {node: '>=0.10.0'} + source-map-js@1.2.2: + resolution: {integrity: sha512-KGj/8Y43x35aZVDtt+J4mK1hoLGHULMYfSkODJNQjNDC3oW1PqPoxMwo0pLUsWM/UEGzON/NxeHywEfNXNP3Vw==} + engines: {node: '>=0.10.0'} + stackback@0.0.2: resolution: {integrity: sha512-1XMJE5fQo1jGH6Y/7ebnwPOBEkIEnT4QF32d5R1+VXdXveM0IBMJt8zfaxX1P3QhVwrYe+576+jkANtSS2mBbw==} @@ -1954,8 +1990,8 @@ packages: resolution: {integrity: sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==} engines: {node: '>=8'} - string-width@8.2.2: - resolution: {integrity: sha512-GaPUh5gfdrYzqeVNZvUfT23vYYxXzKYidUcnMtJg/3rxRV63EFZy3k6xfKlmfeJD0176lnUV/Usr3XcwSvFzpg==} + string-width@8.3.0: + resolution: {integrity: sha512-ZbmZM0JCihQN91dWnxoipT2KOEyHqEyfRXUyjuRhW8b/xnqPDoq4gWEVApTVa9db2wN8mmoikgFBbjh71+cGeQ==} engines: {node: '>=20'} strip-ansi@6.0.1: @@ -1981,8 +2017,8 @@ packages: peerDependencies: stylelint: ^17.0.0 - stylelint@17.15.0: - resolution: {integrity: sha512-mWIkesYQvQjf4Kvdeu9ns0IL8/K/wtjaGxPqsPd6DlLZvaQxGysJsocxUDrBcyHQ5VleAk4uSMat4yMrVED7PA==} + stylelint@17.16.0: + resolution: {integrity: sha512-ejlWnbJ13x1GU32+zZXa6sYQJsKKkwSdv2B4rAdO3OWdEmvhSJKcXi5pOphQYSzyaj1kXpuGJr7pcMBNfDIuPw==} engines: {node: '>=20.19.0'} hasBin: true @@ -1990,8 +2026,8 @@ packages: resolution: {integrity: sha512-SS+jx45GF1QjgEXQx4NJZV9ImqmO2NPz5FNsIHrsDjh2YsHnawpan7SNQ1o8NuhrbHZy9AZhIoCUiCeaW/C80g==} engines: {node: '>=18'} - supports-hyperlinks@4.5.0: - resolution: {integrity: sha512-ZW2OvfeCXrNTbLakPUzjQG922EeGCOteFSVoek5DKStTh898wf7zgtuFlzQN8HfZCxC3Eh02yJVrRW51hADf+w==} + supports-hyperlinks@4.6.0: + resolution: {integrity: sha512-FL/q/YePS4tFFTNiBOR+zPk2ZrKheqNtmTJ/9OUZ4e1wKHJofDbGQSmSsxS0XNnabSkqexryCaXGvEKz1vf9UQ==} engines: {node: '>=20'} svelte-check@4.7.6: @@ -2071,8 +2107,8 @@ packages: undici-types@7.24.6: resolution: {integrity: sha512-WRNW+sJgj5OBN4/0JpHFqtqzhpbnV0GuB+OozA9gCL7a993SmU+1JBZCzLNxYsbMfIeDL+lTsphD5jN5N+n0zg==} - unicorn-magic@0.4.0: - resolution: {integrity: sha512-wH590V9VNgYH9g3lH9wWjTrUoKsjLF6sGLjhR4sH1LWpLmCOH0Zf7PukhDA8BiS7KHe4oPNkcTHqYkj7SOGUOw==} + unicorn-magic@0.4.1: + resolution: {integrity: sha512-lzlXPoVB0Uy/FvTaUgX39RbixYiSKoc3JSoSf01+0c2B6FR3qdYIPN7Qjo/AV7n6sqLCk0509cT3LRj1oSZ1+A==} engines: {node: '>=20'} unified@11.0.5: @@ -2253,33 +2289,39 @@ snapshots: '@colordx/core@5.5.0': {} - '@csstools/css-calc@3.3.0(@csstools/css-parser-algorithms@4.0.0(@csstools/css-tokenizer@4.0.0))(@csstools/css-tokenizer@4.0.0)': + '@csstools/css-calc@3.4.3(@csstools/css-parser-algorithms@4.0.2(@csstools/css-tokenizer@4.0.2))(@csstools/css-tokenizer@4.0.2)': dependencies: - '@csstools/css-parser-algorithms': 4.0.0(@csstools/css-tokenizer@4.0.0) - '@csstools/css-tokenizer': 4.0.0 + '@csstools/css-parser-algorithms': 4.0.2(@csstools/css-tokenizer@4.0.2) + '@csstools/css-tokenizer': 4.0.2 - '@csstools/css-parser-algorithms@4.0.0(@csstools/css-tokenizer@4.0.0)': + '@csstools/css-parser-algorithms@4.0.2(@csstools/css-tokenizer@4.0.2)': dependencies: - '@csstools/css-tokenizer': 4.0.0 + '@csstools/css-tokenizer': 4.0.2 '@csstools/css-syntax-patches-for-csstree@1.1.14(css-tree@3.2.1)': optionalDependencies: css-tree: 3.2.1 + '@csstools/css-syntax-patches-for-csstree@1.1.15(css-tree@3.2.1)': + optionalDependencies: + css-tree: 3.2.1 + '@csstools/css-tokenizer@4.0.0': {} - '@csstools/media-query-list-parser@5.0.0(@csstools/css-parser-algorithms@4.0.0(@csstools/css-tokenizer@4.0.0))(@csstools/css-tokenizer@4.0.0)': + '@csstools/css-tokenizer@4.0.2': {} + + '@csstools/media-query-list-parser@5.0.2(@csstools/css-parser-algorithms@4.0.2(@csstools/css-tokenizer@4.0.2))(@csstools/css-tokenizer@4.0.2)': dependencies: - '@csstools/css-parser-algorithms': 4.0.0(@csstools/css-tokenizer@4.0.0) - '@csstools/css-tokenizer': 4.0.0 + '@csstools/css-parser-algorithms': 4.0.2(@csstools/css-tokenizer@4.0.2) + '@csstools/css-tokenizer': 4.0.2 - '@csstools/selector-resolve-nested@4.0.1(postcss-selector-parser@7.1.5)': + '@csstools/selector-resolve-nested@4.0.2(postcss-selector-parser@7.1.6)': dependencies: - postcss-selector-parser: 7.1.5 + postcss-selector-parser: 7.1.6 - '@csstools/selector-specificity@6.0.0(postcss-selector-parser@7.1.5)': + '@csstools/selector-specificity@6.0.1(postcss-selector-parser@7.1.6)': dependencies: - postcss-selector-parser: 7.1.5 + postcss-selector-parser: 7.1.6 '@emnapi/runtime@1.11.3': dependencies: @@ -2499,6 +2541,8 @@ snapshots: '@jridgewell/sourcemap-codec@1.5.5': {} + '@jridgewell/sourcemap-codec@1.6.0': {} + '@jridgewell/trace-mapping@0.3.31': dependencies: '@jridgewell/resolve-uri': 3.1.2 @@ -2541,7 +2585,7 @@ snapshots: '@nodelib/fs.walk@1.2.8': dependencies: '@nodelib/fs.scandir': 2.1.5 - fastq: 1.20.1 + fastq: 1.20.3 '@oddbird/popover-polyfill@0.6.1': {} @@ -2722,11 +2766,11 @@ snapshots: dependencies: oxlint: 1.75.0(oxlint-tsgolint@0.23.0) - '@projectwallace/stylelint-plugin@0.7.0(stylelint@17.15.0(supports-color@10.2.2)(typescript@6.0.3))': + '@projectwallace/stylelint-plugin@0.7.0(stylelint@17.16.0(supports-color@10.2.2)(typescript@6.0.3))': dependencies: '@projectwallace/css-analyzer': 9.9.3 '@projectwallace/css-parser': 0.18.6 - stylelint: 17.15.0(supports-color@10.2.2)(typescript@6.0.3) + stylelint: 17.16.0(supports-color@10.2.2)(typescript@6.0.3) '@rolldown/binding-android-arm64@1.2.3': optional: true @@ -2776,7 +2820,7 @@ snapshots: dependencies: '@types/estree': 1.0.9 estree-walker: 2.0.2 - picomatch: 4.0.5 + picomatch: 4.0.7 '@sindresorhus/merge-streams@4.0.0': {} @@ -2786,12 +2830,11 @@ snapshots: dependencies: acorn: 8.17.0 - '@sveltejs/adapter-netlify@7.0.0-next.11(@sveltejs/kit@3.0.0-next.27(@sveltejs/vite-plugin-svelte@7.3.0(svelte@5.56.8)(vite@8.2.1(@types/node@25.9.5)(esbuild@0.28.1)))(svelte@5.56.8)(typescript@6.0.3)(vite@8.2.1(@types/node@25.9.5)(esbuild@0.28.1)))': + '@sveltejs/adapter-netlify@7.0.0-next.12(@sveltejs/kit@3.0.0-next.32(@sveltejs/vite-plugin-svelte@7.3.0(svelte@5.56.8)(vite@8.2.1(@types/node@25.9.5)(esbuild@0.28.1)))(svelte@5.56.8)(typescript@6.0.3)(vite@8.2.1(@types/node@25.9.5)(esbuild@0.28.1)))': dependencies: '@netlify/types': 2.8.0 - '@sveltejs/kit': 3.0.0-next.27(@sveltejs/vite-plugin-svelte@7.3.0(svelte@5.56.8)(vite@8.2.1(@types/node@25.9.5)(esbuild@0.28.1)))(svelte@5.56.8)(typescript@6.0.3)(vite@8.2.1(@types/node@25.9.5)(esbuild@0.28.1)) + '@sveltejs/kit': 3.0.0-next.32(@sveltejs/vite-plugin-svelte@7.3.0(svelte@5.56.8)(vite@8.2.1(@types/node@25.9.5)(esbuild@0.28.1)))(svelte@5.56.8)(typescript@6.0.3)(vite@8.2.1(@types/node@25.9.5)(esbuild@0.28.1)) rolldown: 1.2.3 - smol-toml: 1.8.0 '@sveltejs/enhanced-img@0.11.0(@sveltejs/vite-plugin-svelte@7.3.0(svelte@5.56.8)(vite@8.2.1(@types/node@25.9.5)(esbuild@0.28.1)))(@types/node@25.9.5)(svelte@5.56.8)(vite@8.2.1(@types/node@25.9.5)(esbuild@0.28.1))': dependencies: @@ -2807,15 +2850,15 @@ snapshots: - '@types/node' - rollup - '@sveltejs/kit@3.0.0-next.27(@sveltejs/vite-plugin-svelte@7.3.0(svelte@5.56.8)(vite@8.2.1(@types/node@25.9.5)(esbuild@0.28.1)))(svelte@5.56.8)(typescript@6.0.3)(vite@8.2.1(@types/node@25.9.5)(esbuild@0.28.1))': + '@sveltejs/kit@3.0.0-next.32(@sveltejs/vite-plugin-svelte@7.3.0(svelte@5.56.8)(vite@8.2.1(@types/node@25.9.5)(esbuild@0.28.1)))(svelte@5.56.8)(typescript@6.0.3)(vite@8.2.1(@types/node@25.9.5)(esbuild@0.28.1))': dependencies: '@rolldown/pluginutils': 1.0.1 '@standard-schema/spec': 1.1.0 '@sveltejs/vite-plugin-svelte': 7.3.0(svelte@5.56.8)(vite@8.2.1(@types/node@25.9.5)(esbuild@0.28.1)) cookie: 2.0.1 - devalue: 5.9.2 + devalue: 5.9.4 esm-env: 1.2.2 - magic-string: 1.1.0 + magic-string: 1.4.3 mrmime: 2.0.1 sirv: 3.0.2 svelte: 5.56.8 @@ -2913,13 +2956,13 @@ snapshots: ajv@8.20.0: dependencies: fast-deep-equal: 3.1.3 - fast-uri: 4.1.5 + fast-uri: 4.2.2 json-schema-traverse: 1.0.0 require-from-string: 2.0.2 ansi-regex@5.0.1: {} - ansi-regex@6.2.2: {} + ansi-regex@6.4.0: {} ansi-styles@4.3.0: dependencies: @@ -3021,6 +3064,8 @@ snapshots: devalue@5.9.2: {} + devalue@5.9.4: {} + devlop@1.1.0: dependencies: dequal: 2.0.3 @@ -3135,11 +3180,11 @@ snapshots: merge2: 1.4.1 micromatch: 4.0.8 - fast-uri@4.1.5: {} + fast-uri@4.2.2: {} fastest-levenshtein@1.0.16: {} - fastq@1.20.1: + fastq@1.20.3: dependencies: reusify: 1.1.0 @@ -3173,7 +3218,7 @@ snapshots: fsevents@2.3.3: optional: true - get-east-asian-width@1.6.0: {} + get-east-asian-width@1.7.0: {} github-slugger@2.0.0: {} @@ -3195,11 +3240,11 @@ snapshots: dependencies: '@sindresorhus/merge-streams': 4.0.0 fast-glob: 3.3.3 - ignore: 7.0.6 + ignore: 7.0.12 is-path-inside: 4.0.0 micromatch: 4.0.8 slash: 5.1.0 - unicorn-magic: 0.4.0 + unicorn-magic: 0.4.1 globjoin@0.1.4: {} @@ -3243,7 +3288,7 @@ snapshots: domutils: 3.2.2 entities: 4.5.0 - ignore@7.0.6: {} + ignore@7.0.12: {} imagetools-core@9.1.0: {} @@ -3371,6 +3416,10 @@ snapshots: dependencies: '@jridgewell/sourcemap-codec': 1.5.5 + magic-string@1.4.3: + dependencies: + '@jridgewell/sourcemap-codec': 1.6.0 + mathml-tag-names@4.0.0: {} mdn-data@2.27.1: {} @@ -3400,7 +3449,7 @@ snapshots: ms@2.1.3: {} - nanoid@3.3.18: {} + nanoid@3.3.20: {} nanoid@5.1.16: {} @@ -3469,11 +3518,11 @@ snapshots: '@oxlint/binding-win32-x64-msvc': 1.75.0 oxlint-tsgolint: 0.23.0 - paneforge@1.0.2(@sveltejs/kit@3.0.0-next.27(@sveltejs/vite-plugin-svelte@7.3.0(svelte@5.56.8)(vite@8.2.1(@types/node@25.9.5)(esbuild@0.28.1)))(svelte@5.56.8)(typescript@6.0.3)(vite@8.2.1(@types/node@25.9.5)(esbuild@0.28.1)))(svelte@5.56.8): + paneforge@1.0.2(@sveltejs/kit@3.0.0-next.32(@sveltejs/vite-plugin-svelte@7.3.0(svelte@5.56.8)(vite@8.2.1(@types/node@25.9.5)(esbuild@0.28.1)))(svelte@5.56.8)(typescript@6.0.3)(vite@8.2.1(@types/node@25.9.5)(esbuild@0.28.1)))(svelte@5.56.8): dependencies: - runed: 0.37.1(@sveltejs/kit@3.0.0-next.27(@sveltejs/vite-plugin-svelte@7.3.0(svelte@5.56.8)(vite@8.2.1(@types/node@25.9.5)(esbuild@0.28.1)))(svelte@5.56.8)(typescript@6.0.3)(vite@8.2.1(@types/node@25.9.5)(esbuild@0.28.1)))(svelte@5.56.8) + runed: 0.37.1(@sveltejs/kit@3.0.0-next.32(@sveltejs/vite-plugin-svelte@7.3.0(svelte@5.56.8)(vite@8.2.1(@types/node@25.9.5)(esbuild@0.28.1)))(svelte@5.56.8)(typescript@6.0.3)(vite@8.2.1(@types/node@25.9.5)(esbuild@0.28.1)))(svelte@5.56.8) svelte: 5.56.8 - svelte-toolbelt: 0.9.3(@sveltejs/kit@3.0.0-next.27(@sveltejs/vite-plugin-svelte@7.3.0(svelte@5.56.8)(vite@8.2.1(@types/node@25.9.5)(esbuild@0.28.1)))(svelte@5.56.8)(typescript@6.0.3)(vite@8.2.1(@types/node@25.9.5)(esbuild@0.28.1)))(svelte@5.56.8) + svelte-toolbelt: 0.9.3(@sveltejs/kit@3.0.0-next.32(@sveltejs/vite-plugin-svelte@7.3.0(svelte@5.56.8)(vite@8.2.1(@types/node@25.9.5)(esbuild@0.28.1)))(svelte@5.56.8)(typescript@6.0.3)(vite@8.2.1(@types/node@25.9.5)(esbuild@0.28.1)))(svelte@5.56.8) transitivePeerDependencies: - '@sveltejs/kit' - zod @@ -3497,6 +3546,8 @@ snapshots: picomatch@4.0.5: {} + picomatch@4.0.7: {} + playwright-core@1.62.0: {} playwright@1.62.0: @@ -3509,35 +3560,29 @@ snapshots: dependencies: htmlparser2: 8.0.2 js-tokens: 9.0.1 - postcss: 8.5.23 - postcss-safe-parser: 6.0.0(postcss@8.5.23) + postcss: 8.5.30 + postcss-safe-parser: 6.0.0(postcss@8.5.30) - postcss-safe-parser@6.0.0(postcss@8.5.23): + postcss-safe-parser@6.0.0(postcss@8.5.30): dependencies: - postcss: 8.5.23 + postcss: 8.5.30 - postcss-safe-parser@7.0.1(postcss@8.5.26): + postcss-safe-parser@7.1.0(postcss@8.5.30): dependencies: - postcss: 8.5.26 + postcss: 8.5.30 - postcss-selector-parser@7.1.5: + postcss-selector-parser@7.1.6: dependencies: cssesc: 3.0.0 util-deprecate: 1.0.2 postcss-value-parser@4.2.0: {} - postcss@8.5.23: - dependencies: - nanoid: 3.3.18 - picocolors: 1.1.1 - source-map-js: 1.2.1 - - postcss@8.5.26: + postcss@8.5.30: dependencies: - nanoid: 3.3.18 + nanoid: 3.3.20 picocolors: 1.1.1 - source-map-js: 1.2.1 + source-map-js: 1.2.2 prism-svelte@0.4.7: {} @@ -3600,14 +3645,14 @@ snapshots: dependencies: queue-microtask: 1.2.3 - runed@0.37.1(@sveltejs/kit@3.0.0-next.27(@sveltejs/vite-plugin-svelte@7.3.0(svelte@5.56.8)(vite@8.2.1(@types/node@25.9.5)(esbuild@0.28.1)))(svelte@5.56.8)(typescript@6.0.3)(vite@8.2.1(@types/node@25.9.5)(esbuild@0.28.1)))(svelte@5.56.8): + runed@0.37.1(@sveltejs/kit@3.0.0-next.32(@sveltejs/vite-plugin-svelte@7.3.0(svelte@5.56.8)(vite@8.2.1(@types/node@25.9.5)(esbuild@0.28.1)))(svelte@5.56.8)(typescript@6.0.3)(vite@8.2.1(@types/node@25.9.5)(esbuild@0.28.1)))(svelte@5.56.8): dependencies: dequal: 2.0.3 esm-env: 1.2.2 lz-string: 1.5.0 svelte: 5.56.8 optionalDependencies: - '@sveltejs/kit': 3.0.0-next.27(@sveltejs/vite-plugin-svelte@7.3.0(svelte@5.56.8)(vite@8.2.1(@types/node@25.9.5)(esbuild@0.28.1)))(svelte@5.56.8)(typescript@6.0.3)(vite@8.2.1(@types/node@25.9.5)(esbuild@0.28.1)) + '@sveltejs/kit': 3.0.0-next.32(@sveltejs/vite-plugin-svelte@7.3.0(svelte@5.56.8)(vite@8.2.1(@types/node@25.9.5)(esbuild@0.28.1)))(svelte@5.56.8)(typescript@6.0.3)(vite@8.2.1(@types/node@25.9.5)(esbuild@0.28.1)) sade@1.8.1: dependencies: @@ -3666,10 +3711,10 @@ snapshots: astral-regex: 2.0.0 is-fullwidth-code-point: 3.0.0 - smol-toml@1.8.0: {} - source-map-js@1.2.1: {} + source-map-js@1.2.2: {} + stackback@0.0.2: {} std-env@4.2.0: {} @@ -3680,9 +3725,9 @@ snapshots: is-fullwidth-code-point: 3.0.0 strip-ansi: 6.0.1 - string-width@8.2.2: + string-width@8.3.0: dependencies: - get-east-asian-width: 1.6.0 + get-east-asian-width: 1.7.0 strip-ansi: 7.2.0 strip-ansi@6.0.1: @@ -3691,30 +3736,30 @@ snapshots: strip-ansi@7.2.0: dependencies: - ansi-regex: 6.2.2 + ansi-regex: 6.4.0 style-to-object@1.0.14: dependencies: inline-style-parser: 0.2.7 - stylelint-config-recommended@18.0.0(stylelint@17.15.0(supports-color@10.2.2)(typescript@6.0.3)): + stylelint-config-recommended@18.0.0(stylelint@17.16.0(supports-color@10.2.2)(typescript@6.0.3)): dependencies: - stylelint: 17.15.0(supports-color@10.2.2)(typescript@6.0.3) + stylelint: 17.16.0(supports-color@10.2.2)(typescript@6.0.3) - stylelint-config-standard@40.0.0(stylelint@17.15.0(supports-color@10.2.2)(typescript@6.0.3)): + stylelint-config-standard@40.0.0(stylelint@17.16.0(supports-color@10.2.2)(typescript@6.0.3)): dependencies: - stylelint: 17.15.0(supports-color@10.2.2)(typescript@6.0.3) - stylelint-config-recommended: 18.0.0(stylelint@17.15.0(supports-color@10.2.2)(typescript@6.0.3)) + stylelint: 17.16.0(supports-color@10.2.2)(typescript@6.0.3) + stylelint-config-recommended: 18.0.0(stylelint@17.16.0(supports-color@10.2.2)(typescript@6.0.3)) - stylelint@17.15.0(supports-color@10.2.2)(typescript@6.0.3): + stylelint@17.16.0(supports-color@10.2.2)(typescript@6.0.3): dependencies: - '@csstools/css-calc': 3.3.0(@csstools/css-parser-algorithms@4.0.0(@csstools/css-tokenizer@4.0.0))(@csstools/css-tokenizer@4.0.0) - '@csstools/css-parser-algorithms': 4.0.0(@csstools/css-tokenizer@4.0.0) - '@csstools/css-syntax-patches-for-csstree': 1.1.14(css-tree@3.2.1) - '@csstools/css-tokenizer': 4.0.0 - '@csstools/media-query-list-parser': 5.0.0(@csstools/css-parser-algorithms@4.0.0(@csstools/css-tokenizer@4.0.0))(@csstools/css-tokenizer@4.0.0) - '@csstools/selector-resolve-nested': 4.0.1(postcss-selector-parser@7.1.5) - '@csstools/selector-specificity': 6.0.0(postcss-selector-parser@7.1.5) + '@csstools/css-calc': 3.4.3(@csstools/css-parser-algorithms@4.0.2(@csstools/css-tokenizer@4.0.2))(@csstools/css-tokenizer@4.0.2) + '@csstools/css-parser-algorithms': 4.0.2(@csstools/css-tokenizer@4.0.2) + '@csstools/css-syntax-patches-for-csstree': 1.1.15(css-tree@3.2.1) + '@csstools/css-tokenizer': 4.0.2 + '@csstools/media-query-list-parser': 5.0.2(@csstools/css-parser-algorithms@4.0.2(@csstools/css-tokenizer@4.0.2))(@csstools/css-tokenizer@4.0.2) + '@csstools/selector-resolve-nested': 4.0.2(postcss-selector-parser@7.1.6) + '@csstools/selector-specificity': 6.0.1(postcss-selector-parser@7.1.6) colord: 2.10.0 cosmiconfig: 9.0.2(typescript@6.0.3) css-functions-list: 3.3.3 @@ -3727,19 +3772,19 @@ snapshots: globby: 16.2.4 globjoin: 0.1.4 html-tags: 5.1.0 - ignore: 7.0.6 + ignore: 7.0.12 import-meta-resolve: 4.2.0 mathml-tag-names: 4.0.0 meow: 14.1.0 micromatch: 4.0.8 normalize-path: 3.0.0 picocolors: 1.1.1 - postcss: 8.5.26 - postcss-safe-parser: 7.0.1(postcss@8.5.26) - postcss-selector-parser: 7.1.5 + postcss: 8.5.30 + postcss-safe-parser: 7.1.0(postcss@8.5.30) + postcss-selector-parser: 7.1.6 postcss-value-parser: 4.2.0 - string-width: 8.2.2 - supports-hyperlinks: 4.5.0 + string-width: 8.3.0 + supports-hyperlinks: 4.6.0 svg-tags: 1.0.0 table: 6.9.0 write-file-atomic: 7.0.1 @@ -3749,7 +3794,7 @@ snapshots: supports-color@10.2.2: {} - supports-hyperlinks@4.5.0: + supports-hyperlinks@4.6.0: dependencies: has-flag: 5.0.1 supports-color: 10.2.2 @@ -3771,10 +3816,10 @@ snapshots: dependencies: svelte: 5.56.8 - svelte-toolbelt@0.9.3(@sveltejs/kit@3.0.0-next.27(@sveltejs/vite-plugin-svelte@7.3.0(svelte@5.56.8)(vite@8.2.1(@types/node@25.9.5)(esbuild@0.28.1)))(svelte@5.56.8)(typescript@6.0.3)(vite@8.2.1(@types/node@25.9.5)(esbuild@0.28.1)))(svelte@5.56.8): + svelte-toolbelt@0.9.3(@sveltejs/kit@3.0.0-next.32(@sveltejs/vite-plugin-svelte@7.3.0(svelte@5.56.8)(vite@8.2.1(@types/node@25.9.5)(esbuild@0.28.1)))(svelte@5.56.8)(typescript@6.0.3)(vite@8.2.1(@types/node@25.9.5)(esbuild@0.28.1)))(svelte@5.56.8): dependencies: clsx: 2.1.1 - runed: 0.37.1(@sveltejs/kit@3.0.0-next.27(@sveltejs/vite-plugin-svelte@7.3.0(svelte@5.56.8)(vite@8.2.1(@types/node@25.9.5)(esbuild@0.28.1)))(svelte@5.56.8)(typescript@6.0.3)(vite@8.2.1(@types/node@25.9.5)(esbuild@0.28.1)))(svelte@5.56.8) + runed: 0.37.1(@sveltejs/kit@3.0.0-next.32(@sveltejs/vite-plugin-svelte@7.3.0(svelte@5.56.8)(vite@8.2.1(@types/node@25.9.5)(esbuild@0.28.1)))(svelte@5.56.8)(typescript@6.0.3)(vite@8.2.1(@types/node@25.9.5)(esbuild@0.28.1)))(svelte@5.56.8) style-to-object: 1.0.14 svelte: 5.56.8 transitivePeerDependencies: @@ -3843,7 +3888,7 @@ snapshots: undici-types@7.24.6: {} - unicorn-magic@0.4.0: {} + unicorn-magic@0.4.1: {} unified@11.0.5: dependencies: @@ -3921,7 +3966,7 @@ snapshots: dependencies: lightningcss: 1.32.0 picomatch: 4.0.5 - postcss: 8.5.26 + postcss: 8.5.30 rolldown: 1.2.3 tinyglobby: 0.2.17 optionalDependencies: diff --git a/src/lib/components/Linter.svelte b/src/lib/components/Linter.svelte index c6cdfd3a..69b09ca0 100644 --- a/src/lib/components/Linter.svelte +++ b/src/lib/components/Linter.svelte @@ -13,6 +13,11 @@ import { presets, type Preset, DEFAULT_PRESET } from '#lib/lint-preset.ts' import PanedLayout from './PanedLayout.svelte' import Pane from './Pane.svelte' + import { get_css } from '#lib/get-css.ts' + import { format } from '@projectwallace/format-css' + import stylelintPlugin from '@projectwallace/stylelint-plugin' + import { lint } from '#lib/stylelint-browser/lint.ts' + import { PRESET_MAP } from '#lib/stylelint-browser/presets.ts' let { elements: { root, item } @@ -28,7 +33,6 @@ } duration: number css?: string - rules?: Record } type Props = { @@ -69,21 +73,43 @@ status = 'loading' onloading?.(true) try { - const body = url ? { url, preset, prettify } : { css, preset } - const response = await fetch('/api/lint-css', { - method: 'POST', - headers: { 'Content-Type': 'application/json' }, - body: JSON.stringify(body) - }) - if (response.ok) { - lint_result = await response.json() - if (lint_result?.css) { - api_css = lint_result.css + let text: string + if (url) { + const origins = await get_css(url) + text = origins.map((o) => o.css).join('\n') + if (prettify) { + text = format(text) } - status = lint_result?.result.parse_error ? 'lint_error' : 'success' + api_css = text } else { - status = 'error' + text = css + } + + const start = performance.now() + const linter_result = await lint([{ id: url ?? 'input.css', code: text }], { + plugins: stylelintPlugin, + rules: PRESET_MAP[preset] + }) + const duration = performance.now() - start + + const file = linter_result.results.at(0) + if (!file) { + throw new Error('No lint result') + } + + const lint_warnings = file.warnings.filter((w) => w.rule !== 'CssSyntaxError') + const parse_error = file.warnings.find((w) => w.rule === 'CssSyntaxError') + + lint_result = { + result: { + errored: file.invalidOptionWarnings.length > 0 || lint_warnings.some((w) => w.severity === 'error'), + parse_error, + warnings: lint_warnings.toSorted((a, b) => (a.line === b.line ? a.column - b.column : a.line - b.line)) + }, + duration: parseFloat(duration.toFixed(1)), + css: url ? text : undefined } + status = lint_result.result.parse_error ? 'lint_error' : 'success' } catch { status = 'error' } finally { diff --git a/src/lib/stylelint-browser/lint.test.ts b/src/lib/stylelint-browser/lint.test.ts new file mode 100644 index 00000000..8d168b7f --- /dev/null +++ b/src/lib/stylelint-browser/lint.test.ts @@ -0,0 +1,40 @@ +import { test, expect } from 'vitest' +import stylelintPlugin from '@projectwallace/stylelint-plugin' +import { lint } from './lint' +import { PRESET_MAP } from './presets' + +// Smoke test for the deep-imported stylelint internals (lintPostcssResult, +// normalizeAllRuleSettings, createPartialStylelintResult, prepareReturnValue). +// If a stylelint upgrade changes their signatures or the shape of the +// `.stylelint` scaffold object they expect, this should fail loudly instead +// of silently linting nothing. +test('flags a known rule violation', async () => { + const result = await lint([{ id: 'input.css', code: 'a { colour: red !important; }' }], { + rules: PRESET_MAP.recommended, + plugins: stylelintPlugin + }) + + const file = result.results.at(0) + expect(file).toBeDefined() + expect(file?.warnings.map((w) => w.rule)).toContain('projectwallace/max-important-ratio') +}) + +test('reports no warnings for clean CSS', async () => { + const result = await lint([{ id: 'input.css', code: 'a { color: red; }' }], { + rules: PRESET_MAP.recommended, + plugins: stylelintPlugin + }) + + const file = result.results.at(0) + expect(file?.warnings).toEqual([]) +}) + +test('reports a CssSyntaxError for invalid CSS', async () => { + const result = await lint([{ id: 'input.css', code: `a { background: url('")}` }], { + rules: PRESET_MAP.recommended, + plugins: stylelintPlugin + }) + + const file = result.results.at(0) + expect(file?.warnings.some((w) => w.rule === 'CssSyntaxError')).toBe(true) +}) diff --git a/src/lib/stylelint-browser/lint.ts b/src/lib/stylelint-browser/lint.ts new file mode 100644 index 00000000..0deda71c --- /dev/null +++ b/src/lib/stylelint-browser/lint.ts @@ -0,0 +1,123 @@ +// Runs stylelint's linting core directly in the browser, skipping stylelint's +// `standalone()`/`lint()` entry point (and the file-resolution machinery +// behind it: globby, cosmiconfig, write-file-atomic, ...) since we only ever +// lint in-memory CSS against a single, already-resolved config. +// +// This deep-imports a handful of stylelint internals that aren't part of its +// public `exports` map. They're aliased to real files on disk in +// vite.config.js, and their shapes are pinned via stylelint-internals.d.ts. +// Re-verify both against node_modules/stylelint/lib/*.mjs when bumping the +// stylelint version (pinned in package.json). +import postcss from 'postcss' +import lintPostcssResult from 'stylelint/lib/lintPostcssResult.mjs' +import normalizeAllRuleSettings from 'stylelint/lib/normalizeAllRuleSettings.mjs' +import createPartialStylelintResult from 'stylelint/lib/createPartialStylelintResult.mjs' +import prepareReturnValue from 'stylelint/lib/prepareReturnValue.mjs' +import jsonFormatter from 'stylelint/lib/formatters/jsonFormatter.mjs' +// `lib/utils/*` is publicly exported by stylelint, so this one needs no alias. +import getLexer from 'stylelint/lib/utils/getLexer.mjs' +import type { Config, LinterResult, PostcssResult, Rule } from 'stylelint' +// Pins package.json deps that only stylelint's own internals above import by +// name - see that file's header comment for why this needs to exist at all. +import './pinned-transitive-deps.js' + +export type LintSource = { + /** Cosmetic label only (becomes `result.source`); a file path or URL both work. */ + id: string + code: string +} + +type PluginRuleDefinition = { ruleName: string; rule: Rule } + +/** + * Re-implementation of stylelint's `addPluginFunctions` (lib/augmentConfig.mjs), + * minus the module-resolution branch: plugins must already be imported objects, + * never string specifiers. + */ +function build_plugin_functions(plugins: Config['plugins']): Record { + const plugin_functions: Record = {} + if (!plugins) { + return plugin_functions + } + + const normalized_plugins = ([] as unknown[]).concat(plugins) + + for (const plugin_lookup of normalized_plugins) { + if (typeof plugin_lookup === 'string') { + throw new TypeError( + `Browser stylelint driver only accepts already-imported plugin objects, got a string: "${plugin_lookup}"` + ) + } + + const plugin_import = (plugin_lookup as { default?: unknown }).default ?? plugin_lookup + const rule_definitions = ([] as PluginRuleDefinition[]).concat(plugin_import as PluginRuleDefinition) + + for (const rule_definition of rule_definitions) { + if (!rule_definition.ruleName) { + throw new Error('stylelint requires plugins to expose a ruleName.') + } + if (!rule_definition.ruleName.includes('/')) { + throw new Error( + `stylelint requires plugin rules to be namespaced, i.e. only "plugin-namespace/plugin-rule-name" plugin rule names are supported. The plugin rule "${rule_definition.ruleName}" does not do this.` + ) + } + plugin_functions[rule_definition.ruleName] = rule_definition.rule + } + } + + return plugin_functions +} + +function prepare_config(config: Config): Promise { + const prepared: Config = { + rules: config.rules, + defaultSeverity: config.defaultSeverity, + _pluginFunctions: build_plugin_functions(config.plugins) + } + return normalizeAllRuleSettings(prepared) +} + +async function lint_one(source: LintSource, config: Config) { + try { + const postcss_result = (await postcss().process(source.code, { from: source.id }).async()) as PostcssResult + + const wrapped: PostcssResult = Object.assign(postcss_result, { + stylelint: { + ruleSeverities: {}, + customMessages: {}, + customUrls: {}, + ruleMetadata: {}, + fixersData: {}, + rangesOfComputedEditInfos: [], + disabledRanges: {}, + lexer: getLexer(config), + referenceRoots: [] + } + }) + + await lintPostcssResult({ quietDeprecationWarnings: true }, wrapped, config) + + return createPartialStylelintResult(wrapped) + } catch (error) { + if (error instanceof Error && error.name === 'CssSyntaxError') { + return createPartialStylelintResult(undefined, error as Error & { name: 'CssSyntaxError' }) + } + throw error + } +} + +/** + * Lint one or more in-memory CSS sources against a single config. No + * `extends` resolution, no custom syntaxes, no caching, no ignore files, no + * autofix - see the plan this implements for the full list of trade-offs. + */ +export async function lint(sources: LintSource[], config: Config): Promise { + const prepared_config = await prepare_config(config) + const results = [] + + for (const source of sources) { + results.push(await lint_one(source, prepared_config)) + } + + return prepareReturnValue({ results, maxWarnings: undefined, formatter: jsonFormatter, cwd: '/' }) +} diff --git a/src/lib/stylelint-browser/pinned-transitive-deps.ts b/src/lib/stylelint-browser/pinned-transitive-deps.ts new file mode 100644 index 00000000..a3c7f60b --- /dev/null +++ b/src/lib/stylelint-browser/pinned-transitive-deps.ts @@ -0,0 +1,35 @@ +// pnpm's strict node_modules layout only installs packages declared +// directly in this repo's package.json - it doesn't hoist a dependency's +// own dependencies just because we deep-import files from inside that +// dependency. +// +// ./lint.ts deep-imports internals from `stylelint` itself (aliased to the +// real files on disk in vite.config.js, since they aren't part of +// stylelint's public `exports` map - see lint.ts's header comment). Those +// internals statically import a few packages that stylelint installs for +// its own use, but that our own code never references by name: +// +// - `css-tree` and `@csstools/css-syntax-patches-for-csstree`, used by +// stylelint/lib/utils/getLexer.mjs, which lint.ts calls directly to +// build the `.stylelint.lexer` scaffold field. +// - `@csstools/css-tokenizer`, used by stylelint/lib/assignDisabledRanges.mjs, +// which lintPostcssResult.mjs calls unconditionally on every lint. +// - `fastest-levenshtein`, used by stylelint/lib/reportUnknownRuleNames.mjs, +// statically imported by lintPostcssResult.mjs (only executes on an +// unknown-rule-name error, but still needs to resolve at bundle time). +// +// Without them declared in package.json, pnpm won't install them at the top +// level and the browser bundle fails to resolve (see the "MISSING dep" notes +// in git history for the exact errors). This file's only job is to give +// dependency-usage tools (knip, depcheck, ...) - and future readers - a real, +// traceable usage site instead of a mysteriously "unused" dependency. Follow +// the imports above into node_modules/stylelint/lib to see the actual call +// sites; keep the versions here in sync with stylelint's own `dependencies` +// (node_modules/stylelint/package.json) when bumping the pinned stylelint +// version in package.json. +import { fork } from 'css-tree' +import syntaxPatches from '@csstools/css-syntax-patches-for-csstree' with { type: 'json' } +import { tokenize } from '@csstools/css-tokenizer' +import { distance } from 'fastest-levenshtein' + +export const stylelint_transitive_deps = { fork, syntaxPatches, tokenize, distance } diff --git a/src/lib/stylelint-browser/presets.ts b/src/lib/stylelint-browser/presets.ts new file mode 100644 index 00000000..651c9e7d --- /dev/null +++ b/src/lib/stylelint-browser/presets.ts @@ -0,0 +1,17 @@ +import recommendedConfig from '@projectwallace/stylelint-plugin/configs/recommended' +import performanceConfig from '@projectwallace/stylelint-plugin/configs/performance' +import maintainabilityConfig from '@projectwallace/stylelint-plugin/configs/maintainability' +import correctnessConfig from '@projectwallace/stylelint-plugin/configs/correctness' +import designTokensConfig from '@projectwallace/stylelint-plugin/configs/design-tokens' +import holisticConfig from '@projectwallace/stylelint-plugin/configs/holistic' +import type { Config } from 'stylelint' +import { type Preset } from '#lib/lint-preset.ts' + +export const PRESET_MAP: Record | undefined> = { + recommended: recommendedConfig.rules, + performance: performanceConfig.rules, + maintainability: maintainabilityConfig.rules, + correctness: correctnessConfig.rules, + designtokens: designTokensConfig.rules, + holistic: holisticConfig.rules +} diff --git a/src/lib/stylelint-browser/shims/node-os.ts b/src/lib/stylelint-browser/shims/node-os.ts new file mode 100644 index 00000000..68cbaba5 --- /dev/null +++ b/src/lib/stylelint-browser/shims/node-os.ts @@ -0,0 +1,4 @@ +// Browser-only stand-in for Node's `node:os` module. Vite aliases the bare +// `node:os` specifier to this file for client bundles (see vite.config.js). +// Stylelint's internals only ever read `EOL`. +export const EOL = '\n' diff --git a/src/lib/stylelint-browser/shims/node-process.ts b/src/lib/stylelint-browser/shims/node-process.ts new file mode 100644 index 00000000..a5dcd9ea --- /dev/null +++ b/src/lib/stylelint-browser/shims/node-process.ts @@ -0,0 +1,15 @@ +// Browser-only stand-in for Node's `node:process` module. Vite aliases the +// bare `node:process` specifier to this file for client bundles (see +// vite.config.js). Only the bits stylelint's internals touch are stubbed: +// - `env.TIMING` gates a CLI table printout we never trigger +// - `noDeprecation` toggles inclusion of deprecation messages +// - `emitWarning`/`on` are called defensively but never in normal operation +const process_shim = { + env: {} as Record, + noDeprecation: false, + emitWarning: (..._args: unknown[]) => {}, + on: (..._args: unknown[]) => {}, + hrtime: Object.assign((..._args: unknown[]) => [0, 0], { bigint: () => BigInt(0) }) +} + +export default process_shim diff --git a/src/lib/stylelint-browser/shims/stylelint-rules.ts b/src/lib/stylelint-browser/shims/stylelint-rules.ts new file mode 100644 index 00000000..47da96fd --- /dev/null +++ b/src/lib/stylelint-browser/shims/stylelint-rules.ts @@ -0,0 +1,39 @@ +// Browser-only stand-in for stylelint's lib/rules/index.mjs (aliased in +// place of it in vite.config.js). +// +// The real module resolves each built-in rule via a *dynamic* import whose +// path is only known at runtime: `import(\`./${ruleName}/index.mjs\`)`. +// Rollup can't statically enumerate that - the variable makes every +// possible target unknowable at build time - and because the real file +// lives inside node_modules, Vite's "dynamic import with a non-literal +// path" handling (which can glob-expand some such imports) skips it. Net +// result in a production build: no per-rule chunk ever gets emitted, and +// every lint request 404s trying to fetch one at runtime. This reproduces +// identically on stylelint 17.13.0, 17.16.0 and 18.0.0-next.0 - it's not +// tied to any one stylelint version, so bumping/pinning a version alone +// can't fix it. +// +// `import.meta.glob` is Vite's own answer to exactly this: given a literal +// glob pattern (known at build time), it generates one real, statically +// analyzable dynamic import per matched file, so Rollup emits (and +// correctly rewrites every request to) a real chunk for every rule - while +// still loading each one lazily, same as the code this replaces. +import type { Rule } from 'stylelint' + +const rule_modules = import.meta.glob('../../../../node_modules/stylelint/lib/rules/*/index.mjs') as Record< + string, + () => Promise<{ default: Rule }> +> + +const rules: Record> = {} + +for (const [path, load] of Object.entries(rule_modules)) { + const match = /\/rules\/([^/]+)\/index\.mjs$/.exec(path) + if (!match) { + continue + } + // oxlint-disable-next-line prefer-top-level-await -- must stay deferred: awaiting here would load every rule eagerly, defeating the point of this file + rules[match[1]] = load().then((module) => module.default) +} + +export default rules diff --git a/src/lib/stylelint-browser/shims/stylelint-timing.ts b/src/lib/stylelint-browser/shims/stylelint-timing.ts new file mode 100644 index 00000000..d93654b1 --- /dev/null +++ b/src/lib/stylelint-browser/shims/stylelint-timing.ts @@ -0,0 +1,15 @@ +// Browser-only stand-in for stylelint's lib/timing.mjs. Vite redirects that +// relative import to this file for client bundles (see vite.config.js). +// +// The real module is only useful for `TIMING= stylelint ...` CLI runs - +// our `node:process` shim never sets that env var, so `timing.enabled` would +// always be `false` anyway. Pulling in the real module drags in the `table` +// package, which (via `supports-hyperlinks` -> `supports-color`) doesn't +// bundle for the browser. +export default { + display: () => {}, + enabled: false, + getListSize: () => 0, + tableConfig: {}, + time: (_key: string, fn: (...args: unknown[]) => unknown) => fn +} diff --git a/src/lib/stylelint-browser/stylelint-internals.d.ts b/src/lib/stylelint-browser/stylelint-internals.d.ts new file mode 100644 index 00000000..b784f559 --- /dev/null +++ b/src/lib/stylelint-browser/stylelint-internals.d.ts @@ -0,0 +1,87 @@ +// stylelint's package.json `exports` map only publishes `.`, `./package.json` +// and `./lib/utils/*`. The files below are unpublished internals we deep- +// import on purpose (see src/lib/stylelint-browser/lint.ts) and alias in +// vite.config.js so the bundler can still find them on disk. TypeScript's +// "bundler" module resolution honours the exports map though, so without +// these ambient declarations it can't see the deep paths exist. +// +// Pinned to stylelint ~17.16.0 (see package.json) - re-check these shapes +// against node_modules/stylelint/lib/*.mjs whenever that version changes. + +declare module 'stylelint/lib/lintPostcssResult.mjs' { + import type { LinterOptions, PostcssResult, Config } from 'stylelint' + export default function lintPostcssResult( + stylelintOptions: Partial, + postcssResult: PostcssResult, + config: Config + ): Promise +} + +declare module 'stylelint/lib/normalizeAllRuleSettings.mjs' { + import type { Config } from 'stylelint' + export default function normalizeAllRuleSettings(config: Config): Promise +} + +declare module 'stylelint/lib/createPartialStylelintResult.mjs' { + import type { LintResult, PostcssResult } from 'stylelint' + export default function createPartialStylelintResult( + postcssResult?: PostcssResult, + cssSyntaxError?: Error & { name: 'CssSyntaxError' } + ): LintResult +} + +declare module 'stylelint/lib/prepareReturnValue.mjs' { + import type { LinterResult, LintResult, Formatter } from 'stylelint' + export default function prepareReturnValue(args: { + results: LintResult[] + maxWarnings?: number + formatter: Formatter + cwd: string + }): LinterResult +} + +declare module 'stylelint/lib/formatters/jsonFormatter.mjs' { + import type { Formatter } from 'stylelint' + const jsonFormatter: Formatter + export default jsonFormatter +} + +// stylelint's `./lib/utils/*` export is public, but since stylelint ships a +// "types" condition for its main entry, TypeScript treats the whole package +// as self-typed and stops falling back to `allowJs` inference for subpaths +// that lack their own declaration file - these four need the same manual +// pinning as the internals above. + +declare module 'stylelint/lib/utils/getLexer.mjs' { + import type { Config } from 'stylelint' + export default function getLexer(config: Config, additionalSyntax?: unknown): unknown +} + +declare module 'stylelint/lib/utils/report.mjs' { + import type { Problem } from 'stylelint' + export default function report(problem: Problem): void +} + +declare module 'stylelint/lib/utils/ruleMessages.mjs' { + export default function ruleMessages>(ruleName: string, messages: T): T +} + +declare module 'stylelint/lib/utils/validateOptions.mjs' { + import type { PostcssResult } from 'stylelint' + export default function validateOptions( + result: PostcssResult, + ruleName: string, + ...optionDescriptions: unknown[] + ): boolean +} + +declare module 'stylelint/lib/utils/checkAgainstRule.mjs' { + export default function checkAgainstRule(options: unknown, callback: (...args: unknown[]) => void): Promise +} + +// `css-tree` (a stylelint dependency, pinned in pinned-transitive-deps.ts) +// ships no types and has no `@types/css-tree` we've pulled in - only `fork` +// is referenced, so that's all that's declared here. +declare module 'css-tree' { + export function fork(config: unknown): unknown +} diff --git a/src/lib/stylelint-browser/stylelint-shim.ts b/src/lib/stylelint-browser/stylelint-shim.ts new file mode 100644 index 00000000..901588ce --- /dev/null +++ b/src/lib/stylelint-browser/stylelint-shim.ts @@ -0,0 +1,23 @@ +// Browser-only stand-in for the `stylelint` package itself. Vite aliases the +// bare `stylelint` specifier to this file for client bundles (see +// vite.config.js), so that plugin packages doing `import stylelint from +// 'stylelint'` (only to reach `stylelint.createPlugin`/`stylelint.utils`) +// don't drag in `standalone.mjs` and its Node-only deps (globby, cosmiconfig, +// write-file-atomic, ...). +// +// The four utils below live under stylelint's public `./lib/utils/*` export, +// so they resolve without any extra aliasing. +import report from 'stylelint/lib/utils/report.mjs' +import ruleMessages from 'stylelint/lib/utils/ruleMessages.mjs' +import validateOptions from 'stylelint/lib/utils/validateOptions.mjs' +import checkAgainstRule from 'stylelint/lib/utils/checkAgainstRule.mjs' +import type { Rule } from 'stylelint' + +function createPlugin(ruleName: string, rule: Rule) { + return { ruleName, rule } +} + +export default { + createPlugin, + utils: { report, ruleMessages, validateOptions, checkAgainstRule } +} diff --git a/src/routes/(public)/lint-css/spec.ts b/src/routes/(public)/lint-css/spec.ts index f820c6a8..99147811 100644 --- a/src/routes/(public)/lint-css/spec.ts +++ b/src/routes/(public)/lint-css/spec.ts @@ -1,25 +1,17 @@ import { test, expect } from '../../../../tests/fixtures' -const LINT_CSS_API = '**/api/lint-css' - -const mock_lint_response = { - result: { - errored: false, - parse_error: undefined, - warnings: [ - { - line: 1, - column: 5, - endLine: 1, - endColumn: 11, - text: 'Unexpected unknown property "colour" (property-no-unknown)', - rule: 'property-no-unknown' - } - ] - }, - duration: 10, - css: 'a {\n\tcolour: red;\n}\n' -} +// Linting itself now runs client-side (see src/lib/stylelint-browser/lint.ts), +// so only the CSS-fetching API is mocked here; warnings below reflect real +// stylelint output for the given CSS. +const GET_CSS_API = '**/api/get-css*' + +const mock_origins = [ + { + type: 'file', + href: 'https://example.com/style.css', + css: 'a { colour: red !important; }' + } +] test('does SEO well', async ({ page }) => { await page.goto('/lint-css', { waitUntil: 'domcontentloaded' }) @@ -32,9 +24,9 @@ test('does SEO well', async ({ page }) => { test.describe('URL input mode', () => { test.beforeEach(async ({ page }) => { - await page.route(LINT_CSS_API, async (route) => { - if (route.request().method() === 'POST') { - await route.fulfill({ status: 200, json: mock_lint_response }) + await page.route(GET_CSS_API, async (route) => { + if (route.request().method() === 'GET') { + await route.fulfill({ status: 200, json: mock_origins }) } else { await route.continue() } @@ -49,14 +41,14 @@ test.describe('URL input mode', () => { await expect.soft(page.getByRole('table')).toBeVisible() expect.soft(await page.getByRole('table').getByRole('row').count()).toBeGreaterThanOrEqual(2) - await expect.soft(page.getByRole('cell', { name: /Unexpected unknown property/ })).toBeVisible() + await expect.soft(page.getByRole('cell', { name: /important ratio/i })).toBeVisible() }) test('shows the fetched CSS in the CSS input pane', async ({ page }) => { await page.getByLabel('Website URL').fill('example.com') await page.getByRole('button', { name: 'Analyze URL' }).click() - await expect.soft(page.getByTestId('pre-css')).toContainText(mock_lint_response.css) + await expect.soft(page.getByTestId('pre-css')).toContainText('colour: red !important;') }) }) diff --git a/src/routes/api/lint-css/+server.ts b/src/routes/api/lint-css/+server.ts deleted file mode 100644 index 8fafc71e..00000000 --- a/src/routes/api/lint-css/+server.ts +++ /dev/null @@ -1,100 +0,0 @@ -import { error } from '@sveltejs/kit' -import stylelint, { type Config } from 'stylelint' -import recommendedConfig from '@projectwallace/stylelint-plugin/configs/recommended' -import performanceConfig from '@projectwallace/stylelint-plugin/configs/performance' -import maintainabilityConfig from '@projectwallace/stylelint-plugin/configs/maintainability' -import correctnessConfig from '@projectwallace/stylelint-plugin/configs/correctness' -import designTokensConfig from '@projectwallace/stylelint-plugin/configs/design-tokens' -import holisticConfig from '@projectwallace/stylelint-plugin/configs/holistic' -import stylelintPlugin from '@projectwallace/stylelint-plugin' -import { get_css } from '../get-css/get-css' -import { format } from '@projectwallace/format-css' -import type { RequestHandler } from './$types' -import { presets, type Preset, DEFAULT_PRESET } from '#lib/lint-preset.ts' - -export type { Preset } - -const PRESET_MAP: Record | undefined> = { - recommended: recommendedConfig.rules, - performance: performanceConfig.rules, - maintainability: maintainabilityConfig.rules, - correctness: correctnessConfig.rules, - designtokens: designTokensConfig.rules, - holistic: holisticConfig.rules -} - -type RequestBody = { url?: string; css?: string; preset?: string; prettify?: boolean } - -export const POST: RequestHandler = async ({ request, setHeaders }) => { - const body = (await request.json()) as RequestBody - const raw_preset = body.preset?.toString() - - let css: string - let url_css: string | undefined - - if (body.url) { - const origins = await get_css(body.url.toString()) - if ('error' in origins) { - error(400, origins.error.message) - } - css = origins.map((o) => o.css).join('\n') - if (body.prettify) { - css = format(css) - } - url_css = css - } else { - css = body.css?.toString() ?? '' - } - const preset: Preset = - raw_preset && (presets as readonly string[]).includes(raw_preset) ? (raw_preset as Preset) : DEFAULT_PRESET - - let rules: NonNullable = PRESET_MAP[preset] ?? (Object.create(null) as NonNullable) - - const start = performance.now() - const lint_result = await stylelint.lint({ - config: { - plugins: stylelintPlugin, - rules - }, - code: css?.toString(), - configBasedir: process.cwd() - }) - - const file = lint_result.results.at(0) - - if (!file) { - error(500) - } - - const lint_warnings = file.warnings.filter((w) => w.rule !== 'CssSyntaxError') - const parse_error = file.warnings.find((w) => w.rule === 'CssSyntaxError') - - const return_data = { - errored: file.invalidOptionWarnings.length > 0 || lint_warnings.some((w) => w.severity === 'error'), - parse_error, - warnings: lint_warnings - .toSorted((a, b) => { - if (a.line === b.line) { - return a.column - b.column - } - return a.line - b.line - }) - .map(({ line, column, endLine, endColumn, text, rule }) => ({ - line, - column, - endLine, - endColumn, - text, - rule - })) - } - - const duration = performance.now() - start - setHeaders({ 'Server-Timing': `lint;dur=${duration.toFixed(1)}` }) - - return Response.json({ - result: return_data, - duration: parseFloat(duration.toFixed(1)), - css: url_css - }) -} diff --git a/vite-dev-merge.log b/vite-dev-merge.log new file mode 100644 index 00000000..8895033c --- /dev/null +++ b/vite-dev-merge.log @@ -0,0 +1,1314 @@ +11:46:28 AM [vite] (ssr) connected. + + VITE v8.2.1 ready in 1160 ms + + ➜ Local: http://localhost:5186/ + ➜ Network: use --host to expose +[vite:css][lightningcss] 'global' is not recognized as a valid pseudo-class. Did you mean '::global' (pseudo-element) or is this a typo? +15 | } +16 | +17 | :global(html:not([data-theme='naked'])) .logo { + | ^ +18 | &::after { +19 | content: 'W'; +[vite:css][lightningcss] 'search-text' is not recognized as a valid pseudo-element. Did you mean ':search-text' (pseudo-class) or is this a typo? +463 | } +464 | +465 | ::search-text { + | ^ +466 | background: var(--yellow-400); +467 | color: var(--black); +[vite:css][lightningcss] 'search-text' is not recognized as a valid pseudo-element. Did you mean ':search-text' (pseudo-class) or is this a typo? +468 | } +469 | +470 | ::search-text:current { + | ^ +471 | background-color: var(--orange-400); +472 | color: var(--black); +[vite:css][lightningcss] 'highlight' is not recognized as a valid pseudo-element. Did you mean ':highlight' (pseudo-class) or is this a typo? +534 | } +535 | +536 | ::highlight(Property) { + | ^ +537 | color: var(--highlight-property); +538 | } +[vite:css][lightningcss] 'highlight' is not recognized as a valid pseudo-element. Did you mean ':highlight' (pseudo-class) or is this a typo? +538 | } +539 | +540 | ::highlight(AtruleName), + | ^ +541 | ::highlight(Function), +542 | ::highlight(Important) { +[vite:css][lightningcss] 'highlight' is not recognized as a valid pseudo-element. Did you mean ':highlight' (pseudo-class) or is this a typo? +539 | +540 | ::highlight(AtruleName), +541 | ::highlight(Function), + | ^ +542 | ::highlight(Important) { +543 | color: var(--highlight-atrule); +[vite:css][lightningcss] 'highlight' is not recognized as a valid pseudo-element. Did you mean ':highlight' (pseudo-class) or is this a typo? +540 | ::highlight(AtruleName), +541 | ::highlight(Function), +542 | ::highlight(Important) { + | ^ +543 | color: var(--highlight-atrule); +544 | } +[vite:css][lightningcss] 'highlight' is not recognized as a valid pseudo-element. Did you mean ':highlight' (pseudo-class) or is this a typo? +544 | } +545 | +546 | ::highlight(Unit), + | ^ +547 | ::highlight(Function) { +548 | color: var(--highlight-name); +[vite:css][lightningcss] 'highlight' is not recognized as a valid pseudo-element. Did you mean ':highlight' (pseudo-class) or is this a typo? +545 | +546 | ::highlight(Unit), +547 | ::highlight(Function) { + | ^ +548 | color: var(--highlight-name); +549 | } +[vite:css][lightningcss] 'highlight' is not recognized as a valid pseudo-element. Did you mean ':highlight' (pseudo-class) or is this a typo? +549 | } +550 | +551 | ::highlight(SelectorList), + | ^ +552 | ::highlight(Selector) { +553 | color: var(--highlight-selector); +[vite:css][lightningcss] 'highlight' is not recognized as a valid pseudo-element. Did you mean ':highlight' (pseudo-class) or is this a typo? +550 | +551 | ::highlight(SelectorList), +552 | ::highlight(Selector) { + | ^ +553 | color: var(--highlight-selector); +554 | } +[vite:css][lightningcss] 'highlight' is not recognized as a valid pseudo-element. Did you mean ':highlight' (pseudo-class) or is this a typo? +554 | } +555 | +556 | ::highlight(AtrulePrelude), + | ^ +557 | ::highlight(Value) { +558 | color: var(--highlight-value); +[vite:css][lightningcss] 'highlight' is not recognized as a valid pseudo-element. Did you mean ':highlight' (pseudo-class) or is this a typo? +555 | +556 | ::highlight(AtrulePrelude), +557 | ::highlight(Value) { + | ^ +558 | color: var(--highlight-value); +559 | } +[vite:css][lightningcss] 'highlight' is not recognized as a valid pseudo-element. Did you mean ':highlight' (pseudo-class) or is this a typo? +559 | } +560 | +561 | ::highlight(Number) { + | ^ +562 | color: var(--highlight-number); +563 | } +[vite:css][lightningcss] 'highlight' is not recognized as a valid pseudo-element. Did you mean ':highlight' (pseudo-class) or is this a typo? +563 | } +564 | +565 | ::highlight(String) { + | ^ +566 | color: var(--highlight-string); +567 | } +[vite:css][lightningcss] 'highlight' is not recognized as a valid pseudo-element. Did you mean ':highlight' (pseudo-class) or is this a typo? +567 | } +568 | +569 | ::highlight(Comment) { + | ^ +570 | color: var(--highlight-comment); +571 | } +[vite:css][lightningcss] 'global' is not recognized as a valid pseudo-class. Did you mean '::global' (pseudo-element) or is this a typo? +19 | } +20 | +21 | :global(.icon) { + | ^ +22 | margin-top: -4px; +23 | } +[vite:css][lightningcss] 'global' is not recognized as a valid pseudo-class. Did you mean '::global' (pseudo-element) or is this a typo? +17 | font-size: var(--pw-table-font-size); +18 | +19 | & :global(thead tr) { + | ^ +20 | position: sticky; +21 | top: 0; +[vite:css][lightningcss] 'global' is not recognized as a valid pseudo-class. Did you mean '::global' (pseudo-element) or is this a typo? +26 | } +27 | +28 | & :global(th:not([scope='row' i])) { + | ^ +29 | font-weight: var(--font-bold); +30 | } +[vite:css][lightningcss] 'global' is not recognized as a valid pseudo-class. Did you mean '::global' (pseudo-element) or is this a typo? +30 | } +31 | +32 | & :global(th[scope='row' i]) { + | ^ +33 | font-weight: var(--font-normal); +34 | } +[vite:css][lightningcss] 'global' is not recognized as a valid pseudo-class. Did you mean '::global' (pseudo-element) or is this a typo? +34 | } +35 | +36 | & :global(:is(th, td)) { + | ^ +37 | text-align: start; +38 | padding-block: var(--pw-table-padding-block); +[vite:css][lightningcss] 'global' is not recognized as a valid pseudo-class. Did you mean '::global' (pseudo-element) or is this a typo? +40 | } +41 | +42 | & :global(td:not(:first-child)) { + | ^ +43 | border-inline-start: 1px solid var(--fg-500); +44 | } +[vite:css][lightningcss] 'global' is not recognized as a valid pseudo-class. Did you mean '::global' (pseudo-element) or is this a typo? +44 | } +45 | +46 | & :global(th), + | ^ +47 | & :global(td:first-child) { +48 | white-space: nowrap; +[vite:css][lightningcss] 'global' is not recognized as a valid pseudo-class. Did you mean '::global' (pseudo-element) or is this a typo? +45 | +46 | & :global(th), +47 | & :global(td:first-child) { + | ^ +48 | white-space: nowrap; +49 | } +[vite:css][lightningcss] 'global' is not recognized as a valid pseudo-class. Did you mean '::global' (pseudo-element) or is this a typo? +49 | } +50 | +51 | & :global(:where(tr:nth-child(even))) { + | ^ +52 | background-color: var(--uneven-tr-bg); +53 | } +[vite:css][lightningcss] 'global' is not recognized as a valid pseudo-class. Did you mean '::global' (pseudo-element) or is this a typo? +53 | } +54 | +55 | & :global(td) { + | ^ +56 | line-height: var(--leading-snug); +57 | vertical-align: baseline; +[vite:css][lightningcss] 'global' is not recognized as a valid pseudo-class. Did you mean '::global' (pseudo-element) or is this a typo? +58 | } +59 | +60 | & :global(.numeric) { + | ^ +61 | text-align: end; +62 | white-space: nowrap; +[vite:css][lightningcss] 'global' is not recognized as a valid pseudo-class. Did you mean '::global' (pseudo-element) or is this a typo? +1 | +2 | /* stylelint-disable projectwallace/max-average-selector-complexity -- highlight pseudo-elements inflate complexity */ +3 | :global(::highlight(lint_lines), ::highlight(lint_selected_line)) { + | ^ +4 | text-decoration-color: var(--red-300); +5 | text-decoration-style: wavy; +[vite:css][lightningcss] 'global' is not recognized as a valid pseudo-class. Did you mean '::global' (pseudo-element) or is this a typo? +7 | } +8 | +9 | :global(::highlight(lint_lines)) { + | ^ +10 | background-color: transparent; +11 | } +[vite:css][lightningcss] 'global' is not recognized as a valid pseudo-class. Did you mean '::global' (pseudo-element) or is this a typo? +11 | } +12 | +13 | :global(::highlight(lint_selected_line)) { + | ^ +14 | background-color: var(--highlight-code); +15 | } +[vite:css][lightningcss] 'highlight' is not recognized as a valid pseudo-element. Did you mean ':highlight' (pseudo-class) or is this a typo? +4 | } +5 | +6 | ::highlight(lines) { + | ^ +7 | background-color: var(--highlight-code); +8 | } +[vite:css][lightningcss] 'highlight' is not recognized as a valid pseudo-element. Did you mean ':highlight' (pseudo-class) or is this a typo? +8 | } +9 | +10 | ::highlight(selected_line) { + | ^ +11 | background-color: var(--highlight-code-selected); +12 | } +[vite:css][lightningcss] 'highlight' is not recognized as a valid pseudo-element. Did you mean ':highlight' (pseudo-class) or is this a typo? +3 | } +4 | +5 | .svelte-il175y::highlight(lines) { + | ^ +6 | background-color: var(--highlight-code); +7 | } +[vite:css][lightningcss] 'highlight' is not recognized as a valid pseudo-element. Did you mean ':highlight' (pseudo-class) or is this a typo? +7 | } +8 | +9 | .svelte-il175y::highlight(selected_line) { + | ^ +10 | background-color: var(--highlight-code-selected); +11 | } +[vite:css][lightningcss] 'highlight' is not recognized as a valid pseudo-element. Did you mean ':highlight' (pseudo-class) or is this a typo? +1 | ::highlight(lint_lines), ::highlight(lint_selected_line) { + | ^ +2 | -webkit-text-decoration-color: var(--red-300); +3 | text-decoration-color: var(--red-300); +[vite:css][lightningcss] 'highlight' is not recognized as a valid pseudo-element. Did you mean ':highlight' (pseudo-class) or is this a typo? +1 | ::highlight(lint_lines), ::highlight(lint_selected_line) { + | ^ +2 | -webkit-text-decoration-color: var(--red-300); +3 | text-decoration-color: var(--red-300); +[vite:css][lightningcss] 'highlight' is not recognized as a valid pseudo-element. Did you mean ':highlight' (pseudo-class) or is this a typo? +6 | } +7 | +8 | ::highlight(lint_lines) { + | ^ +9 | background-color: #0000; +10 | } +[vite:css][lightningcss] 'highlight' is not recognized as a valid pseudo-element. Did you mean ':highlight' (pseudo-class) or is this a typo? +10 | } +11 | +12 | ::highlight(lint_selected_line) { + | ^ +13 | background-color: var(--highlight-code); +14 | } +[vite:css][lightningcss] 'global' is not recognized as a valid pseudo-class. Did you mean '::global' (pseudo-element) or is this a typo? +91 | font-size: var(--size-lg); +92 | +93 | & :global(.icon) { + | ^ +94 | margin-block-start: -0.2em; +95 | zoom: 1.2; +[vite:css][lightningcss] 'global' is not recognized as a valid pseudo-class. Did you mean '::global' (pseudo-element) or is this a typo? +34 | } +35 | +36 | .pane-header :global(.pane-title) { + | ^ +37 | font-weight: var(--font-bold); +38 | margin-inline-end: auto; +[vite:css][lightningcss] 'global' is not recognized as a valid pseudo-class. Did you mean '::global' (pseudo-element) or is this a typo? +1 | +2 | /* stylelint-disable projectwallace/max-average-selector-complexity -- Global styling requires more complex selector... +3 | :global(.markdown :is(h1, h2, h3, h4)) { + | ^ +4 | line-height: var(--leading-none); +5 | } +[vite:css][lightningcss] 'global' is not recognized as a valid pseudo-class. Did you mean '::global' (pseudo-element) or is this a typo? +5 | } +6 | +7 | :global(.markdown :is(h1, h2, h3, h4) :any-link) { + | ^ +8 | text-decoration: none; +9 | color: inherit; +[vite:css][lightningcss] 'global' is not recognized as a valid pseudo-class. Did you mean '::global' (pseudo-element) or is this a typo? +10 | } +11 | +12 | :global(.markdown h1) { + | ^ +13 | font-size: var(--size-4xl); +14 | } +[vite:css][lightningcss] 'global' is not recognized as a valid pseudo-class. Did you mean '::global' (pseudo-element) or is this a typo? +14 | } +15 | +16 | :global(.markdown h2) { + | ^ +17 | font-size: var(--size-2xl); +18 | margin-top: var(--space-16); +[vite:css][lightningcss] 'global' is not recognized as a valid pseudo-class. Did you mean '::global' (pseudo-element) or is this a typo? +20 | } +21 | +22 | :global(.markdown h3) { + | ^ +23 | font-size: var(--size-xl); +24 | margin-top: var(--space-12); +[vite:css][lightningcss] 'global' is not recognized as a valid pseudo-class. Did you mean '::global' (pseudo-element) or is this a typo? +26 | } +27 | +28 | :global(.markdown h4) { + | ^ +29 | font-size: var(--size-base); +30 | margin-top: var(--space-12); +[vite:css][lightningcss] 'global' is not recognized as a valid pseudo-class. Did you mean '::global' (pseudo-element) or is this a typo? +32 | } +33 | +34 | :global(.markdown blockquote) { + | ^ +35 | background-color: var(--bg-200); +36 | padding-block: var(--space-4); +[vite:css][lightningcss] 'global' is not recognized as a valid pseudo-class. Did you mean '::global' (pseudo-element) or is this a typo? +41 | } +42 | +43 | :global(.markdown p) { + | ^ +44 | line-height: var(--leading-relaxed); +45 | max-width: 60ch; +[vite:css][lightningcss] 'global' is not recognized as a valid pseudo-class. Did you mean '::global' (pseudo-element) or is this a typo? +46 | } +47 | +48 | :global(.markdown svg[role='img']) { + | ^ +49 | max-width: 80ch; +50 | } +[vite:css][lightningcss] 'global' is not recognized as a valid pseudo-class. Did you mean '::global' (pseudo-element) or is this a typo? +50 | } +51 | +52 | :global(.markdown strong) { + | ^ +53 | font-style: normal; +54 | font-weight: var(--font-bold); +[vite:css][lightningcss] 'global' is not recognized as a valid pseudo-class. Did you mean '::global' (pseudo-element) or is this a typo? +56 | } +57 | +58 | :global(.markdown em) { + | ^ +59 | font-style: italic; +60 | } +[vite:css][lightningcss] 'global' is not recognized as a valid pseudo-class. Did you mean '::global' (pseudo-element) or is this a typo? +61 | +62 | /* stylelint-disable-next-line projectwallace/max-selector-complexity -- This is just a big one */ +63 | :global(.markdown :is(p, pre, img, table, ol, ul, blockquote, figure, iframe, math, .bar-chart)) { + | ^ +64 | margin-block-start: var(--space-6); +65 | +[vite:css][lightningcss] 'global' is not recognized as a valid pseudo-class. Did you mean '::global' (pseudo-element) or is this a typo? +69 | } +70 | +71 | :global(.markdown pre) { + | ^ +72 | background-color: var(--bg-200); +73 | padding-block: 1rem; +[vite:css][lightningcss] 'global' is not recognized as a valid pseudo-class. Did you mean '::global' (pseudo-element) or is this a typo? +92 | +93 | @media (min-width: 44rem) { +94 | :global(.markdown pre) { + | ^ +95 | padding-block: 0.75rem; +96 | padding-inline: 1rem; +[vite:css][lightningcss] 'global' is not recognized as a valid pseudo-class. Did you mean '::global' (pseudo-element) or is this a typo? +101 | +102 | @media (min-width: 66rem) { +103 | :global(.markdown pre) { + | ^ +104 | margin-right: calc(-1 * var(--space-8)); +105 | margin-left: calc(-1 * var(--space-8)); +[vite:css][lightningcss] 'global' is not recognized as a valid pseudo-class. Did you mean '::global' (pseudo-element) or is this a typo? +107 | } +108 | +109 | :global(.markdown pre code) { + | ^ +110 | background-color: transparent; +111 | } +[vite:css][lightningcss] 'global' is not recognized as a valid pseudo-class. Did you mean '::global' (pseudo-element) or is this a typo? +111 | } +112 | +113 | :global(.markdown ul) { + | ^ +114 | line-height: var(--leading-relaxed); +115 | } +[vite:css][lightningcss] 'global' is not recognized as a valid pseudo-class. Did you mean '::global' (pseudo-element) or is this a typo? +115 | } +116 | +117 | :global(.markdown li) { + | ^ +118 | margin-top: 0.75rem; +119 | max-width: 66ch; +[vite:css][lightningcss] 'global' is not recognized as a valid pseudo-class. Did you mean '::global' (pseudo-element) or is this a typo? +120 | } +121 | +122 | :global(.markdown ul li) { + | ^ +123 | list-style: square; +124 | margin-left: 2.25rem; +[vite:css][lightningcss] 'global' is not recognized as a valid pseudo-class. Did you mean '::global' (pseudo-element) or is this a typo? +125 | } +126 | +127 | :global(.markdown ol li) { + | ^ +128 | list-style: decimal; +129 | margin-left: 3rem; +[vite:css][lightningcss] 'global' is not recognized as a valid pseudo-class. Did you mean '::global' (pseudo-element) or is this a typo? +130 | } +131 | +132 | :global(.markdown ul li::marker) { + | ^ +133 | color: var(--accent-500); +134 | } +[vite:css][lightningcss] 'global' is not recognized as a valid pseudo-class. Did you mean '::global' (pseudo-element) or is this a typo? +134 | } +135 | +136 | :global(.markdown ol li::marker) { + | ^ +137 | color: var(--fg-400); +138 | font-weight: var(--font-bold); +[vite:css][lightningcss] 'global' is not recognized as a valid pseudo-class. Did you mean '::global' (pseudo-element) or is this a typo? +141 | } +142 | +143 | :global(.markdown :where(:any-link)), + | ^ +144 | :global(.markdown :where(:any-link code)) { +145 | color: light-dark(var(--accent-800), var(--accent-300)); +[vite:css][lightningcss] 'global' is not recognized as a valid pseudo-class. Did you mean '::global' (pseudo-element) or is this a typo? +142 | +143 | :global(.markdown :where(:any-link)), +144 | :global(.markdown :where(:any-link code)) { + | ^ +145 | color: light-dark(var(--accent-800), var(--accent-300)); +146 | text-decoration: underline; +[vite:css][lightningcss] 'global' is not recognized as a valid pseudo-class. Did you mean '::global' (pseudo-element) or is this a typo? +148 | } +149 | +150 | :global(.markdown table) { + | ^ +151 | --cell-spacing: 0.75rem; +152 | border-spacing: 0; +[vite:css][lightningcss] 'global' is not recognized as a valid pseudo-class. Did you mean '::global' (pseudo-element) or is this a typo? +157 | } +158 | +159 | :global(.markdown th) { + | ^ +160 | text-align: left; +161 | font-family: var(--font-body); +[vite:css][lightningcss] 'global' is not recognized as a valid pseudo-class. Did you mean '::global' (pseudo-element) or is this a typo? +166 | } +167 | +168 | :global(.markdown tbody tr:nth-child(2n + 1)) { + | ^ +169 | background-color: var(--uneven-tr-bg); +170 | } +[vite:css][lightningcss] 'global' is not recognized as a valid pseudo-class. Did you mean '::global' (pseudo-element) or is this a typo? +170 | } +171 | +172 | :global(.markdown td) { + | ^ +173 | padding: var(--cell-spacing); +174 | } +[vite:css][lightningcss] 'global' is not recognized as a valid pseudo-class. Did you mean '::global' (pseudo-element) or is this a typo? +174 | } +175 | +176 | :global(.markdown :is(th, td):not(:first-child)) { + | ^ +177 | text-align: right; +178 | } +[vite:css][lightningcss] 'global' is not recognized as a valid pseudo-class. Did you mean '::global' (pseudo-element) or is this a typo? +178 | } +179 | +180 | :global(.markdown img) { + | ^ +181 | box-shadow: var(--shadow); +182 | border: 1px solid var(--fg-700); +[vite:css][lightningcss] 'global' is not recognized as a valid pseudo-class. Did you mean '::global' (pseudo-element) or is this a typo? +183 | } +184 | +185 | :global(.markdown code) { + | ^ +186 | font-size: var(--size-smaller); +187 | } +[vite:css][lightningcss] 'global' is not recognized as a valid pseudo-class. Did you mean '::global' (pseudo-element) or is this a typo? +187 | } +188 | +189 | :global(.markdown :is(p, li, figcaption) code) { + | ^ +190 | display: inline-block; +191 | margin-right: 0.25ch; +[vite:css][lightningcss] 'global' is not recognized as a valid pseudo-class. Did you mean '::global' (pseudo-element) or is this a typo? +195 | } +196 | +197 | :global(.markdown pre code) { + | ^ +198 | color: var(--fg-200); +199 | } +[vite:css][lightningcss] 'global' is not recognized as a valid pseudo-class. Did you mean '::global' (pseudo-element) or is this a typo? +199 | } +200 | +201 | :global(.markdown aside) { + | ^ +202 | margin-block: var(--space-16); +203 | } +[vite:css][lightningcss] 'global' is not recognized as a valid pseudo-class. Did you mean '::global' (pseudo-element) or is this a typo? +203 | } +204 | +205 | :global(.markdown aside):not([class]) { + | ^ +206 | border: 2px solid var(--accent-800); +207 | padding-block: var(--space-6); +[vite:css][lightningcss] 'global' is not recognized as a valid pseudo-class. Did you mean '::global' (pseudo-element) or is this a typo? +209 | } +210 | +211 | :global(.markdown :is(aside, blockquote) > :first-child) { + | ^ +212 | margin-top: 0; +213 | } +[vite:css][lightningcss] 'global' is not recognized as a valid pseudo-class. Did you mean '::global' (pseudo-element) or is this a typo? +213 | } +214 | +215 | :global(.markdown :is(aside, blockquote) > :last-child) { + | ^ +216 | margin-bottom: 0; +217 | } +[vite:css][lightningcss] 'global' is not recognized as a valid pseudo-class. Did you mean '::global' (pseudo-element) or is this a typo? +217 | } +218 | +219 | :global(.markdown figcaption) { + | ^ +220 | text-align: center; +221 | font-size: var(--size-base); +[vite:css][lightningcss] 'global' is not recognized as a valid pseudo-class. Did you mean '::global' (pseudo-element) or is this a typo? +224 | } +225 | +226 | :global(.markdown hr) { + | ^ +227 | border-block-start: 1px solid var(--gray-500); +228 | margin-block: var(--space-16); +[vite:css][lightningcss] 'search-text' is not recognized as a valid pseudo-element. Did you mean ':search-text' (pseudo-class) or is this a typo? +463 | } +464 | +465 | ::search-text { + | ^ +466 | background: var(--yellow-400); +467 | color: var(--black); +[vite:css][lightningcss] 'search-text' is not recognized as a valid pseudo-element. Did you mean ':search-text' (pseudo-class) or is this a typo? +468 | } +469 | +470 | ::search-text:current { + | ^ +471 | background-color: var(--orange-400); +472 | color: var(--black); +[vite:css][lightningcss] 'highlight' is not recognized as a valid pseudo-element. Did you mean ':highlight' (pseudo-class) or is this a typo? +534 | } +535 | +536 | ::highlight(Property) { + | ^ +537 | color: var(--highlight-property); +538 | } +[vite:css][lightningcss] 'highlight' is not recognized as a valid pseudo-element. Did you mean ':highlight' (pseudo-class) or is this a typo? +538 | } +539 | +540 | ::highlight(AtruleName), + | ^ +541 | ::highlight(Function), +542 | ::highlight(Important) { +[vite:css][lightningcss] 'highlight' is not recognized as a valid pseudo-element. Did you mean ':highlight' (pseudo-class) or is this a typo? +539 | +540 | ::highlight(AtruleName), +541 | ::highlight(Function), + | ^ +542 | ::highlight(Important) { +543 | color: var(--highlight-atrule); +[vite:css][lightningcss] 'highlight' is not recognized as a valid pseudo-element. Did you mean ':highlight' (pseudo-class) or is this a typo? +540 | ::highlight(AtruleName), +541 | ::highlight(Function), +542 | ::highlight(Important) { + | ^ +543 | color: var(--highlight-atrule); +544 | } +[vite:css][lightningcss] 'highlight' is not recognized as a valid pseudo-element. Did you mean ':highlight' (pseudo-class) or is this a typo? +544 | } +545 | +546 | ::highlight(Unit), + | ^ +547 | ::highlight(Function) { +548 | color: var(--highlight-name); +[vite:css][lightningcss] 'highlight' is not recognized as a valid pseudo-element. Did you mean ':highlight' (pseudo-class) or is this a typo? +545 | +546 | ::highlight(Unit), +547 | ::highlight(Function) { + | ^ +548 | color: var(--highlight-name); +549 | } +[vite:css][lightningcss] 'highlight' is not recognized as a valid pseudo-element. Did you mean ':highlight' (pseudo-class) or is this a typo? +549 | } +550 | +551 | ::highlight(SelectorList), + | ^ +552 | ::highlight(Selector) { +553 | color: var(--highlight-selector); +[vite:css][lightningcss] 'highlight' is not recognized as a valid pseudo-element. Did you mean ':highlight' (pseudo-class) or is this a typo? +550 | +551 | ::highlight(SelectorList), +552 | ::highlight(Selector) { + | ^ +553 | color: var(--highlight-selector); +554 | } +[vite:css][lightningcss] 'highlight' is not recognized as a valid pseudo-element. Did you mean ':highlight' (pseudo-class) or is this a typo? +554 | } +555 | +556 | ::highlight(AtrulePrelude), + | ^ +557 | ::highlight(Value) { +558 | color: var(--highlight-value); +[vite:css][lightningcss] 'highlight' is not recognized as a valid pseudo-element. Did you mean ':highlight' (pseudo-class) or is this a typo? +555 | +556 | ::highlight(AtrulePrelude), +557 | ::highlight(Value) { + | ^ +558 | color: var(--highlight-value); +559 | } +[vite:css][lightningcss] 'highlight' is not recognized as a valid pseudo-element. Did you mean ':highlight' (pseudo-class) or is this a typo? +559 | } +560 | +561 | ::highlight(Number) { + | ^ +562 | color: var(--highlight-number); +563 | } +[vite:css][lightningcss] 'highlight' is not recognized as a valid pseudo-element. Did you mean ':highlight' (pseudo-class) or is this a typo? +563 | } +564 | +565 | ::highlight(String) { + | ^ +566 | color: var(--highlight-string); +567 | } +[vite:css][lightningcss] 'highlight' is not recognized as a valid pseudo-element. Did you mean ':highlight' (pseudo-class) or is this a typo? +567 | } +568 | +569 | ::highlight(Comment) { + | ^ +570 | color: var(--highlight-comment); +571 | } +[vite:css][lightningcss] 'highlight' is not recognized as a valid pseudo-element. Did you mean ':highlight' (pseudo-class) or is this a typo? +1 | ::highlight(lint_lines), ::highlight(lint_selected_line) { + | ^ +2 | -webkit-text-decoration-color: var(--red-300); +3 | text-decoration-color: var(--red-300); +[vite:css][lightningcss] 'highlight' is not recognized as a valid pseudo-element. Did you mean ':highlight' (pseudo-class) or is this a typo? +1 | ::highlight(lint_lines), ::highlight(lint_selected_line) { + | ^ +2 | -webkit-text-decoration-color: var(--red-300); +3 | text-decoration-color: var(--red-300); +[vite:css][lightningcss] 'highlight' is not recognized as a valid pseudo-element. Did you mean ':highlight' (pseudo-class) or is this a typo? +6 | } +7 | +8 | ::highlight(lint_lines) { + | ^ +9 | background-color: #0000; +10 | } +[vite:css][lightningcss] 'highlight' is not recognized as a valid pseudo-element. Did you mean ':highlight' (pseudo-class) or is this a typo? +10 | } +11 | +12 | ::highlight(lint_selected_line) { + | ^ +13 | background-color: var(--highlight-code); +14 | } +[vite:css][lightningcss] 'highlight' is not recognized as a valid pseudo-element. Did you mean ':highlight' (pseudo-class) or is this a typo? +3 | } +4 | +5 | .svelte-il175y::highlight(lines) { + | ^ +6 | background-color: var(--highlight-code); +7 | } +[vite:css][lightningcss] 'highlight' is not recognized as a valid pseudo-element. Did you mean ':highlight' (pseudo-class) or is this a typo? +7 | } +8 | +9 | .svelte-il175y::highlight(selected_line) { + | ^ +10 | background-color: var(--highlight-code-selected); +11 | } +200 GET /lint-css +200 GET /_app/env.js +11:46:45 AM [vite] (client) [optimizer] bundling dependencies... +11:46:46 AM [vite] (client) dependency optimized: @oddbird/popover-polyfill/fn +11:46:46 AM [vite] (client) optimized dependencies changed. reloading +200 GET /lint-css +200 GET /_app/env.js +[vite:css][lightningcss] 'search-text' is not recognized as a valid pseudo-element. Did you mean ':search-text' (pseudo-class) or is this a typo? +463 | } +464 | +465 | ::search-text { + | ^ +466 | background: var(--yellow-400); +467 | color: var(--black); +[vite:css][lightningcss] 'search-text' is not recognized as a valid pseudo-element. Did you mean ':search-text' (pseudo-class) or is this a typo? +468 | } +469 | +470 | ::search-text:current { + | ^ +471 | background-color: var(--orange-400); +472 | color: var(--black); +[vite:css][lightningcss] 'highlight' is not recognized as a valid pseudo-element. Did you mean ':highlight' (pseudo-class) or is this a typo? +534 | } +535 | +536 | ::highlight(Property) { + | ^ +537 | color: var(--highlight-property); +538 | } +[vite:css][lightningcss] 'highlight' is not recognized as a valid pseudo-element. Did you mean ':highlight' (pseudo-class) or is this a typo? +538 | } +539 | +540 | ::highlight(AtruleName), + | ^ +541 | ::highlight(Function), +542 | ::highlight(Important) { +[vite:css][lightningcss] 'highlight' is not recognized as a valid pseudo-element. Did you mean ':highlight' (pseudo-class) or is this a typo? +539 | +540 | ::highlight(AtruleName), +541 | ::highlight(Function), + | ^ +542 | ::highlight(Important) { +543 | color: var(--highlight-atrule); +[vite:css][lightningcss] 'highlight' is not recognized as a valid pseudo-element. Did you mean ':highlight' (pseudo-class) or is this a typo? +540 | ::highlight(AtruleName), +541 | ::highlight(Function), +542 | ::highlight(Important) { + | ^ +543 | color: var(--highlight-atrule); +544 | } +[vite:css][lightningcss] 'highlight' is not recognized as a valid pseudo-element. Did you mean ':highlight' (pseudo-class) or is this a typo? +544 | } +545 | +546 | ::highlight(Unit), + | ^ +547 | ::highlight(Function) { +548 | color: var(--highlight-name); +[vite:css][lightningcss] 'highlight' is not recognized as a valid pseudo-element. Did you mean ':highlight' (pseudo-class) or is this a typo? +545 | +546 | ::highlight(Unit), +547 | ::highlight(Function) { + | ^ +548 | color: var(--highlight-name); +549 | } +[vite:css][lightningcss] 'highlight' is not recognized as a valid pseudo-element. Did you mean ':highlight' (pseudo-class) or is this a typo? +549 | } +550 | +551 | ::highlight(SelectorList), + | ^ +552 | ::highlight(Selector) { +553 | color: var(--highlight-selector); +[vite:css][lightningcss] 'highlight' is not recognized as a valid pseudo-element. Did you mean ':highlight' (pseudo-class) or is this a typo? +550 | +551 | ::highlight(SelectorList), +552 | ::highlight(Selector) { + | ^ +553 | color: var(--highlight-selector); +554 | } +[vite:css][lightningcss] 'highlight' is not recognized as a valid pseudo-element. Did you mean ':highlight' (pseudo-class) or is this a typo? +554 | } +555 | +556 | ::highlight(AtrulePrelude), + | ^ +557 | ::highlight(Value) { +558 | color: var(--highlight-value); +[vite:css][lightningcss] 'highlight' is not recognized as a valid pseudo-element. Did you mean ':highlight' (pseudo-class) or is this a typo? +555 | +556 | ::highlight(AtrulePrelude), +557 | ::highlight(Value) { + | ^ +558 | color: var(--highlight-value); +559 | } +[vite:css][lightningcss] 'highlight' is not recognized as a valid pseudo-element. Did you mean ':highlight' (pseudo-class) or is this a typo? +559 | } +560 | +561 | ::highlight(Number) { + | ^ +562 | color: var(--highlight-number); +563 | } +[vite:css][lightningcss] 'highlight' is not recognized as a valid pseudo-element. Did you mean ':highlight' (pseudo-class) or is this a typo? +563 | } +564 | +565 | ::highlight(String) { + | ^ +566 | color: var(--highlight-string); +567 | } +[vite:css][lightningcss] 'highlight' is not recognized as a valid pseudo-element. Did you mean ':highlight' (pseudo-class) or is this a typo? +567 | } +568 | +569 | ::highlight(Comment) { + | ^ +570 | color: var(--highlight-comment); +571 | } +[vite:css][lightningcss] 'global' is not recognized as a valid pseudo-class. Did you mean '::global' (pseudo-element) or is this a typo? +19 | } +20 | +21 | :global(.icon) { + | ^ +22 | margin-top: -4px; +23 | } +[vite:css][lightningcss] 'global' is not recognized as a valid pseudo-class. Did you mean '::global' (pseudo-element) or is this a typo? +15 | } +16 | +17 | :global(html:not([data-theme='naked'])) .logo { + | ^ +18 | &::after { +19 | content: 'W'; +[vite:css][lightningcss] 'global' is not recognized as a valid pseudo-class. Did you mean '::global' (pseudo-element) or is this a typo? +1 | +2 | /* stylelint-disable projectwallace/max-average-selector-complexity -- Global styling requires more complex selector... +3 | :global(.markdown :is(h1, h2, h3, h4)) { + | ^ +4 | line-height: var(--leading-none); +5 | } +[vite:css][lightningcss] 'global' is not recognized as a valid pseudo-class. Did you mean '::global' (pseudo-element) or is this a typo? +5 | } +6 | +7 | :global(.markdown :is(h1, h2, h3, h4) :any-link) { + | ^ +8 | text-decoration: none; +9 | color: inherit; +[vite:css][lightningcss] 'global' is not recognized as a valid pseudo-class. Did you mean '::global' (pseudo-element) or is this a typo? +10 | } +11 | +12 | :global(.markdown h1) { + | ^ +13 | font-size: var(--size-4xl); +14 | } +[vite:css][lightningcss] 'global' is not recognized as a valid pseudo-class. Did you mean '::global' (pseudo-element) or is this a typo? +14 | } +15 | +16 | :global(.markdown h2) { + | ^ +17 | font-size: var(--size-2xl); +18 | margin-top: var(--space-16); +[vite:css][lightningcss] 'global' is not recognized as a valid pseudo-class. Did you mean '::global' (pseudo-element) or is this a typo? +20 | } +21 | +22 | :global(.markdown h3) { + | ^ +23 | font-size: var(--size-xl); +24 | margin-top: var(--space-12); +[vite:css][lightningcss] 'global' is not recognized as a valid pseudo-class. Did you mean '::global' (pseudo-element) or is this a typo? +26 | } +27 | +28 | :global(.markdown h4) { + | ^ +29 | font-size: var(--size-base); +30 | margin-top: var(--space-12); +[vite:css][lightningcss] 'global' is not recognized as a valid pseudo-class. Did you mean '::global' (pseudo-element) or is this a typo? +32 | } +33 | +34 | :global(.markdown blockquote) { + | ^ +35 | background-color: var(--bg-200); +36 | padding-block: var(--space-4); +[vite:css][lightningcss] 'global' is not recognized as a valid pseudo-class. Did you mean '::global' (pseudo-element) or is this a typo? +41 | } +42 | +43 | :global(.markdown p) { + | ^ +44 | line-height: var(--leading-relaxed); +45 | max-width: 60ch; +[vite:css][lightningcss] 'global' is not recognized as a valid pseudo-class. Did you mean '::global' (pseudo-element) or is this a typo? +46 | } +47 | +48 | :global(.markdown svg[role='img']) { + | ^ +49 | max-width: 80ch; +50 | } +[vite:css][lightningcss] 'global' is not recognized as a valid pseudo-class. Did you mean '::global' (pseudo-element) or is this a typo? +50 | } +51 | +52 | :global(.markdown strong) { + | ^ +53 | font-style: normal; +54 | font-weight: var(--font-bold); +[vite:css][lightningcss] 'global' is not recognized as a valid pseudo-class. Did you mean '::global' (pseudo-element) or is this a typo? +56 | } +57 | +58 | :global(.markdown em) { + | ^ +59 | font-style: italic; +60 | } +[vite:css][lightningcss] 'global' is not recognized as a valid pseudo-class. Did you mean '::global' (pseudo-element) or is this a typo? +61 | +62 | /* stylelint-disable-next-line projectwallace/max-selector-complexity -- This is just a big one */ +63 | :global(.markdown :is(p, pre, img, table, ol, ul, blockquote, figure, iframe, math, .bar-chart)) { + | ^ +64 | margin-block-start: var(--space-6); +65 | +[vite:css][lightningcss] 'global' is not recognized as a valid pseudo-class. Did you mean '::global' (pseudo-element) or is this a typo? +69 | } +70 | +71 | :global(.markdown pre) { + | ^ +72 | background-color: var(--bg-200); +73 | padding-block: 1rem; +[vite:css][lightningcss] 'global' is not recognized as a valid pseudo-class. Did you mean '::global' (pseudo-element) or is this a typo? +92 | +93 | @media (min-width: 44rem) { +94 | :global(.markdown pre) { + | ^ +95 | padding-block: 0.75rem; +96 | padding-inline: 1rem; +[vite:css][lightningcss] 'global' is not recognized as a valid pseudo-class. Did you mean '::global' (pseudo-element) or is this a typo? +101 | +102 | @media (min-width: 66rem) { +103 | :global(.markdown pre) { + | ^ +104 | margin-right: calc(-1 * var(--space-8)); +105 | margin-left: calc(-1 * var(--space-8)); +[vite:css][lightningcss] 'global' is not recognized as a valid pseudo-class. Did you mean '::global' (pseudo-element) or is this a typo? +107 | } +108 | +109 | :global(.markdown pre code) { + | ^ +110 | background-color: transparent; +111 | } +[vite:css][lightningcss] 'global' is not recognized as a valid pseudo-class. Did you mean '::global' (pseudo-element) or is this a typo? +111 | } +112 | +113 | :global(.markdown ul) { + | ^ +114 | line-height: var(--leading-relaxed); +115 | } +[vite:css][lightningcss] 'global' is not recognized as a valid pseudo-class. Did you mean '::global' (pseudo-element) or is this a typo? +115 | } +116 | +117 | :global(.markdown li) { + | ^ +118 | margin-top: 0.75rem; +119 | max-width: 66ch; +[vite:css][lightningcss] 'global' is not recognized as a valid pseudo-class. Did you mean '::global' (pseudo-element) or is this a typo? +120 | } +121 | +122 | :global(.markdown ul li) { + | ^ +123 | list-style: square; +124 | margin-left: 2.25rem; +[vite:css][lightningcss] 'global' is not recognized as a valid pseudo-class. Did you mean '::global' (pseudo-element) or is this a typo? +125 | } +126 | +127 | :global(.markdown ol li) { + | ^ +128 | list-style: decimal; +129 | margin-left: 3rem; +[vite:css][lightningcss] 'global' is not recognized as a valid pseudo-class. Did you mean '::global' (pseudo-element) or is this a typo? +130 | } +131 | +132 | :global(.markdown ul li::marker) { + | ^ +133 | color: var(--accent-500); +134 | } +[vite:css][lightningcss] 'global' is not recognized as a valid pseudo-class. Did you mean '::global' (pseudo-element) or is this a typo? +134 | } +135 | +136 | :global(.markdown ol li::marker) { + | ^ +137 | color: var(--fg-400); +138 | font-weight: var(--font-bold); +[vite:css][lightningcss] 'global' is not recognized as a valid pseudo-class. Did you mean '::global' (pseudo-element) or is this a typo? +141 | } +142 | +143 | :global(.markdown :where(:any-link)), + | ^ +144 | :global(.markdown :where(:any-link code)) { +145 | color: light-dark(var(--accent-800), var(--accent-300)); +[vite:css][lightningcss] 'global' is not recognized as a valid pseudo-class. Did you mean '::global' (pseudo-element) or is this a typo? +142 | +143 | :global(.markdown :where(:any-link)), +144 | :global(.markdown :where(:any-link code)) { + | ^ +145 | color: light-dark(var(--accent-800), var(--accent-300)); +146 | text-decoration: underline; +[vite:css][lightningcss] 'global' is not recognized as a valid pseudo-class. Did you mean '::global' (pseudo-element) or is this a typo? +148 | } +149 | +150 | :global(.markdown table) { + | ^ +151 | --cell-spacing: 0.75rem; +152 | border-spacing: 0; +[vite:css][lightningcss] 'global' is not recognized as a valid pseudo-class. Did you mean '::global' (pseudo-element) or is this a typo? +157 | } +158 | +159 | :global(.markdown th) { + | ^ +160 | text-align: left; +161 | font-family: var(--font-body); +[vite:css][lightningcss] 'global' is not recognized as a valid pseudo-class. Did you mean '::global' (pseudo-element) or is this a typo? +166 | } +167 | +168 | :global(.markdown tbody tr:nth-child(2n + 1)) { + | ^ +169 | background-color: var(--uneven-tr-bg); +170 | } +[vite:css][lightningcss] 'global' is not recognized as a valid pseudo-class. Did you mean '::global' (pseudo-element) or is this a typo? +170 | } +171 | +172 | :global(.markdown td) { + | ^ +173 | padding: var(--cell-spacing); +174 | } +[vite:css][lightningcss] 'global' is not recognized as a valid pseudo-class. Did you mean '::global' (pseudo-element) or is this a typo? +174 | } +175 | +176 | :global(.markdown :is(th, td):not(:first-child)) { + | ^ +177 | text-align: right; +178 | } +[vite:css][lightningcss] 'global' is not recognized as a valid pseudo-class. Did you mean '::global' (pseudo-element) or is this a typo? +178 | } +179 | +180 | :global(.markdown img) { + | ^ +181 | box-shadow: var(--shadow); +182 | border: 1px solid var(--fg-700); +[vite:css][lightningcss] 'global' is not recognized as a valid pseudo-class. Did you mean '::global' (pseudo-element) or is this a typo? +183 | } +184 | +185 | :global(.markdown code) { + | ^ +186 | font-size: var(--size-smaller); +187 | } +[vite:css][lightningcss] 'global' is not recognized as a valid pseudo-class. Did you mean '::global' (pseudo-element) or is this a typo? +187 | } +188 | +189 | :global(.markdown :is(p, li, figcaption) code) { + | ^ +190 | display: inline-block; +191 | margin-right: 0.25ch; +[vite:css][lightningcss] 'global' is not recognized as a valid pseudo-class. Did you mean '::global' (pseudo-element) or is this a typo? +195 | } +196 | +197 | :global(.markdown pre code) { + | ^ +198 | color: var(--fg-200); +199 | } +[vite:css][lightningcss] 'global' is not recognized as a valid pseudo-class. Did you mean '::global' (pseudo-element) or is this a typo? +199 | } +200 | +201 | :global(.markdown aside) { + | ^ +202 | margin-block: var(--space-16); +203 | } +[vite:css][lightningcss] 'global' is not recognized as a valid pseudo-class. Did you mean '::global' (pseudo-element) or is this a typo? +203 | } +204 | +205 | :global(.markdown aside):not([class]) { + | ^ +206 | border: 2px solid var(--accent-800); +207 | padding-block: var(--space-6); +[vite:css][lightningcss] 'global' is not recognized as a valid pseudo-class. Did you mean '::global' (pseudo-element) or is this a typo? +209 | } +210 | +211 | :global(.markdown :is(aside, blockquote) > :first-child) { + | ^ +212 | margin-top: 0; +213 | } +[vite:css][lightningcss] 'global' is not recognized as a valid pseudo-class. Did you mean '::global' (pseudo-element) or is this a typo? +213 | } +214 | +215 | :global(.markdown :is(aside, blockquote) > :last-child) { + | ^ +216 | margin-bottom: 0; +217 | } +[vite:css][lightningcss] 'global' is not recognized as a valid pseudo-class. Did you mean '::global' (pseudo-element) or is this a typo? +217 | } +218 | +219 | :global(.markdown figcaption) { + | ^ +220 | text-align: center; +221 | font-size: var(--size-base); +[vite:css][lightningcss] 'global' is not recognized as a valid pseudo-class. Did you mean '::global' (pseudo-element) or is this a typo? +224 | } +225 | +226 | :global(.markdown hr) { + | ^ +227 | border-block-start: 1px solid var(--gray-500); +228 | margin-block: var(--space-16); +[vite:css][lightningcss] 'global' is not recognized as a valid pseudo-class. Did you mean '::global' (pseudo-element) or is this a typo? +17 | font-size: var(--pw-table-font-size); +18 | +19 | & :global(thead tr) { + | ^ +20 | position: sticky; +21 | top: 0; +[vite:css][lightningcss] 'global' is not recognized as a valid pseudo-class. Did you mean '::global' (pseudo-element) or is this a typo? +26 | } +27 | +28 | & :global(th:not([scope='row' i])) { + | ^ +29 | font-weight: var(--font-bold); +30 | } +[vite:css][lightningcss] 'global' is not recognized as a valid pseudo-class. Did you mean '::global' (pseudo-element) or is this a typo? +30 | } +31 | +32 | & :global(th[scope='row' i]) { + | ^ +33 | font-weight: var(--font-normal); +34 | } +[vite:css][lightningcss] 'global' is not recognized as a valid pseudo-class. Did you mean '::global' (pseudo-element) or is this a typo? +34 | } +35 | +36 | & :global(:is(th, td)) { + | ^ +37 | text-align: start; +38 | padding-block: var(--pw-table-padding-block); +[vite:css][lightningcss] 'global' is not recognized as a valid pseudo-class. Did you mean '::global' (pseudo-element) or is this a typo? +40 | } +41 | +42 | & :global(td:not(:first-child)) { + | ^ +43 | border-inline-start: 1px solid var(--fg-500); +44 | } +[vite:css][lightningcss] 'global' is not recognized as a valid pseudo-class. Did you mean '::global' (pseudo-element) or is this a typo? +44 | } +45 | +46 | & :global(th), + | ^ +47 | & :global(td:first-child) { +48 | white-space: nowrap; +[vite:css][lightningcss] 'global' is not recognized as a valid pseudo-class. Did you mean '::global' (pseudo-element) or is this a typo? +45 | +46 | & :global(th), +47 | & :global(td:first-child) { + | ^ +48 | white-space: nowrap; +49 | } +[vite:css][lightningcss] 'global' is not recognized as a valid pseudo-class. Did you mean '::global' (pseudo-element) or is this a typo? +49 | } +50 | +51 | & :global(:where(tr:nth-child(even))) { + | ^ +52 | background-color: var(--uneven-tr-bg); +53 | } +[vite:css][lightningcss] 'global' is not recognized as a valid pseudo-class. Did you mean '::global' (pseudo-element) or is this a typo? +53 | } +54 | +55 | & :global(td) { + | ^ +56 | line-height: var(--leading-snug); +57 | vertical-align: baseline; +[vite:css][lightningcss] 'global' is not recognized as a valid pseudo-class. Did you mean '::global' (pseudo-element) or is this a typo? +58 | } +59 | +60 | & :global(.numeric) { + | ^ +61 | text-align: end; +62 | white-space: nowrap; +[vite:css][lightningcss] 'global' is not recognized as a valid pseudo-class. Did you mean '::global' (pseudo-element) or is this a typo? +1 | +2 | /* stylelint-disable projectwallace/max-average-selector-complexity -- highlight pseudo-elements inflate complexity */ +3 | :global(::highlight(lint_lines), ::highlight(lint_selected_line)) { + | ^ +4 | text-decoration-color: var(--red-300); +5 | text-decoration-style: wavy; +[vite:css][lightningcss] 'global' is not recognized as a valid pseudo-class. Did you mean '::global' (pseudo-element) or is this a typo? +7 | } +8 | +9 | :global(::highlight(lint_lines)) { + | ^ +10 | background-color: transparent; +11 | } +[vite:css][lightningcss] 'global' is not recognized as a valid pseudo-class. Did you mean '::global' (pseudo-element) or is this a typo? +11 | } +12 | +13 | :global(::highlight(lint_selected_line)) { + | ^ +14 | background-color: var(--highlight-code); +15 | } +[vite:css][lightningcss] 'global' is not recognized as a valid pseudo-class. Did you mean '::global' (pseudo-element) or is this a typo? +91 | font-size: var(--size-lg); +92 | +93 | & :global(.icon) { + | ^ +94 | margin-block-start: -0.2em; +95 | zoom: 1.2; +[vite:css][lightningcss] 'global' is not recognized as a valid pseudo-class. Did you mean '::global' (pseudo-element) or is this a typo? +34 | } +35 | +36 | .pane-header :global(.pane-title) { + | ^ +37 | font-weight: var(--font-bold); +38 | margin-inline-end: auto; +[vite:css][lightningcss] 'highlight' is not recognized as a valid pseudo-element. Did you mean ':highlight' (pseudo-class) or is this a typo? +1 | ::highlight(lint_lines), ::highlight(lint_selected_line) { + | ^ +2 | -webkit-text-decoration-color: var(--red-300); +3 | text-decoration-color: var(--red-300); +[vite:css][lightningcss] 'highlight' is not recognized as a valid pseudo-element. Did you mean ':highlight' (pseudo-class) or is this a typo? +1 | ::highlight(lint_lines), ::highlight(lint_selected_line) { + | ^ +2 | -webkit-text-decoration-color: var(--red-300); +3 | text-decoration-color: var(--red-300); +[vite:css][lightningcss] 'highlight' is not recognized as a valid pseudo-element. Did you mean ':highlight' (pseudo-class) or is this a typo? +6 | } +7 | +8 | ::highlight(lint_lines) { + | ^ +9 | background-color: #0000; +10 | } +[vite:css][lightningcss] 'highlight' is not recognized as a valid pseudo-element. Did you mean ':highlight' (pseudo-class) or is this a typo? +10 | } +11 | +12 | ::highlight(lint_selected_line) { + | ^ +13 | background-color: var(--highlight-code); +14 | } +[vite:css][lightningcss] 'highlight' is not recognized as a valid pseudo-element. Did you mean ':highlight' (pseudo-class) or is this a typo? +4 | } +5 | +6 | ::highlight(lines) { + | ^ +7 | background-color: var(--highlight-code); +8 | } +[vite:css][lightningcss] 'highlight' is not recognized as a valid pseudo-element. Did you mean ':highlight' (pseudo-class) or is this a typo? +8 | } +9 | +10 | ::highlight(selected_line) { + | ^ +11 | background-color: var(--highlight-code-selected); +12 | } +[vite:css][lightningcss] 'highlight' is not recognized as a valid pseudo-element. Did you mean ':highlight' (pseudo-class) or is this a typo? +3 | } +4 | +5 | .svelte-il175y::highlight(lines) { + | ^ +6 | background-color: var(--highlight-code); +7 | } +[vite:css][lightningcss] 'highlight' is not recognized as a valid pseudo-element. Did you mean ':highlight' (pseudo-class) or is this a typo? +7 | } +8 | +9 | .svelte-il175y::highlight(selected_line) { + | ^ +10 | background-color: var(--highlight-code-selected); +11 | } +11:46:47 AM [vite] (client) [console.warn] Module "path" has been externalized for browser compatibility. Cannot access "path.isAbsolute" in client code. See https://vite.dev/guide/troubleshooting.html#module-externalized-for-browser-compatibility for more details. +11:46:47 AM [vite] (client) [console.warn] Module "path" has been externalized for browser compatibility. Cannot access "path.resolve" in client code. See https://vite.dev/guide/troubleshooting.html#module-externalized-for-browser-compatibility for more details. +11:46:47 AM [vite] (client) [console.warn] Module "source-map-js" has been externalized for browser compatibility. Cannot access "source-map-js.SourceMapConsumer" in client code. See https://vite.dev/guide/troubleshooting.html#module-externalized-for-browser-compatibility for more details. +11:46:47 AM [vite] (client) [console.warn] Module "source-map-js" has been externalized for browser compatibility. Cannot access "source-map-js.SourceMapGenerator" in client code. See https://vite.dev/guide/troubleshooting.html#module-externalized-for-browser-compatibility for more details. +11:46:47 AM [vite] (client) [console.warn] Module "url" has been externalized for browser compatibility. Cannot access "url.fileURLToPath" in client code. See https://vite.dev/guide/troubleshooting.html#module-externalized-for-browser-compatibility for more details. +11:46:47 AM [vite] (client) [console.warn] Module "url" has been externalized for browser compatibility. Cannot access "url.pathToFileURL" in client code. See https://vite.dev/guide/troubleshooting.html#module-externalized-for-browser-compatibility for more details. +11:46:47 AM [vite] (client) [console.warn] Module "fs" has been externalized for browser compatibility. Cannot access "fs.existsSync" in client code. See https://vite.dev/guide/troubleshooting.html#module-externalized-for-browser-compatibility for more details. +11:46:47 AM [vite] (client) [console.warn] Module "fs" has been externalized for browser compatibility. Cannot access "fs.readFileSync" in client code. See https://vite.dev/guide/troubleshooting.html#module-externalized-for-browser-compatibility for more details. +11:46:47 AM [vite] (client) [console.warn] Module "fs" has been externalized for browser compatibility. Cannot access "fs.realpathSync" in client code. See https://vite.dev/guide/troubleshooting.html#module-externalized-for-browser-compatibility for more details. +11:46:47 AM [vite] (client) [console.warn] Module "path" has been externalized for browser compatibility. Cannot access "path.dirname" in client code. See https://vite.dev/guide/troubleshooting.html#module-externalized-for-browser-compatibility for more details. +11:46:47 AM [vite] (client) [console.warn] Module "path" has been externalized for browser compatibility. Cannot access "path.isAbsolute" in client code. See https://vite.dev/guide/troubleshooting.html#module-externalized-for-browser-compatibility for more details. +11:46:47 AM [vite] (client) [console.warn] Module "path" has been externalized for browser compatibility. Cannot access "path.join" in client code. See https://vite.dev/guide/troubleshooting.html#module-externalized-for-browser-compatibility for more details. +11:46:47 AM [vite] (client) [console.warn] Module "path" has been externalized for browser compatibility. Cannot access "path.relative" in client code. See https://vite.dev/guide/troubleshooting.html#module-externalized-for-browser-compatibility for more details. +11:46:47 AM [vite] (client) [console.warn] Module "path" has been externalized for browser compatibility. Cannot access "path.sep" in client code. See https://vite.dev/guide/troubleshooting.html#module-externalized-for-browser-compatibility for more details. +11:46:47 AM [vite] (client) [console.warn] Module "source-map-js" has been externalized for browser compatibility. Cannot access "source-map-js.SourceMapConsumer" in client code. See https://vite.dev/guide/troubleshooting.html#module-externalized-for-browser-compatibility for more details. +11:46:47 AM [vite] (client) [console.warn] Module "source-map-js" has been externalized for browser compatibility. Cannot access "source-map-js.SourceMapGenerator" in client code. See https://vite.dev/guide/troubleshooting.html#module-externalized-for-browser-compatibility for more details. +11:46:47 AM [vite] (client) [console.warn] Module "path" has been externalized for browser compatibility. Cannot access "path.dirname" in client code. See https://vite.dev/guide/troubleshooting.html#module-externalized-for-browser-compatibility for more details. +11:46:47 AM [vite] (client) [console.warn] Module "path" has been externalized for browser compatibility. Cannot access "path.relative" in client code. See https://vite.dev/guide/troubleshooting.html#module-externalized-for-browser-compatibility for more details. +11:46:47 AM [vite] (client) [console.warn] Module "path" has been externalized for browser compatibility. Cannot access "path.resolve" in client code. See https://vite.dev/guide/troubleshooting.html#module-externalized-for-browser-compatibility for more details. +11:46:47 AM [vite] (client) [console.warn] Module "path" has been externalized for browser compatibility. Cannot access "path.sep" in client code. See https://vite.dev/guide/troubleshooting.html#module-externalized-for-browser-compatibility for more details. +11:46:47 AM [vite] (client) [console.warn] Module "source-map-js" has been externalized for browser compatibility. Cannot access "source-map-js.SourceMapConsumer" in client code. See https://vite.dev/guide/troubleshooting.html#module-externalized-for-browser-compatibility for more details. +11:46:47 AM [vite] (client) [console.warn] Module "source-map-js" has been externalized for browser compatibility. Cannot access "source-map-js.SourceMapGenerator" in client code. See https://vite.dev/guide/troubleshooting.html#module-externalized-for-browser-compatibility for more details. +11:46:47 AM [vite] (client) [console.warn] Module "url" has been externalized for browser compatibility. Cannot access "url.pathToFileURL" in client code. See https://vite.dev/guide/troubleshooting.html#module-externalized-for-browser-compatibility for more details. +11:46:48 AM [vite] (client) [Unhandled error] Error: ResizeObserver loop completed with undelivered notifications. + > ../../../@vite/client:535:50 + +The file does not exist at "/home/user/projectwallace.com/node_modules/.vite/deps/max-nesting-depth/index.mjs" which is in the optimize deps directory. The dependency might be incompatible with the dep optimizer. Try adding it to `optimizeDeps.exclude`. +11:46:48 AM [vite] (client) [console.error] DEBUG run_lint error: TypeError: Failed to fetch dynamically imported module: http://localhost:5186/node_modules/.vite/deps/max-nesting-depth/index.mjs +11:46:58 AM [vite] (client) [console.error] DEBUG run_lint error: TypeError: Failed to fetch dynamically imported module: http://localhost:5186/node_modules/.vite/deps/max-nesting-depth/index.mjs +11:46:59 AM [vite] (client) [console.error] DEBUG run_lint error: TypeError: Failed to fetch dynamically imported module: http://localhost:5186/node_modules/.vite/deps/max-nesting-depth/index.mjs +200 GET /lint-css +200 GET /_app/env.js +11:47:01 AM [vite] (client) [console.warn] Module "path" has been externalized for browser compatibility. Cannot access "path.isAbsolute" in client code. See https://vite.dev/guide/troubleshooting.html#module-externalized-for-browser-compatibility for more details. +11:47:01 AM [vite] (client) [console.warn] Module "path" has been externalized for browser compatibility. Cannot access "path.resolve" in client code. See https://vite.dev/guide/troubleshooting.html#module-externalized-for-browser-compatibility for more details. +11:47:01 AM [vite] (client) [console.warn] Module "source-map-js" has been externalized for browser compatibility. Cannot access "source-map-js.SourceMapConsumer" in client code. See https://vite.dev/guide/troubleshooting.html#module-externalized-for-browser-compatibility for more details. +11:47:01 AM [vite] (client) [console.warn] Module "source-map-js" has been externalized for browser compatibility. Cannot access "source-map-js.SourceMapGenerator" in client code. See https://vite.dev/guide/troubleshooting.html#module-externalized-for-browser-compatibility for more details. +11:47:01 AM [vite] (client) [console.warn] Module "url" has been externalized for browser compatibility. Cannot access "url.fileURLToPath" in client code. See https://vite.dev/guide/troubleshooting.html#module-externalized-for-browser-compatibility for more details. +11:47:01 AM [vite] (client) [console.warn] Module "url" has been externalized for browser compatibility. Cannot access "url.pathToFileURL" in client code. See https://vite.dev/guide/troubleshooting.html#module-externalized-for-browser-compatibility for more details. +11:47:01 AM [vite] (client) [console.warn] Module "fs" has been externalized for browser compatibility. Cannot access "fs.existsSync" in client code. See https://vite.dev/guide/troubleshooting.html#module-externalized-for-browser-compatibility for more details. +11:47:01 AM [vite] (client) [console.warn] Module "fs" has been externalized for browser compatibility. Cannot access "fs.readFileSync" in client code. See https://vite.dev/guide/troubleshooting.html#module-externalized-for-browser-compatibility for more details. +11:47:01 AM [vite] (client) [console.warn] Module "fs" has been externalized for browser compatibility. Cannot access "fs.realpathSync" in client code. See https://vite.dev/guide/troubleshooting.html#module-externalized-for-browser-compatibility for more details. +11:47:01 AM [vite] (client) [console.warn] Module "path" has been externalized for browser compatibility. Cannot access "path.dirname" in client code. See https://vite.dev/guide/troubleshooting.html#module-externalized-for-browser-compatibility for more details. +11:47:01 AM [vite] (client) [console.warn] Module "path" has been externalized for browser compatibility. Cannot access "path.isAbsolute" in client code. See https://vite.dev/guide/troubleshooting.html#module-externalized-for-browser-compatibility for more details. +11:47:01 AM [vite] (client) [console.warn] Module "path" has been externalized for browser compatibility. Cannot access "path.join" in client code. See https://vite.dev/guide/troubleshooting.html#module-externalized-for-browser-compatibility for more details. +11:47:01 AM [vite] (client) [console.warn] Module "path" has been externalized for browser compatibility. Cannot access "path.relative" in client code. See https://vite.dev/guide/troubleshooting.html#module-externalized-for-browser-compatibility for more details. +11:47:01 AM [vite] (client) [console.warn] Module "path" has been externalized for browser compatibility. Cannot access "path.sep" in client code. See https://vite.dev/guide/troubleshooting.html#module-externalized-for-browser-compatibility for more details. +11:47:01 AM [vite] (client) [console.warn] Module "source-map-js" has been externalized for browser compatibility. Cannot access "source-map-js.SourceMapConsumer" in client code. See https://vite.dev/guide/troubleshooting.html#module-externalized-for-browser-compatibility for more details. +11:47:01 AM [vite] (client) [console.warn] Module "source-map-js" has been externalized for browser compatibility. Cannot access "source-map-js.SourceMapGenerator" in client code. See https://vite.dev/guide/troubleshooting.html#module-externalized-for-browser-compatibility for more details. +11:47:01 AM [vite] (client) [console.warn] Module "path" has been externalized for browser compatibility. Cannot access "path.dirname" in client code. See https://vite.dev/guide/troubleshooting.html#module-externalized-for-browser-compatibility for more details. +11:47:01 AM [vite] (client) [console.warn] Module "path" has been externalized for browser compatibility. Cannot access "path.relative" in client code. See https://vite.dev/guide/troubleshooting.html#module-externalized-for-browser-compatibility for more details. +11:47:01 AM [vite] (client) [console.warn] Module "path" has been externalized for browser compatibility. Cannot access "path.resolve" in client code. See https://vite.dev/guide/troubleshooting.html#module-externalized-for-browser-compatibility for more details. +11:47:01 AM [vite] (client) [console.warn] Module "path" has been externalized for browser compatibility. Cannot access "path.sep" in client code. See https://vite.dev/guide/troubleshooting.html#module-externalized-for-browser-compatibility for more details. +11:47:01 AM [vite] (client) [console.warn] Module "source-map-js" has been externalized for browser compatibility. Cannot access "source-map-js.SourceMapConsumer" in client code. See https://vite.dev/guide/troubleshooting.html#module-externalized-for-browser-compatibility for more details. +11:47:01 AM [vite] (client) [console.warn] Module "source-map-js" has been externalized for browser compatibility. Cannot access "source-map-js.SourceMapGenerator" in client code. See https://vite.dev/guide/troubleshooting.html#module-externalized-for-browser-compatibility for more details. +11:47:01 AM [vite] (client) [console.warn] Module "url" has been externalized for browser compatibility. Cannot access "url.pathToFileURL" in client code. See https://vite.dev/guide/troubleshooting.html#module-externalized-for-browser-compatibility for more details. +11:47:01 AM [vite] (client) [Unhandled error] Error: ResizeObserver loop completed with undelivered notifications. + > ../../../@vite/client:535:50 + +The file does not exist at "/home/user/projectwallace.com/node_modules/.vite/deps/max-nesting-depth/index.mjs" which is in the optimize deps directory. The dependency might be incompatible with the dep optimizer. Try adding it to `optimizeDeps.exclude`. +11:47:01 AM [vite] (client) [console.error] DEBUG run_lint error: TypeError: Failed to fetch dynamically imported module: http://localhost:5186/node_modules/.vite/deps/max-nesting-depth/index.mjs diff --git a/vite.config.js b/vite.config.js index 39b7e0db..0c6000dc 100644 --- a/vite.config.js +++ b/vite.config.js @@ -6,6 +6,68 @@ import { /** @type {import('vite').UserConfig} */ preprocessMeltUI } from '@melt import { sveltekit } from '@sveltejs/kit/vite' import { enhancedImages } from '@sveltejs/enhanced-img' import { Features } from 'lightningcss' +import { fileURLToPath } from 'node:url' + +const stylelint_lib_dir = fileURLToPath(new URL('./node_modules/stylelint/lib/', import.meta.url)) +const stylelint_browser_dir = fileURLToPath(new URL('./src/lib/stylelint-browser/', import.meta.url)) + +// stylelint's package.json `exports` map only publishes `.`, `./package.json` +// and `./lib/utils/*`. src/lib/stylelint-browser/lint.ts deep-imports a few +// unpublished internals on purpose (see that file's header comment) - point +// those specifiers straight at the real files on disk so bundling and +// type-checking (via stylelint-internals.d.ts) both work. +// +// These use `resolve.alias` (not a custom plugin `resolveId` hook) because +// Vite's dependency optimizer pre-bundles reachable node_modules packages +// with esbuild directly, ahead of the normal plugin pipeline, and only +// honours declarative aliases - a custom resolver here would be silently +// skipped during that pre-bundling pass. +// +// Nothing server-side imports real `stylelint`/`node:os`/`node:process` +// anymore (linting is client-only), so these aliases apply everywhere rather +// than being scoped to the client build - simpler, and harmless for SSR +// since this code only ever executes in the browser (see the `browser` guard +// in Linter.svelte) and just needs to *resolve* for the SSR bundle. +const config_alias = [ + // Unpublished internals, aliased to the real files on disk. + { find: 'stylelint/lib/lintPostcssResult.mjs', replacement: stylelint_lib_dir + 'lintPostcssResult.mjs' }, + { + find: 'stylelint/lib/normalizeAllRuleSettings.mjs', + replacement: stylelint_lib_dir + 'normalizeAllRuleSettings.mjs' + }, + { + find: 'stylelint/lib/createPartialStylelintResult.mjs', + replacement: stylelint_lib_dir + 'createPartialStylelintResult.mjs' + }, + { find: 'stylelint/lib/prepareReturnValue.mjs', replacement: stylelint_lib_dir + 'prepareReturnValue.mjs' }, + { + find: 'stylelint/lib/formatters/jsonFormatter.mjs', + replacement: stylelint_lib_dir + 'formatters/jsonFormatter.mjs' + }, + + // lintPostcssResult.mjs's own `./timing.mjs` import drags in the `table` + // package (for `TIMING= stylelint ...` CLI output we never trigger), + // which doesn't bundle for the browser. See shims/stylelint-timing.ts. + { find: './timing.mjs', replacement: stylelint_browser_dir + 'shims/stylelint-timing.ts' }, + + // lib/{lintPostcssResult,reportUnknownRuleNames}.mjs import this as + // `./rules/index.mjs`; lib/utils/getStylelintRule.mjs imports the same + // file as `../rules/index.mjs`. Both specifiers need aliasing - see + // shims/stylelint-rules.ts for why the real file can't be used as-is. + { find: './rules/index.mjs', replacement: stylelint_browser_dir + 'shims/stylelint-rules.ts' }, + { find: '../rules/index.mjs', replacement: stylelint_browser_dir + 'shims/stylelint-rules.ts' }, + + // Node-free stand-ins for bare specifiers stylelint's internals (and our + // plugin package) import. + { find: 'node:os', replacement: stylelint_browser_dir + 'shims/node-os.ts' }, + { find: 'node:process', replacement: stylelint_browser_dir + 'shims/node-process.ts' }, + // `find` must be an exact-match regex here, not the plain string + // shorthand: Vite's aliasing treats a bare string `find` as a *prefix* + // (so it'd also rewrite real subpaths like `stylelint/lib/utils/report.mjs` + // to `.../stylelint-shim.ts/lib/utils/report.mjs`), which those subpaths + // need to keep resolving to the real, publicly-exported package files. + { find: /^stylelint$/, replacement: stylelint_browser_dir + 'stylelint-shim.ts' } +] const config = { plugins: [ @@ -39,6 +101,9 @@ const config = { } }) ], + resolve: { + alias: config_alias + }, css: { transformer: 'lightningcss', lightningcss: {