{"_id":"tw-fade","_rev":"8-225bb299719c2b07a8f089e49a4a1b18","name":"tw-fade","dist-tags":{"latest":"0.8.0"},"versions":{"0.1.0":{"name":"tw-fade","version":"0.1.0","keywords":["tailwindcss","tailwind-plugin","scroll","fade","mask","scroll-driven-animations","scrim","edge-fade","overflow"],"author":{"name":"Pete Petrash"},"license":"MIT","_id":"tw-fade@0.1.0","maintainers":[{"name":"petepetrash","email":"pete.petrash@gmail.com"}],"dist":{"shasum":"7340bff83213d492f5efcfc0da159dbffe473c06","tarball":"https://registry.npmjs.org/tw-fade/-/tw-fade-0.1.0.tgz","fileCount":5,"integrity":"sha512-hRttIh9WoOOpmFt9RkJvnGCiNEm0Fldht8Fr9tyZZ8/CdhoI+6DFQtW+DYfXWLUC8TQW/ksWXi5h7Q2U4r1kng==","signatures":[{"sig":"MEYCIQD5ep4lauSs7JzVbiN0mnVMoXCikLqH2/MxxL+6JE9FIAIhANWjHHT1FkmwChhw0QC3dinmwZhXs3IegAIllFmTfrTN","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":44831},"main":"./src/index.js","type":"commonjs","exports":{".":{"import":"./src/index.js","default":"./src/index.js","require":"./src/index.js"},"./css":"./dist/tw-fade.css","./package.json":"./package.json","./dist/tw-fade.css":"./dist/tw-fade.css"},"scripts":{"test":"node --test","build":"node scripts/build-css.mjs","verify":"node build/verify.mjs && node build/verify-dist.mjs && node build/verify-fade.mjs && node build/verify-page.mjs","build:demo":"tailwind -c tailwind.config.js -i demo/input.css -o demo/styles.css","prepublishOnly":"node scripts/build-css.mjs && node --test"},"_npmUser":{"name":"petepetrash","email":"pete.petrash@gmail.com"},"_npmVersion":"11.13.0","description":"Elegant, CSS-driven scroll-edge fade masking for Tailwind CSS. Add fade-t/b/l/r (or -x/-y) to any scroll container to fade content into its surface at the edges — scroll-gated with zero JavaScript.","directories":{},"_nodeVersion":"24.16.0","_hasShrinkwrap":false,"devDependencies":{"playwright":"^1.61.0","tailwindcss":"^3.4.0","@tailwindcss/cli":"^4.0.0"},"peerDependencies":{"tailwindcss":">=3.4.0"},"peerDependenciesMeta":{"tailwindcss":{"optional":true}},"_npmOperationalInternal":{"tmp":"tmp/tw-fade_0.1.0_1781660351547_0.8319768439935993","host":"s3://npm-registry-packages-npm-production"}},"0.2.0":{"name":"tw-fade","version":"0.2.0","keywords":["tailwindcss","tailwind-plugin","tailwindcss-v4","scroll","fade","mask","scroll-driven-animations","scrim","edge-fade","overflow"],"author":{"name":"Pete Petrash"},"license":"MIT","_id":"tw-fade@0.2.0","maintainers":[{"name":"petepetrash","email":"pete.petrash@gmail.com"}],"homepage":"https://github.com/petekp/tw-fade#readme","bugs":{"url":"https://github.com/petekp/tw-fade/issues"},"dist":{"shasum":"f9dc135e08e1db4a38898063d9f8f3ea7632cd6e","tarball":"https://registry.npmjs.org/tw-fade/-/tw-fade-0.2.0.tgz","fileCount":5,"integrity":"sha512-Pm9ozEG0+yTrdDS9LU9IablBBUOnf8MCkCwSWREP1ydXx4ykB/FxhGUlKbi6QbU2CkQQpQLjjJ9IWyjgO3+VMg==","signatures":[{"sig":"MEQCIBAMfBiw6j+Zql9HLvrKfW3z6tglgAqhNymLlAaTpklNAiANJInC4HySxh0y3TwEEvl7ugL1TebkeFcOvIXbTZc8ng==","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":50200},"style":"./dist/tw-fade.css","exports":{".":"./src/tw-fade.css","./css":"./dist/tw-fade.css","./package.json":"./package.json","./dist/tw-fade.css":"./dist/tw-fade.css"},"gitHead":"2b9beafa6415b48a123ab1e84f00d213a0009554","scripts":{"test":"node --test","build":"node scripts/build-css.mjs","verify":"node build/verify.mjs && node build/verify-dist.mjs && node build/verify-fade.mjs && node build/verify-page.mjs","build:demo":"tailwindcss -i demo/input.css -o demo/styles.css","prepublishOnly":"node scripts/build-css.mjs && node --test"},"_npmUser":{"name":"petepetrash","email":"pete.petrash@gmail.com"},"repository":{"url":"git+https://github.com/petekp/tw-fade.git","type":"git"},"_npmVersion":"11.13.0","description":"Elegant, CSS-driven scroll-edge fade masking for Tailwind CSS v4. Add fade-t/b/l/r (or -x/-y/-xy) to any scroll container to fade content into its surface at the edges — scroll-gated with zero JavaScript.","directories":{},"_nodeVersion":"24.16.0","_hasShrinkwrap":false,"devDependencies":{"playwright":"^1.61.0","tailwindcss":"^4.3.1","@tailwindcss/cli":"^4.0.0"},"peerDependencies":{"tailwindcss":">=4.0.0"},"peerDependenciesMeta":{"tailwindcss":{"optional":true}},"_npmOperationalInternal":{"tmp":"tmp/tw-fade_0.2.0_1781722862807_0.5842824202215704","host":"s3://npm-registry-packages-npm-production"}},"0.3.0":{"name":"tw-fade","version":"0.3.0","keywords":["tailwindcss","tailwind-plugin","tailwindcss-v4","scroll","fade","mask","scroll-driven-animations","scrim","edge-fade","overflow"],"author":{"name":"Pete Petrash"},"license":"MIT","_id":"tw-fade@0.3.0","maintainers":[{"name":"petepetrash","email":"pete.petrash@gmail.com"}],"homepage":"https://github.com/petekp/tw-fade#readme","bugs":{"url":"https://github.com/petekp/tw-fade/issues"},"dist":{"shasum":"47d63a69eab57aa99f1af253b5857aef982a858d","tarball":"https://registry.npmjs.org/tw-fade/-/tw-fade-0.3.0.tgz","fileCount":5,"integrity":"sha512-5Iht3SsUrL73OMEvkplE+n0fwfYV1+jDXGeYWUf8W2mHR29m/LIRhdeU1x4rs6/28JhfW90ZQq0yJM/31YEfTQ==","signatures":[{"sig":"MEUCIQDuzP7+tGmRLSZX6z7FYOEHouB9YKi61rrZSNMQoRUnXwIgX2KY6n/YZ1mUueHLnx5j5XRFvWp7Np96MLY4YFfcA3w=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":62841},"style":"./dist/tw-fade.css","exports":{".":"./src/tw-fade.css","./css":"./dist/tw-fade.css","./package.json":"./package.json","./dist/tw-fade.css":"./dist/tw-fade.css"},"gitHead":"1183ea4453cc77d64de7a0231480405467f9d39b","scripts":{"test":"node --test","build":"node scripts/build-css.mjs","verify":"node build/verify.mjs && node build/verify-dist.mjs && node build/verify-fade.mjs && node build/verify-page.mjs","build:demo":"tailwindcss -i demo/input.css -o demo/styles.css","prepublishOnly":"node scripts/build-css.mjs && node --test"},"_npmUser":{"name":"petepetrash","email":"pete.petrash@gmail.com"},"repository":{"url":"git+https://github.com/petekp/tw-fade.git","type":"git"},"_npmVersion":"11.13.0","description":"Elegant, CSS-driven scroll-edge fade masking for Tailwind CSS v4. Add fade-t/b/l/r (or -x/-y/-xy) to any scroll container to fade content into its surface at the edges — scroll-gated with zero JavaScript.","directories":{},"_nodeVersion":"24.16.0","_hasShrinkwrap":false,"devDependencies":{"playwright":"^1.61.0","tailwindcss":"^4.3.1","@tailwindcss/cli":"^4.0.0"},"peerDependencies":{"tailwindcss":">=4.0.0"},"peerDependenciesMeta":{"tailwindcss":{"optional":true}},"_npmOperationalInternal":{"tmp":"tmp/tw-fade_0.3.0_1781725905539_0.5803828407556586","host":"s3://npm-registry-packages-npm-production"}},"0.5.0":{"name":"tw-fade","version":"0.5.0","keywords":["tailwindcss","tailwind-plugin","tailwindcss-v4","scroll","fade","mask","scroll-driven-animations","scrim","edge-fade","overflow"],"author":{"name":"Pete Petrash"},"license":"MIT","_id":"tw-fade@0.5.0","maintainers":[{"name":"petepetrash","email":"pete.petrash@gmail.com"}],"homepage":"https://github.com/petekp/tw-fade#readme","bugs":{"url":"https://github.com/petekp/tw-fade/issues"},"dist":{"shasum":"9bb6f5ba61fc6c01adce2ac9410da5b6b0f848ef","tarball":"https://registry.npmjs.org/tw-fade/-/tw-fade-0.5.0.tgz","fileCount":5,"integrity":"sha512-1rQfU64W6lmCASXcl8T5OacR3l2ZjL8rn+4XoZGNyuUh+0mtY9XnBikwooXVoEDVBveHMsQx4m27S9M1AgBbrQ==","signatures":[{"sig":"MEYCIQCvoIrOf7Z1oa46pGLKI0vW6GupK0I05fzd5ED/gFToLwIhAOYG8MqHwNlR8CwBHap1bYHENfaGL9eXusA8EO14VGBv","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":94700},"style":"./dist/tw-fade.css","exports":{".":"./src/tw-fade.css","./css":"./dist/tw-fade.css","./package.json":"./package.json","./dist/tw-fade.css":"./dist/tw-fade.css"},"gitHead":"4e04e320ffd6c5fdb4d3383bdc4326791a8fc4ac","scripts":{"test":"node --test","build":"node scripts/build-css.mjs","verify":"node build/verify.mjs && node build/verify-dist.mjs && node build/verify-fade.mjs && node build/verify-page.mjs && node build/verify-seo.mjs","release":"node scripts/release.mjs","build:demo":"tailwindcss -i demo/input.css -o demo/styles.css","generate:seo":"node scripts/generate-seo-assets.mjs","prepublishOnly":"node scripts/build-css.mjs && node --test"},"_npmUser":{"name":"petepetrash","email":"pete.petrash@gmail.com"},"repository":{"url":"git+https://github.com/petekp/tw-fade.git","type":"git"},"_npmVersion":"11.13.0","description":"Elegant, CSS-driven scroll-edge fade masking for Tailwind CSS v4. Add fade-t/b/l/r (or -x/-y/-xy) to any scroll container to fade content into its surface at the edges — scroll-gated with zero JavaScript.","directories":{},"_nodeVersion":"24.17.0","_hasShrinkwrap":false,"devDependencies":{"playwright":"^1.61.0","tailwindcss":"^4.3.1","@tailwindcss/cli":"^4.0.0"},"peerDependencies":{"tailwindcss":">=4.0.0"},"peerDependenciesMeta":{"tailwindcss":{"optional":true}},"_npmOperationalInternal":{"tmp":"tmp/tw-fade_0.5.0_1781820689572_0.2693220050605696","host":"s3://npm-registry-packages-npm-production"}},"0.6.0":{"name":"tw-fade","version":"0.6.0","keywords":["tailwindcss","tailwind-plugin","tailwindcss-v4","scroll","fade","mask","scroll-driven-animations","scrim","edge-fade","overflow"],"author":{"name":"Pete Petrash"},"license":"MIT","_id":"tw-fade@0.6.0","maintainers":[{"name":"petepetrash","email":"pete.petrash@gmail.com"}],"homepage":"https://github.com/petekp/tw-fade#readme","bugs":{"url":"https://github.com/petekp/tw-fade/issues"},"dist":{"shasum":"0cf0704df5d365685b7fc25512ae08cef692e4a2","tarball":"https://registry.npmjs.org/tw-fade/-/tw-fade-0.6.0.tgz","fileCount":5,"integrity":"sha512-V6UIfsVngw7EWC+K8H3QDU217SOyqe8L65/sje+3NTpnFWcPixZLEGehP5D8dVkuR4N/4gDlB654PWqV6OHbig==","signatures":[{"sig":"MEUCIQDPUTzooM/bkD7sRjCxPLHOYkzRFGRyXAXQWk7N7GWo0QIgVsJ/1M/PLQJLkkadLVOIRoGK7Rgf25I/QaXo0mzI8G8=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":86192},"style":"./dist/tw-fade.css","exports":{".":"./src/tw-fade.css","./css":"./dist/tw-fade.css","./package.json":"./package.json","./dist/tw-fade.css":"./dist/tw-fade.css"},"gitHead":"6b1bd35a1b30b9eb37b8a364232c2d4d59992e92","scripts":{"test":"node --test","build":"node scripts/build-css.mjs","verify":"node build/verify.mjs && node build/verify-dist.mjs && node build/verify-fade.mjs && node build/verify-demo-assets.mjs && node build/verify-page.mjs && node build/verify-demo-runtime.mjs && node build/verify-seo.mjs","release":"node scripts/release.mjs","build:demo":"tailwindcss -i demo/input.css -o demo/styles.css","export:demo":"node scripts/export-demo-static.mjs","generate:seo":"node scripts/generate-seo-assets.mjs","prepublishOnly":"node scripts/build-css.mjs && node --test"},"_npmUser":{"name":"petepetrash","email":"pete.petrash@gmail.com"},"repository":{"url":"git+https://github.com/petekp/tw-fade.git","type":"git"},"_npmVersion":"11.13.0","description":"Elegant, CSS-driven scroll-edge fade masking for Tailwind CSS v4. Add fade-t/b/l/r (or -x/-y/-xy) to any scroll container to fade content into its surface at the edges — scroll-gated with zero JavaScript.","directories":{},"_nodeVersion":"24.17.0","_hasShrinkwrap":false,"devDependencies":{"playwright":"^1.61.0","tailwindcss":"^4.3.1","@tailwindcss/cli":"^4.0.0"},"peerDependencies":{"tailwindcss":">=4.0.0"},"peerDependenciesMeta":{"tailwindcss":{"optional":true}},"_npmOperationalInternal":{"tmp":"tmp/tw-fade_0.6.0_1782064437408_0.6112624671043974","host":"s3://npm-registry-packages-npm-production"}},"0.7.0":{"name":"tw-fade","version":"0.7.0","keywords":["tailwindcss","tailwind-plugin","tailwindcss-v4","scroll","fade","mask","scroll-driven-animations","scrim","edge-fade","overflow","rtl","direction-aware","logical-properties","bidi"],"author":{"name":"Pete Petrash"},"license":"MIT","_id":"tw-fade@0.7.0","maintainers":[{"name":"petepetrash","email":"pete.petrash@gmail.com"}],"homepage":"https://github.com/petekp/tw-fade#readme","bugs":{"url":"https://github.com/petekp/tw-fade/issues"},"dist":{"shasum":"cda5b02eb2988387298132a559d85ea45762a79e","tarball":"https://registry.npmjs.org/tw-fade/-/tw-fade-0.7.0.tgz","fileCount":7,"integrity":"sha512-1FUIYNLZ4vSiJGBuMl+Ju130I3DQ+1OOl3q07/pd1crT9am4vyktRlJt0jpB4oe5ffqu6VshbMUz//zCOKGRJg==","signatures":[{"sig":"MEUCIDGWX36zQoVwqfWY45CMASaGyM3Ng7SLG971wBeTsk9HAiEAkYhXK2b9JaLGKnm4n4/GpbjldzxuRwAEkXa86gQYzxM=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":83424},"style":"./dist/tw-fade.css","exports":{".":"./src/tw-fade.css","./css":"./dist/tw-fade.css","./package.json":"./package.json","./dist/tw-fade.css":"./dist/tw-fade.css"},"gitHead":"27e813af08c8a413c6ba6e189c5c0971136fa134","scripts":{"test":"node --test","build":"node scripts/build-css.mjs","debug":"node scripts/build-debug.mjs","verify":"node build/verify.mjs && node build/verify-horizontal-rtl.mjs && node build/verify-dist.mjs && node build/verify-fade.mjs && node build/verify-demo-assets.mjs && node build/verify-page.mjs && node build/verify-demo-runtime.mjs && node build/verify-favicon.mjs && node build/verify-seo.mjs","release":"node scripts/release.mjs","ship-demo":"node scripts/ship-demo.mjs","build:demo":"tailwindcss -i demo/input.css -o demo/styles.css","export:demo":"node scripts/export-demo-static.mjs","generate:seo":"node scripts/generate-seo-assets.mjs","prepublishOnly":"node scripts/build-css.mjs && node --test"},"_npmUser":{"name":"petepetrash","email":"pete.petrash@gmail.com"},"repository":{"url":"git+https://github.com/petekp/tw-fade.git","type":"git"},"_npmVersion":"11.16.0","description":"Elegant, CSS-driven scroll-edge fade masking for Tailwind CSS v4. Add fade-y, fade-x, fade-start, or fade-end to any scroll container to fade content into its surface at the edges — scroll-gated with zero JavaScript.","directories":{},"_nodeVersion":"24.18.0","_hasShrinkwrap":false,"devDependencies":{"playwright":"^1.61.0","tw-shimmer":"^0.4.11","tailwindcss":"^4.3.1","@tailwindcss/cli":"^4.0.0"},"peerDependencies":{"tailwindcss":">=4.0.0"},"peerDependenciesMeta":{"tailwindcss":{"optional":true}},"_npmOperationalInternal":{"tmp":"tmp/tw-fade_0.7.0_1782711188960_0.2313699131461957","host":"s3://npm-registry-packages-npm-production"}},"0.7.1":{"name":"tw-fade","version":"0.7.1","keywords":["tailwindcss","tailwind-plugin","tailwindcss-v4","scroll","fade","mask","scroll-driven-animations","scrim","edge-fade","overflow","rtl","direction-aware","logical-properties","bidi"],"author":{"name":"Pete Petrash"},"license":"MIT","_id":"tw-fade@0.7.1","maintainers":[{"name":"petepetrash","email":"pete.petrash@gmail.com"}],"homepage":"https://github.com/petekp/tw-fade#readme","bugs":{"url":"https://github.com/petekp/tw-fade/issues"},"dist":{"shasum":"32e8916d546ebf3cc6376cf24a46c078ae8acc90","tarball":"https://registry.npmjs.org/tw-fade/-/tw-fade-0.7.1.tgz","fileCount":7,"integrity":"sha512-eV4kb+ff/GPbGkM5UM5TBrVUXKtkq8BH/vHIUvz4YX59GJepfunv/d6q7nhNd4c4VoyZMHRER0zVlRBV3SUZJg==","signatures":[{"sig":"MEQCIFvbxIBKQ+ZBhnbPPACvW7oiqNYpMUcZOqwucKTdN26lAiA3WyXdDca5x4Cy7YcNDwIjCZeSuNNLFZoLia12uYqEcQ==","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":87631},"style":"./dist/tw-fade.css","exports":{".":"./src/tw-fade.css","./css":"./dist/tw-fade.css","./package.json":"./package.json","./dist/tw-fade.css":"./dist/tw-fade.css"},"gitHead":"38d463869edf556fb030e1323621954db40686c1","scripts":{"test":"node --test","build":"node scripts/build-css.mjs","debug":"node scripts/build-debug.mjs","verify":"node build/verify.mjs && node build/verify-horizontal-rtl.mjs && node build/verify-dist.mjs && node build/verify-stale-state.mjs && node build/verify-fade.mjs && node build/verify-demo-assets.mjs && node build/verify-page.mjs && node build/verify-demo-runtime.mjs && node build/verify-favicon.mjs && node build/verify-seo.mjs","release":"node scripts/release.mjs","ship-demo":"node scripts/ship-demo.mjs","build:demo":"tailwindcss -i demo/input.css -o demo/styles.css","export:demo":"node scripts/export-demo-static.mjs","generate:seo":"node scripts/generate-seo-assets.mjs","prepublishOnly":"node scripts/build-css.mjs && node --test"},"_npmUser":{"name":"petepetrash","email":"pete.petrash@gmail.com"},"repository":{"url":"git+https://github.com/petekp/tw-fade.git","type":"git"},"_npmVersion":"11.16.0","description":"Elegant, CSS-driven scroll-edge fade masking for Tailwind CSS v4. Add fade-y, fade-x, fade-start, or fade-end to any scroll container to fade content into its surface at the edges — scroll-gated with zero JavaScript.","directories":{},"_nodeVersion":"24.18.0","_hasShrinkwrap":false,"devDependencies":{"playwright":"^1.61.0","tw-shimmer":"^0.4.11","tailwindcss":"^4.3.1","@tailwindcss/cli":"^4.0.0"},"peerDependencies":{"tailwindcss":">=4.0.0"},"peerDependenciesMeta":{"tailwindcss":{"optional":true}},"_npmOperationalInternal":{"tmp":"tmp/tw-fade_0.7.1_1782802547649_0.17272473899513208","host":"s3://npm-registry-packages-npm-production"}},"0.8.0":{"name":"tw-fade","version":"0.8.0","description":"Elegant, CSS-driven scroll-edge fade masking for Tailwind CSS v4. Add fade-y, fade-x, fade-start, or fade-end to any scroll container to fade content into its surface at the edges — scroll-gated with zero JavaScript.","keywords":["tailwindcss","tailwind-plugin","tailwindcss-v4","scroll","fade","mask","scroll-driven-animations","scrim","edge-fade","overflow","rtl","direction-aware","logical-properties","bidi"],"license":"MIT","author":{"name":"Pete Petrash"},"repository":{"type":"git","url":"git+https://github.com/petekp/tw-fade.git"},"homepage":"https://github.com/petekp/tw-fade#readme","bugs":{"url":"https://github.com/petekp/tw-fade/issues"},"style":"./dist/tw-fade.css","exports":{".":"./src/tw-fade.css","./css":"./dist/tw-fade.css","./dist/tw-fade.css":"./dist/tw-fade.css","./package.json":"./package.json"},"scripts":{"build":"node scripts/build-css.mjs","build:demo":"tailwindcss -i demo/input.css -o demo/styles.css","debug":"node scripts/build-debug.mjs","export:demo":"node scripts/export-demo-static.mjs","ship-demo":"node scripts/ship-demo.mjs","generate:seo":"node scripts/generate-seo-assets.mjs","release":"node scripts/release.mjs","test":"node --test","verify":"node build/verify.mjs && node build/verify-horizontal-rtl.mjs && node build/verify-dist.mjs && node build/verify-stale-state.mjs && node build/verify-scrollbar.mjs && node build/verify-fade.mjs && node build/verify-demo-assets.mjs && node build/verify-page.mjs && node build/verify-demo-runtime.mjs && node build/verify-favicon.mjs && node build/verify-seo.mjs","prepublishOnly":"node scripts/build-css.mjs && node --test"},"peerDependencies":{"tailwindcss":">=4.0.0"},"peerDependenciesMeta":{"tailwindcss":{"optional":true}},"devDependencies":{"@tailwindcss/cli":"^4.0.0","playwright":"^1.61.0","tailwindcss":"^4.3.1","tw-shimmer":"^0.4.11"},"gitHead":"595b598d827c876fb4525a856b1b51cd4328ec65","_id":"tw-fade@0.8.0","_nodeVersion":"24.18.1","_npmVersion":"11.16.0","dist":{"integrity":"sha512-9ewfWqOiMaUKrsiN4+jsu1IyFnqzr9coZrVRzGlB0G1HuEPcvpCG2sRo8F1rEoRXxFVmrL6WxT8CRIlmYPV0Qw==","shasum":"657172fd8b96cd1a710e83e9567a0c0ef6a3d4c6","tarball":"https://registry.npmjs.org/tw-fade/-/tw-fade-0.8.0.tgz","fileCount":7,"unpackedSize":127353,"signatures":[{"keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U","sig":"MEUCIQDimLmS3+rj8uLqJPqkiVJscYz0IyDrzMcZcCVulOnI/gIgCL808+Fdh1cmAwyLpBNCzBcqH+Pdopl7ZhJCazofLiQ="}]},"_npmUser":{"name":"petepetrash","email":"pete.petrash@gmail.com"},"directories":{},"maintainers":[{"name":"petepetrash","email":"pete.petrash@gmail.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages-npm-production","tmp":"tmp/tw-fade_0.8.0_1785521861039_0.14368059927349397"},"_hasShrinkwrap":false}},"time":{"created":"2026-06-17T01:39:11.464Z","modified":"2026-07-31T18:17:41.330Z","0.1.0":"2026-06-17T01:39:11.689Z","0.2.0":"2026-06-17T19:01:03.015Z","0.3.0":"2026-06-17T19:51:45.786Z","0.5.0":"2026-06-18T22:11:29.710Z","0.6.0":"2026-06-21T17:53:57.548Z","0.7.0":"2026-06-29T05:33:09.086Z","0.7.1":"2026-06-30T06:55:47.814Z","0.8.0":"2026-07-31T18:17:41.186Z"},"bugs":{"url":"https://github.com/petekp/tw-fade/issues"},"author":{"name":"Pete Petrash"},"license":"MIT","homepage":"https://github.com/petekp/tw-fade#readme","keywords":["tailwindcss","tailwind-plugin","tailwindcss-v4","scroll","fade","mask","scroll-driven-animations","scrim","edge-fade","overflow","rtl","direction-aware","logical-properties","bidi"],"repository":{"type":"git","url":"git+https://github.com/petekp/tw-fade.git"},"description":"Elegant, CSS-driven scroll-edge fade masking for Tailwind CSS v4. Add fade-y, fade-x, fade-start, or fade-end to any scroll container to fade content into its surface at the edges — scroll-gated with zero JavaScript.","maintainers":[{"name":"petepetrash","email":"pete.petrash@gmail.com"}],"readme":"# tw-fade\n\nScroll-aware edge fades for Tailwind CSS v4. Mask the edges of any scroll container so content dissolves into the surface behind it. All CSS. No runtime JavaScript.\n\n**[Live demo](https://pete.design/tw-fade)**\n\n```html\n<div class=\"fade-y h-64 overflow-y-auto\">\n  <!-- long content; top and bottom fade as you scroll -->\n</div>\n```\n\nThe fade appears only when there is content beyond that edge, then recedes again when you reach the start or end.\n\n## Why\n\nA static gradient overlay is always on. It dims content even when nothing is hidden beyond the edge, and it sits in front of your content as another layer.\n\n`tw-fade` uses a CSS mask on the scroll container itself:\n\n- **Scroll-aware.** The fade is gated by the element's own scroll position.\n- **No extra DOM.** The mask lives on the scroll container.\n- **Surface-neutral.** The mask reveals whatever is behind the element instead of painting a fake background color.\n- **Composable.** Direction, size, travel distance, and clear zones are separate utilities.\n- **Graceful fallback.** Browsers without scroll-driven animations get a static fade instead of a broken mask.\n\n## Install\n\n### Tailwind v4 source path\n\nUse this when your app already builds with Tailwind v4. This path supports arbitrary values like `fade-size-[2rem]`.\n\n```bash\nnpm install tw-fade\n```\n\n```css\n@import \"tailwindcss\";\n@import \"tw-fade\";\n```\n\n### Prebuilt CSS\n\nUse this for plain HTML, CDN usage, or bundlers that import CSS directly.\n\n```html\n<link rel=\"stylesheet\" href=\"https://unpkg.com/tw-fade@0.8.0/dist/tw-fade.css\" />\n```\n\n```js\nimport \"tw-fade/css\";\n```\n\nThe prebuilt file includes only the named utility set. Arbitrary bracket values need Tailwind's source path.\n\nIf you use an unversioned CDN URL, you receive the latest package and any breaking API changes that come with it. Pin a version when you need stable HTML.\n\n## Usage\n\nPut the fade utility on the element that actually scrolls.\n\n```html\n<!-- Top and bottom -->\n<div class=\"fade-y h-80 overflow-y-auto\">...</div>\n\n<!-- All four edges -->\n<div class=\"fade h-80 overflow-auto\">...</div>\n\n<!-- Horizontal rail, direction-aware -->\n<div class=\"fade-x overflow-x-auto\">...</div>\n\n<!-- Compose single edges -->\n<div class=\"fade-top fade-end h-80 overflow-auto\">...</div>\n\n<!-- Tune the band and travel distance -->\n<div class=\"fade-y fade-size-lg fade-travel-xl h-80 overflow-y-auto\">...</div>\n```\n\n## Direction Utilities\n\n| Utility | Edges |\n| --- | --- |\n| `fade` | all four edges |\n| `fade-y` | top + bottom |\n| `fade-top` | top |\n| `fade-bottom` | bottom |\n| `fade-x` | horizontal start + horizontal end |\n| `fade-start` | horizontal start |\n| `fade-end` | horizontal end |\n\n`start` and `end` are **horizontal only** and follow semantic reading direction. In LTR, start is the left edge and end is the right edge; in RTL, start is the right edge and end is the left edge. For the top or bottom edge use `fade-top` / `fade-bottom` — there is no `fade-block-start`. Use the HTML `dir` attribute on the scroll container or an ancestor; a CSS-only `direction: rtl` rule does not trigger RTL routing.\n\nVertical names stay physical (`top` / `bottom`) because the block axis is not affected by text direction. This split — physical vertical, direction-aware horizontal — mirrors how Tailwind itself ships physical `top`/`bottom` insets alongside logical `ps`/`pe`. See [Why plain directions](./MIGRATING.md#why-plain-directions) for the naming rationale.\n\n## Size\n\nSize controls how thick the fade band is.\n\n| Utility | Affects |\n| --- | --- |\n| `fade-size-*` | all edges |\n| `fade-size-y-*` | top + bottom |\n| `fade-size-x-*` | start + end |\n| `fade-size-top-*` | top |\n| `fade-size-bottom-*` | bottom |\n| `fade-size-start-*` | horizontal start |\n| `fade-size-end-*` | horizontal end |\n\n```html\n<div class=\"fade fade-size-md fade-size-top-2xl overflow-auto\">...</div>\n```\n\nResolution is edge, then axis, then global, then the default. For example, top uses `fade-size-top-*` first, then `fade-size-y-*`, then `fade-size-*`.\n\nThe default size is capped at `min(12%, 3rem)`, so small scroll areas do not get swallowed by the fade. Named sizes derive from Tailwind's spacing unit, `--spacing`, with `0.25rem` as the fallback.\n\n| Step | Value | Step | Value |\n| --- | --- | --- | --- |\n| `xs` | `1.5rem` | `xl` | `5rem` |\n| `sm` | `2rem` | `2xl` | `6rem` |\n| `md` | `3rem` | `3xl` | `8rem` |\n| `lg` | `4rem` | `4xl` | `10rem` |\n\nYou can override the tokens:\n\n```css\n@theme {\n  --fade-size-md: 2.5rem;\n}\n```\n\nOn the Tailwind source path, size accepts named values, lengths, and percentages:\n\n```html\n<div class=\"fade-y fade-size-[15%]\">...</div>\n```\n\nThe prebuilt CSS includes the named sizes only.\n\n## Travel Distance\n\nTravel distance controls how far you scroll before the soft band eases open to its full width.\n\n| Utility | Affects |\n| --- | --- |\n| `fade-travel-*` | all selected edges |\n\n```html\n<div class=\"fade-y fade-travel-sm overflow-y-auto\">...</div>\n<div class=\"fade-y fade-travel-[80px] overflow-y-auto\">...</div>\n```\n\nA smaller travel distance opens the band faster; a larger one eases it over more scroll. Either way the **edge is masked almost immediately** — the band's transparency saturates within `travel ÷ 8` of scroll, so content is never hard-clipped at the scroll edge while the band is still widening. The travel is purely the cosmetic open-speed; it is safe at any size.\n\nThe named travel scale is the same as the size scale (default `sm`) and can be overridden with `--fade-travel-{step}`. Arbitrary travel values are source-path only. To change how fast the edge itself goes transparent, set `--tw-fade-onset` (default `8`; higher = snappier).\n\n## Clear Zones\n\nClear zones keep a fully opaque strip before the fade starts. Use them for sticky headers, sticky footers, or fixed controls inside the scroll container.\n\n| Utility | Affects |\n| --- | --- |\n| `fade-clear-*` | all edges |\n| `fade-clear-y-*` | top + bottom |\n| `fade-clear-x-*` | start + end |\n| `fade-clear-top-*` | top |\n| `fade-clear-bottom-*` | bottom |\n| `fade-clear-start-*` | horizontal start |\n| `fade-clear-end-*` | horizontal end |\n\n```html\n<div class=\"fade-top fade-clear-top-[56px] h-80 overflow-y-auto\">\n  <header class=\"sticky top-0 h-14\">...</header>\n  ...\n</div>\n```\n\nClear utilities accept named values, lengths, percentages, and bare integers on the Tailwind source path. A bare integer maps to `--spacing * N`, so `fade-clear-top-4` is `1rem` with the default spacing unit.\n\nThe prebuilt CSS includes named clear values and `-var` forms, not arbitrary values or integer forms.\n\n### Dynamic Clear Zones\n\nUse `-var` when the clear zone depends on runtime layout:\n\n```html\n<div class=\"fade-top fade-clear-top-var\" style=\"--fade-clear-top: 56px\">\n  ...\n</div>\n```\n\nAvailable forms:\n\n```txt\nfade-clear-var\nfade-clear-y-var\nfade-clear-x-var\nfade-clear-top-var\nfade-clear-bottom-var\nfade-clear-start-var\nfade-clear-end-var\n```\n\nThe fallback chain is edge, then axis, then global, then `0px`.\n\n```css\n--fade-clear-top: 56px;\n--fade-clear-y: 24px;\n--fade-clear: 0px;\n```\n\n## Force Or Disable A Fade\n\nThese utilities change only the active fade amount. They do not select edges on their own, so pair them with a direction utility.\n\n| Utility | Effect |\n| --- | --- |\n| `fade-none` | disables all selected fades |\n| `fade-none-y` | disables selected vertical fades |\n| `fade-none-x` | disables selected horizontal fades |\n| `fade-always` | pins all selected fades fully on |\n| `fade-always-y` | pins selected vertical fades fully on |\n| `fade-always-x` | pins selected horizontal fades fully on |\n\n```html\n<div class=\"fade-y fade-always-y overflow-y-auto\">...</div>\n<div class=\"fade fade-none-x overflow-auto\">...</div>\n```\n\n## Scrollbars\n\nThe fade is a mask on the scroll container, and a mask can't distinguish content from the container's own scrollbar. Whether that matters depends on how the browser paints the scrollbar:\n\n- **Overlay scrollbars** — the default on macOS, iOS, and Android — paint in a separate layer on top of the element, so the mask never touches them. Nothing to do.\n- **Classic (space-consuming) scrollbars** — the default on Windows and Linux, on macOS with *Show scroll bars → Always*, and any bar you style with `::-webkit-scrollbar` — paint inside the element's box, so the fade dims the scrollbar's ends along with the content.\n\nIf the container doesn't need a visible scrollbar, the shortest fix is to remove it — Tailwind's `scrollbar-none` (or `scrollbar-width: none`) takes the bar out of the box entirely and there is nothing left to fade. Reach for that first; it costs nothing and works everywhere.\n\nWhen you *do* want the bar visible, add the `fade-scrollbar-safe-*` class for the axis you scroll. It shields the scrollbar's column with an opaque strip in the mask, so the content still fades while the scrollbar stays fully opaque.\n\n| Utility | Effect |\n| --- | --- |\n| `fade-scrollbar-safe-y` | shields the **vertical** bar (from scrolling on y) |\n| `fade-scrollbar-safe-x` | shields the **horizontal** bar (from scrolling on x) |\n| `fade-scrollbar-safe-xy` | both |\n| `fade-scrollbar-width-sm\\|md\\|lg` | sets the bar width: `11px` / `15px` (default) / `17px` |\n\n**The suffix is the scroll axis, not the faded edge.** `-y` follows `overflow-y` — it's the vertical bar at the inline end. It deliberately does *not* follow this plugin's own `fade-y` (top + bottom edges). In practice the two agree, which is why it reads cleanly:\n\n```html\n<div class=\"overflow-y-auto fade-y fade-scrollbar-safe-y\">...</div>\n```\n\nMatch the class to the axis that actually scrolls. Putting `-y` on a horizontal-only scroller reserves a gutter for a vertical bar that never appears, and the strip then lands on your content — a bright notch at the fading edge. `-x` is the correct class there, and it reserves nothing.\n\n`fade-scrollbar-width-*` is a setter, not a switch — on its own it turns nothing on. It also inherits, so the usual place for it is an ancestor:\n\n```html\n<body class=\"fade-scrollbar-width-lg\">\n  <!-- every opted-in container below picks up 17px -->\n</body>\n```\n\nThe named widths come from the `--fade-scrollbar-width-*` theme namespace and override like any other token:\n\n```css\n@theme {\n  --fade-scrollbar-width-md: 13px;\n}\n```\n\nOn the Tailwind source path the utility also takes any length — `fade-scrollbar-width-[13px]`. A bare integer is deliberately rejected: everywhere else in this plugin an integer means spacing steps, and here it would have to mean pixels. Any width that reaches the plugin is clamped at `0px`, whether it comes from an arbitrary utility, a theme-token override, or a direct `--tw-fade-scrollbar-width` declaration. Negative lengths therefore behave as `0px` instead of invalidating the mask.\n\n### The trade it makes\n\nFor the strip to line up with the scrollbar, the plugin has to know the bar's width — and CSS gives it no way to ask. The reserved gutter sits *inside* every box the mask can reference, so no `mask-clip` value excludes it; container query units can measure it but only descendants can read them, and the mask is on the container itself.\n\nSo `fade-scrollbar-safe-*` doesn't measure the bar, it **declares** it. It pins the bar via `::-webkit-scrollbar` and sizes the strip from the same custom property, which makes them equal by construction rather than by luck — including under page zoom, where a native bar's width in CSS px drifts but two declared lengths scale together.\n\nThe cost: pinning the bar makes it **classic on every platform**, including macOS, where you'd otherwise get an overlay bar and no bug at all. Apply it when your users see classic scrollbars, or when you want a consistent bar everywhere — not by default.\n\nIt also fixes a quieter symptom of the same root cause. Mask percentages resolve against a box that includes the gutter, while content stops at the scrollport edge, so an inline-end fade authored to reach transparent at `100%` reaches it *inside the gutter* — over real content it never finishes. How badly depends on the ratio: with a 15px bar the last content pixel measured 40/255 opaque under a 60px band, and 161/255 under a 26px one — the tighter the band, the larger the share of it spent inside the gutter. Pinning the width lets the plugin inset that layer so the ramp lands on the content edge instead (0/255 and 1/255 respectively).\n\n### Styling\n\nThe reserved gutter shouldn't read as a separate panel, so the utility also gives the bar a **transparent track** and a subtle thumb derived from the container's `currentColor` (adapts to light and dark). Knobs:\n\n- `--tw-fade-scrollbar-thumb` — the thumb color. Defaults to `color-mix(in srgb, currentColor 30%, transparent)`.\n- `--tw-fade-scrollbar-width` — what `fade-scrollbar-width-*` sets, for a value off the scale. Defaults to `15px`, matching a macOS classic bar, and clamps negative values to `0px`. Set this rather than `--tw-fade-scrollbar`: it drives the bar and the strip together, so they can't disagree. The pin *replaces* the native bar rather than decorating it, so this is your users' actual hit target — going much below native trades pointer accuracy for looks.\n\n```html\n<div class=\"fade-y fade-scrollbar-safe-y overflow-y-auto\" style=\"--tw-fade-scrollbar-thumb: #888\">...</div>\n```\n\nDo **not** set `scrollbar-width` or `scrollbar-color` on a `fade-scrollbar-safe-*` container — including via Tailwind's own `scrollbar-thin`, `scrollbar-auto`, `scrollbar-none`, `scrollbar-thumb-*`, and `scrollbar-track-*`. Either property makes Blink discard `::-webkit-scrollbar` styling entirely (`scrollbar-width` does the same in WebKit), which cancels the pin and takes the gutter to `0` — leaving a 15px opaque strip sitting on your content. Use `fade-scrollbar-width-*` for the size, and `::-webkit-scrollbar-track` / `::-webkit-scrollbar-thumb` for the colors.\n\n### Limits\n\n- RTL is handled automatically — the strip follows the vertical bar to the inline-start edge.\n- **Pinning the bar is per-element, not per-axis.** Opting in makes *both* bars classic, so a container that scrolls both ways gets a classic horizontal bar whether or not you asked for one — which is why `-xy` exists, and why the axis suffix is worth getting right. The block strip can't just be on by default: unlike the inline gutter, the block gutter is only reserved when content actually overflows horizontally, so a blind block strip would slab an opaque band over content on every vertical-only scroller.\n- **Firefox is not covered.** It ignores `::-webkit-scrollbar`, so its bar can't be pinned, and whether it's using overlay or classic bars can't be detected either. A guessed strip would be right on Windows/Linux and an opaque slab over content on macOS, with no way to tell which — and a missed strip damages content, while the bug it prevents only dims chrome. Firefox gets a thin styled bar and no strip only when scroll-driven animations are enabled. Release Firefox fails that feature gate, so this opt-in leaves its native scrollbar unchanged.\n- **In Safari, a container that isn't currently overflowing on the block axis has no gutter** (WebKit doesn't honor `scrollbar-gutter: stable`'s reserve-anyway behavior for custom bars), so the inline strip lands on content — an opaque band exactly where the fade just finished. It shows when such a container is faded anyway: with `fade-always*`, or with a live fade on the *other* axis (a two-axis scroller currently overflowing only horizontally). **Fix it with `overflow-y-scroll` instead of `overflow-y-auto`** — a permanent bar means a permanent gutter, in WebKit too (measured: 15px reserved, strip landing exactly on the track). Or apply the class only on a state that actually overflows.\n- **The whole opt-in requires scroll-driven animations, and stands down without them.** On Safari 17.x / 18.x and on release Firefox, the plugin falls back to pinning fades on regardless of overflow — and a faded container with no overflow is precisely the case above. Rather than shield a bar on those engines, the utility declines to pin one, so they keep their native scrollbars: overlay on macOS, which the mask never touches. Pinning without shielding would be worse than not opting in at all — it manufactures a space-consuming bar and then lets the fade dim it.\n- On overlay-scrollbar platforms the bar already paints above the mask and is never faded, so nothing is needed there — the utility trades that away deliberately in exchange for a bar it can shield exactly.\n\n## Fading The Whole Page\n\nFade the element that scrolls. For a full-page fade, make `<body>` the scroll container and keep the surface behind it on `<html>`.\n\n```html\n<html class=\"h-full overflow-hidden bg-neutral-950\">\n  <body class=\"fade-y h-full overflow-y-auto bg-transparent\">\n    ...\n  </body>\n</html>\n```\n\nTwo details matter:\n\n1. `<body>` must have a fixed height and `overflow-y-auto`, otherwise the viewport scrolls instead.\n2. The scroll container should be transparent if you want the mask to reveal the page surface behind it.\n\n## Source Path Vs. Prebuilt\n\n| | `@import \"tw-fade\"` | `tw-fade/css` |\n| --- | --- | --- |\n| Needs Tailwind v4 | yes | no |\n| Direction utilities | yes | yes |\n| Named size/travel/clear utilities | yes | yes |\n| `fade-scrollbar-safe-*` and named `fade-scrollbar-width-*` | yes | yes |\n| `fade-clear-*-var` | yes | yes |\n| Arbitrary values like `fade-size-[6rem]` | yes | no |\n| Integer clear values like `fade-clear-top-14` | yes | no |\n\nThe prebuilt file is generated from an explicit safelist. It does not include Tailwind Preflight, core Tailwind utilities, arbitrary values, or integer `fade-clear-*` classes.\n\n## Exports\n\n| Specifier | Resolves to |\n| --- | --- |\n| `tw-fade` | `./src/tw-fade.css` |\n| `tw-fade/css` | `./dist/tw-fade.css` |\n| `tw-fade/dist/tw-fade.css` | `./dist/tw-fade.css` |\n\n`tailwindcss >=4.0.0` is an optional peer dependency. You need it for the source path, but not for the prebuilt CSS.\n\n## How It Works\n\nEach faded element gets a six-layer `mask-image`: four edge gradients, one per physical edge, combined with `intersect`, plus two scrollbar-shield strips unioned in front of them with `add`. Inactive edge layers fall back to an opaque identity mask; active ones use a 13-stop eased gradient. The strips are `0px` by default and inert — a union can only raise opacity — until a [`fade-scrollbar-safe-*`](#scrollbars) class widens one.\n\nThe public API uses plain direction names, but the internal engine still keeps four physical edge amounts. Those internal properties are typed numbers, do not inherit, and are driven by scroll animations. Keeping the engine physical makes the mask predictable; the public `start` and `end` utilities route to the correct physical side for LTR or RTL in browsers that support the `:dir()` selector (see [Browser Support](#browser-support)).\n\nInside browsers with scroll-driven animation support:\n\n- vertical fades use `scroll(self y)`;\n- horizontal fades use `scroll(self inline)`;\n- leading edges reveal from `0` to `1` near the start of scroll;\n- trailing edges retract from `1` to `0` near the end of scroll.\n\nIf an axis cannot scroll, that axis stays at `0`, so the fade does not show. This is intentional.\n\nIn browsers without scroll-driven animations, selected fades pin fully on as a static fallback.\n\n### Dynamic content on a stable scrollport\n\nIf you replace the contents of a faded scrollport without replacing the scrollport itself, the browser has to invalidate the element's scroll-driven animation state. For example: a tabbed mobile list keeps one `.fade-y` node mounted, scrolls a long tab, then swaps in a short tab whose content no longer overflows.\n\nCurrent `tw-fade` mitigates this in Chromium. The expected post-swap state is:\n\n- `scrollTop` / `scrollLeft` is clamped back to `0`;\n- the axis no longer overflows;\n- the selected fade amounts return to `0`.\n\nWebKit can still retain a stale sampled scroll-animation value in this exact shape, especially after collapsing content from the bottom/end of the scroll range. If a user reports a fade that stays visible after a content swap, advise them in this order:\n\n1. Upgrade to the latest `tw-fade`.\n2. Key/remount the scrollport by content identity when practical.\n3. If remounting is awkward, restart the fade animation after the content swap.\n4. If the app already knows the content cannot overflow, add `fade-none-y` or `fade-none-x` for that state.\n\nReact remount pattern:\n\n```tsx\n<div key={activeTabId} className=\"fade-y overflow-y-auto\">\n  {items.map((item) => (\n    <ListItem key={item.id} item={item} />\n  ))}\n</div>\n```\n\nAnimation reset helper:\n\n```js\nfunction resetTwFade(el) {\n  const previous = el.style.animation\n  el.style.animation = 'none'\n  void el.offsetHeight\n  requestAnimationFrame(() => {\n    el.style.animation = previous\n  })\n}\n```\n\nReact reset pattern:\n\n```tsx\nconst scrollRef = useRef(null)\n\nuseLayoutEffect(() => {\n  if (scrollRef.current) resetTwFade(scrollRef.current)\n}, [activeTabId])\n\nreturn (\n  <div ref={scrollRef} className=\"fade-y overflow-y-auto\">\n    {items.map((item) => (\n      <ListItem key={item.id} item={item} />\n    ))}\n  </div>\n)\n```\n\nKnown no-overflow escape hatch:\n\n```tsx\n<div className={canOverflow ? 'fade-y overflow-y-auto' : 'fade-y fade-none-y overflow-y-auto'}>\n  {items.map((item) => (\n    <ListItem key={item.id} item={item} />\n  ))}\n</div>\n```\n\nThe supported public surface is the `fade-*` utilities, the public `--fade-*` theme tokens described above (`--fade-size-*`, `--fade-travel-*`, `--fade-clear-*`, `--fade-scrollbar-width-*`), and three author knobs: `--tw-fade-onset` (the edge-speed knob under [Travel Distance](#travel-distance)) plus `--tw-fade-scrollbar-width` and `--tw-fade-scrollbar-thumb` (both under [Scrollbars](#scrollbars)). Treat the rest of the `--tw-fade-*` namespace — including `--tw-fade-scrollbar` and `--tw-fade-scrollbar-block` — as internal implementation detail.\n\n## RTL\n\nHorizontal fades are direction-aware:\n\n```html\n<div dir=\"rtl\" class=\"fade-start overflow-x-auto\">...</div>\n```\n\nIn that example, `fade-start` selects the right edge because the scroll container is RTL. `fade-end` selects the left edge. `fade-x` selects both.\n\nRTL routing follows semantic direction through `dir`, not a CSS-only `direction: rtl` declaration. It relies on the `:dir()` selector, so on the narrow band of Chromium that supports scroll-driven animations but not `:dir()` (Chrome 115–119), RTL scrollers fall back to LTR edge mapping — see [Browser Support](#browser-support). LTR is unaffected.\n\nVertical fades are unchanged by text direction.\n\n## Accessibility\n\n`tw-fade` is visual only. It does not move content, add scroll behavior, or change focus order. Like any edge fade, it lowers contrast near the masked edge, so keep band sizes modest and use clear zones for sticky controls or critical text.\n\n## Browser Support\n\nThree CSS features carry different support floors:\n\n- **CSS masking** (`mask-image`, `mask-composite`). Interoperable across current evergreen browsers.\n- **Scroll-driven animations** (`animation-timeline: scroll()`). Shipped by default in every major engine except Firefox release.\n- **The `:dir()` selector**, used to route `start` / `end` to the correct physical edge under RTL.\n\n| Engine | Masking | Scroll-driven animation | `:dir()` | Result |\n| --- | --- | --- | --- | --- |\n| Chrome / Edge | 120+ | 115+ | 120+ | Full scroll-gated, direction-aware fade |\n| Safari (WebKit) | 15.4+ | 26.0+ | 16.4+ | Full on 26+; static fade fallback below |\n| Firefox (release) | 53+ | not by default | 49+ | Static always-on fade |\n\n**Scroll-driven fallback.** Browsers without scroll-driven animations still render selected fades, but as always-on static fades. Safari 17.x / 18.x and Firefox release get this fallback (Firefox keeps scroll-driven animations behind a flag, default-on only in Nightly).\n\n**RTL routing floor.** Direction-aware `start` / `end` routing additionally needs `:dir()`. On the narrow band of Chromium that has scroll-driven animations but not `:dir()` (Chrome 115–119), RTL scrollers fall back to LTR physical-edge mapping — the fade still renders, but `start` / `end` map to the wrong side. LTR is unaffected, and that band is effectively gone on auto-updating Chromium.\n\n**Older WebKit** may also need `-webkit-mask-*`; run the prebuilt CSS through Autoprefixer if you target it.\n\n## Migrating\n\nUpgrading from `0.6.x`? [MIGRATING.md](./MIGRATING.md) is written as a step-by-step\nprocedure you can hand straight to a coding agent (\"upgrade this project to tw-fade\n0.7.0 using MIGRATING.md\") — ordered renames, the physical→logical RTL caveats to\nreview by hand, and a one-line grep to verify nothing was missed. It reads fine for\nhumans too.\n\n## Development\n\n```bash\nnpm test\nnpm run build\nnpm run build:demo\nnpm run verify\n```\n","readmeFilename":"README.md"}