diff --git a/.editorconfig b/.editorconfig
new file mode 100644
index 000000000..c6c8b3621
--- /dev/null
+++ b/.editorconfig
@@ -0,0 +1,9 @@
+root = true
+
+[*]
+indent_style = space
+indent_size = 2
+end_of_line = lf
+charset = utf-8
+trim_trailing_whitespace = true
+insert_final_newline = true
diff --git a/.eslintignore b/.eslintignore
new file mode 100644
index 000000000..7de3c52e3
--- /dev/null
+++ b/.eslintignore
@@ -0,0 +1,4 @@
+/lib
+/docs
+/__tests__/fixtures/cli-utils.js
+/stubs/*
diff --git a/.eslintrc.json b/.eslintrc.json
new file mode 100644
index 000000000..d0832f697
--- /dev/null
+++ b/.eslintrc.json
@@ -0,0 +1,29 @@
+{
+ "env": {
+ "jest": true
+ },
+ "parserOptions": {
+ "ecmaVersion": 2018,
+ "sourceType": "module"
+ },
+ "extends": ["prettier"],
+ "plugins": ["prettier"],
+ "rules": {
+ "camelcase": ["error", { "allow": ["^unstable_"] }],
+ "no-unused-vars": [2, { "args": "all", "argsIgnorePattern": "^_" }],
+ "no-warning-comments": 0,
+ "prettier/prettier": [
+ "error",
+ {
+ "semi": false,
+ "singleQuote": true,
+ "printWidth": 100,
+ "tabWidth": 2,
+ "useTabs": false,
+ "trailingComma": "es5",
+ "bracketSpacing": true,
+ "parser": "flow"
+ }
+ ]
+ }
+}
diff --git a/.github/CODEOWNERS b/.github/CODEOWNERS
deleted file mode 100644
index 4bf4af1ed..000000000
--- a/.github/CODEOWNERS
+++ /dev/null
@@ -1 +0,0 @@
-* @tailwindlabs/engineering
diff --git a/.github/CODE_OF_CONDUCT.md b/.github/CODE_OF_CONDUCT.md
new file mode 100644
index 000000000..7ce9543c5
--- /dev/null
+++ b/.github/CODE_OF_CONDUCT.md
@@ -0,0 +1,10 @@
+# Tailwind CSS Community Guidelines
+
+The following community guidelines are based on [The Ruby Community Conduct Guidelines](https://www.ruby-lang.org/en/conduct/).
+
+This document provides community guidelines for a respectful, productive, and collaborative place for any person who is willing to contribute to the Tailwind CSS project. It applies to all “collaborative space”, which is defined as community communications channels (such as mailing lists, submitted patches, commit comments, etc.).
+
+- Participants will be tolerant of opposing views.
+- Participants must ensure that their language and actions are free of personal attacks and disparaging personal remarks.
+- When interpreting the words and actions of others, participants should always assume good intentions.
+- Behaviour which can be reasonably considered harassment will not be tolerated.
diff --git a/.github/CONTRIBUTING.md b/.github/CONTRIBUTING.md
index 63f79fa10..704597620 100644
--- a/.github/CONTRIBUTING.md
+++ b/.github/CONTRIBUTING.md
@@ -1,103 +1,64 @@
# Contributing
-## Requirements
+Thanks for your interest in contributing to Tailwind CSS! Please take a moment to review this document **before submitting a pull request**.
-Before getting started, ensure your system has access to the following tools:
+## Pull requests
-- [Node.js](https://nodejs.org/)
-- [Rustup](https://rustup.rs/)
-- [pnpm](https://pnpm.io/)
+**Please ask first before starting work on any significant new features.**
-## Getting started
-
-```sh
-# Install dependencies
-pnpm install
-
-# Install Rust toolchain and WASM targets
-rustup default stable
-rustup target add wasm32-wasip1-threads
-
-# Build the project
-pnpm build
-```
-
-## Development workflow
-
-During development, you can run tests in watch mode:
-
-```sh
-pnpm tdd
-```
-
-The `playgrounds` directory contains example projects you can use to test your changes. To start the Vite playground, use:
-
-```sh
-pnpm build && pnpm vite
-```
-
-## Bug fixes
-
-If you've found a bug in Tailwind that you'd like to fix, [submit a pull request](https://github.com/tailwindlabs/tailwindcss/pulls) with your changes. Include a helpful description of the problem and how your changes address it, and provide tests so we can verify the fix works as expected.
-
-## New features
-
-If there's a new feature you'd like to see added to Tailwind, [share your idea with us](https://github.com/tailwindlabs/tailwindcss/discussions/new?category=ideas) in our discussion forum to get it on our radar as something to consider for a future release before starting work on it.
-
-**Please note that we don't often accept pull requests for new features.** Adding a new feature to Tailwind requires us to think through the entire problem ourselves to make sure we agree with the proposed API, which means the feature needs to be high on our own priority list for us to be able to give it the attention it needs.
-
-If you open a pull request for a new feature, we're likely to close it not because it's a bad idea, but because we aren't ready to prioritize the feature and don't want the PR to sit open for months or even years.
+It's never a fun experience to have your pull request declined after investing a lot of time and effort into a new feature. To avoid this from happening, we request that contributors create [an issue](https://github.com/tailwindcss/tailwindcss/issues) to first discuss any significant new features. This includes things like adding new utilities, creating new at-rules, etc.
## Coding standards
-Our code formatting rules are defined in the `"prettier"` section of [package.json](https://github.com/tailwindlabs/tailwindcss/blob/main/package.json). You can check your code against these standards by running:
+Our code formatting rules are defined in [.eslintrc](https://github.com/tailwindcss/tailwindcss/blob/master/.eslintrc.json). You can check your code against these standards by running:
```sh
-pnpm run lint
+npm run style
```
To automatically fix any style violations in your code, you can run:
```sh
-pnpm run format
+npm run style -- --fix
```
## Running tests
-You can run the TypeScript and Rust test suites using the following command:
+You can run the test suite using the following commands:
```sh
-pnpm test
+npm test
```
-To run the integration tests, use:
+Please ensure that the tests are passing when submitting a pull request. If you're adding new features to Tailwind, please include tests.
+
+## Building the CSS and trying your changes manually
+
+In addition to the automated tests, if you'd like to test the generated CSS manually with your own test HTML file, you can generate the default build by running:
```sh
-pnpm build && pnpm test:integrations
+npm run prepare
```
-Additionally, some features require testing in browsers (i.e. to ensure CSS variable resolution works as expected). These can be run via:
+This will create new CSS files in the `/dist` folder which you can reference in your own test HTML file. We often test our own changes by creating an `index.html` file in the root of the Tailwind project itself that pulls in the `/dist/tailwind.css` stylesheet:
+
+```html
+
+
+
+
+
+
+ Hello, world!
+
+
+
Hello world!
+
+
+```
+
+You can then use a tool like [live-server](https://www.npmjs.com/package/live-server) to preview it in the browser:
```sh
-pnpm build && pnpm test:ui
+live-server .
```
-
-Please ensure that all tests are passing when submitting a pull request. If you're adding new features to Tailwind CSS, always include tests.
-
-After a successful build, you can also use the npm package tarballs created inside the `dist/` folder to install your build in other local projects.
-
-## Pull request process
-
-When submitting a pull request:
-
-- Ensure the pull request title and description explain the changes you made and why you made them.
-- Include a test plan section that outlines how you tested your contributions. We do not accept contributions without tests.
-- Ensure all tests pass. You can add the tag `[ci-all]` in your pull request description to run the test suites across all platforms.
-
-When a pull request is created, Tailwind CSS maintainers will be notified automatically.
-
-## Communication
-
-- **GitHub discussions**: For feature ideas and general questions
-- **GitHub issues**: For bug reports
-- **GitHub pull requests**: For code contributions
diff --git a/.github/FUNDING.yml b/.github/FUNDING.yml
deleted file mode 100644
index 848c851b1..000000000
--- a/.github/FUNDING.yml
+++ /dev/null
@@ -1 +0,0 @@
-custom: ['https://tailwindcss.com/sponsor']
diff --git a/.github/ISSUE_TEMPLATE.md b/.github/ISSUE_TEMPLATE.md
new file mode 100644
index 000000000..520264c47
--- /dev/null
+++ b/.github/ISSUE_TEMPLATE.md
@@ -0,0 +1,13 @@
+
diff --git a/.github/ISSUE_TEMPLATE/bug-report.md b/.github/ISSUE_TEMPLATE/bug-report.md
index 1b8a310c6..e3e463444 100644
--- a/.github/ISSUE_TEMPLATE/bug-report.md
+++ b/.github/ISSUE_TEMPLATE/bug-report.md
@@ -1,39 +1,28 @@
---
-name: Bug report
-about: If you've already asked for help with a problem and confirmed something is broken with Tailwind CSS itself, create a bug report.
+name: 'Bug Report'
+about: 'Report a reproducible bug in the framework.'
title: ''
labels: ''
assignees: ''
---
-
+### Describe the problem:
-**What version of Tailwind CSS are you using?**
+
-For example: postcss-cli 11.0.0, Next.js 15.1.7, Vite 6.1.0
+### Link to a minimal reproduction:
-**What version of Node.js are you using?**
+
diff --git a/.github/ISSUE_TEMPLATE/config.yml b/.github/ISSUE_TEMPLATE/config.yml
index 10ee9a6b8..679240972 100644
--- a/.github/ISSUE_TEMPLATE/config.yml
+++ b/.github/ISSUE_TEMPLATE/config.yml
@@ -1,11 +1,11 @@
blank_issues_enabled: false
contact_links:
- - name: Get Help
- url: https://github.com/tailwindlabs/tailwindcss/discussions/new?category=help
- about: If you can't get something to work the way you expect, open a question in our discussion forums.
- name: Feature Request
- url: https://github.com/tailwindlabs/tailwindcss/discussions/new?category=ideas
+ url: https://github.com/tailwindcss/tailwindcss/discussions/new?category_id=65335
about: 'Suggest any ideas you have using our discussion forums.'
+ - name: Help
+ url: https://github.com/tailwindcss/tailwindcss/discussions/new?category_id=65334
+ about: 'If you have a question or need help, ask a question on the discussion forums.'
- name: Documentation Issue
- url: https://github.com/tailwindlabs/tailwindcss.com
+ url: https://github.com/tailwindcss/docs
about: 'For documentation issues, suggest changes on our documentation repository.'
diff --git a/.github/PULL_REQUEST_TEMPLATE.md b/.github/PULL_REQUEST_TEMPLATE.md
index aa0793aa3..ce7fafb97 100644
--- a/.github/PULL_REQUEST_TEMPLATE.md
+++ b/.github/PULL_REQUEST_TEMPLATE.md
@@ -4,26 +4,8 @@
**Please ask first before starting work on any significant new features.**
-It's never a fun experience to have your pull request declined after investing a lot of time and effort into a new feature. To avoid this from happening, we request that contributors create a discussion to first discuss any significant new features.
+It's never a fun experience to have your pull request declined after investing a lot of time and effort into a new feature. To avoid this from happening, we request that contributors create an issue to first discuss any significant new features. This includes things like adding new utilities, creating new at-rules, or adding new component examples to the documentation.
-For more info, check out the contributing guide:
-
-https://github.com/tailwindlabs/tailwindcss/blob/main/.github/CONTRIBUTING.md
-
--->
-
-## Summary
-
-
-
-## Test plan
-
-
diff --git a/.github/logo-dark.svg b/.github/logo-dark.svg
deleted file mode 100644
index fe7f33aea..000000000
--- a/.github/logo-dark.svg
+++ /dev/null
@@ -1 +0,0 @@
-
\ No newline at end of file
diff --git a/.github/logo-light.svg b/.github/logo-light.svg
deleted file mode 100644
index a1731300d..000000000
--- a/.github/logo-light.svg
+++ /dev/null
@@ -1 +0,0 @@
-
\ No newline at end of file
diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml
deleted file mode 100644
index 5ae59e80f..000000000
--- a/.github/workflows/ci.yml
+++ /dev/null
@@ -1,124 +0,0 @@
-name: CI
-
-on:
- push:
- branches: [main]
- pull_request:
-
-permissions:
- contents: read
-
-env:
- NODE_VERSION: 24
-
-concurrency:
- group: ${{ github.workflow }}-${{ github.ref }}
- cancel-in-progress: true
-
-jobs:
- tests:
- strategy:
- fail-fast: false
- matrix:
- runner:
- - name: Windows
- os: windows-latest
-
- - name: Linux
- os: namespace-profile-default
-
- # Playwright 1.62+ dropped WebKit support for macOS 14, and hangs
- # instead of failing when launching WebKit on a macos-14 runner.
- - name: macOS
- os: macos-15
-
- # Exclude windows and macos from being built on feature branches
- run-all:
- - ${{ github.ref == 'refs/heads/main' || contains(github.event.pull_request.body, '[ci-all]') || github.event.pull_request.user.login == 'depfu[bot]' }}
- exclude:
- - run-all: false
- runner:
- name: Windows
- - run-all: false
- runner:
- name: macOS
-
- runs-on: ${{ matrix.runner.os }}
- timeout-minutes: 30
-
- name: ${{ matrix.runner.name }}
-
- steps:
- - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6
- with:
- persist-credentials: false
- - uses: pnpm/action-setup@0ebf47130e4866e96fce0953f49152a61190b271 # v6.0.9
-
- - name: Use Node.js ${{ env.NODE_VERSION }}
- uses: actions/setup-node@48b55a011bda9f5d6aeb4c2d9c7362e8dae4041e # v6
- with:
- node-version: ${{ env.NODE_VERSION }}
-
- # Cargo already skips downloading dependencies if they already exist
- - name: Cache cargo
- uses: actions/cache@27d5ce7f107fe9357f9df03efb73ab90386fccae # v5
- with:
- path: |
- ~/.cargo/registry/index/
- ~/.cargo/registry/cache/
- ~/.cargo/git/db/
- target/
- key: ${{ runner.os }}-cargo-${{ hashFiles('**/Cargo.lock') }}
-
- # Cache the `oxide` Rust build
- - name: Cache oxide build
- uses: actions/cache@27d5ce7f107fe9357f9df03efb73ab90386fccae # v5
- with:
- path: |
- ./crates/node/*.node
- ./crates/node/*.wasm
- ./crates/node/index.d.ts
- ./crates/node/index.js
- ./crates/node/browser.js
- ./crates/node/tailwindcss-oxide.wasi-browser.js
- ./crates/node/tailwindcss-oxide.wasi.cjs
- ./crates/node/wasi-worker-browser.mjs
- ./crates/node/wasi-worker.mjs
- key: ${{ runner.os }}-oxide-${{ hashFiles('./crates/**/*') }}
-
- - name: Setup WASM target
- run: rustup target add wasm32-wasip1-threads
-
- - name: Install dependencies
- run: pnpm install --frozen-lockfile
-
- - name: Build
- run: pnpm run build
- env:
- CARGO_PROFILE_RELEASE_LTO: 'off'
- CARGO_TARGET_X86_64_PC_WINDOWS_MSVC_LINKER: 'lld-link'
-
- - name: Lint
- run: pnpm run lint
- # Only lint on linux to avoid \r\n line ending errors
- if: matrix.runner.os == 'ubuntu-latest'
-
- - name: Test
- run: pnpm run test
-
- - name: Install Playwright Browsers
- run: npx playwright install --with-deps
-
- - name: Run Playwright tests
- run: npm run test:ui
-
- notify:
- if: ${{ always() && github.ref == 'refs/heads/main' && needs.tests.result == 'failure' }}
- needs: tests
- runs-on: ubuntu-latest
- steps:
- - name: Notify Discord
- uses: discord-actions/message@5c7149c81a83146e5d01f142be1bf87a61831c4d # v2
- with:
- webhookUrl: ${{ secrets.DISCORD_WEBHOOK_URL }}
- message: 'The [most recent ${{ github.workflow }} workflow](<${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }}>) on the `main` branch has failed.'
diff --git a/.github/workflows/integration-tests.yml b/.github/workflows/integration-tests.yml
deleted file mode 100644
index 457c38424..000000000
--- a/.github/workflows/integration-tests.yml
+++ /dev/null
@@ -1,125 +0,0 @@
-name: Integration Tests
-
-on:
- push:
- branches: [main]
- pull_request:
-
-permissions:
- contents: read
-
-env:
- NODE_VERSION: 24
-
-concurrency:
- group: ${{ github.workflow }}-${{ github.ref }}
- cancel-in-progress: true
-
-jobs:
- tests:
- strategy:
- fail-fast: false
- matrix:
- runner:
- - name: Windows
- os: windows-latest
-
- - name: Linux
- os: namespace-profile-default
-
- - name: macOS
- os: macos-14
-
- integration:
- - upgrade
- - vite
- - cli
- - postcss
- - oxide
- - webpack
-
- # Exclude windows and macos from being built on feature branches
- run-all:
- - ${{ github.ref == 'refs/heads/main' || contains(github.event.pull_request.body, '[ci-all]') }}
- exclude:
- - run-all: false
- runner:
- name: Windows
- - run-all: false
- runner:
- name: macOS
-
- runs-on: ${{ matrix.runner.os }}
- timeout-minutes: 30
-
- name: ${{ matrix.runner.name }} / ${{ matrix.integration }}
-
- steps:
- - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6
- with:
- persist-credentials: false
- - uses: pnpm/action-setup@0ebf47130e4866e96fce0953f49152a61190b271 # v6.0.9
-
- - run: |
- git config --global user.name "github-actions[bot]"
- git config --global user.email "41898282+github-actions[bot]@users.noreply.github.com"
-
- - name: Use Node.js ${{ env.NODE_VERSION }}
- uses: actions/setup-node@48b55a011bda9f5d6aeb4c2d9c7362e8dae4041e # v6
- with:
- node-version: ${{ env.NODE_VERSION }}
-
- # Cargo already skips downloading dependencies if they already exist
- - name: Cache cargo
- uses: actions/cache@27d5ce7f107fe9357f9df03efb73ab90386fccae # v5
- with:
- path: |
- ~/.cargo/registry/index/
- ~/.cargo/registry/cache/
- ~/.cargo/git/db/
- target/
- key: ${{ runner.os }}-cargo-${{ hashFiles('**/Cargo.lock') }}
-
- # Cache the `oxide` Rust build
- - name: Cache oxide build
- uses: actions/cache@27d5ce7f107fe9357f9df03efb73ab90386fccae # v5
- with:
- path: |
- ./crates/node/*.node
- ./crates/node/*.wasm
- ./crates/node/index.d.ts
- ./crates/node/index.js
- ./crates/node/browser.js
- ./crates/node/tailwindcss-oxide.wasi-browser.js
- ./crates/node/tailwindcss-oxide.wasi.cjs
- ./crates/node/wasi-worker-browser.mjs
- ./crates/node/wasi-worker.mjs
- key: ${{ runner.os }}-oxide-${{ hashFiles('./crates/**/*') }}
-
- - name: Setup WASM target
- run: rustup target add wasm32-wasip1-threads
-
- - name: Install dependencies
- run: pnpm install
-
- - name: Build
- run: pnpm run build
- env:
- CARGO_PROFILE_RELEASE_LTO: 'off'
- CARGO_TARGET_X86_64_PC_WINDOWS_MSVC_LINKER: 'lld-link'
-
- - name: Test ${{ matrix.integration }}
- run: pnpm run test:integrations ./integrations/${{ matrix.integration }}
- env:
- GITHUB_WORKSPACE: ${{ github.workspace }}
-
- notify:
- if: ${{ always() && github.ref == 'refs/heads/main' && needs.tests.result == 'failure' }}
- needs: tests
- runs-on: ubuntu-latest
- steps:
- - name: Notify Discord
- uses: discord-actions/message@5c7149c81a83146e5d01f142be1bf87a61831c4d # v2
- with:
- webhookUrl: ${{ secrets.DISCORD_WEBHOOK_URL }}
- message: 'The [most recent ${{ github.workflow }} workflow](<${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }}>) on the `main` branch has failed.'
diff --git a/.github/workflows/nodejs.yml b/.github/workflows/nodejs.yml
new file mode 100644
index 000000000..7be71d1e0
--- /dev/null
+++ b/.github/workflows/nodejs.yml
@@ -0,0 +1,43 @@
+# This workflow will do a clean install of node dependencies, build the source code and run tests across different versions of node
+# For more information see: https://help.github.com/actions/language-and-framework-guides/using-nodejs-with-github-actions
+
+name: Node.js CI
+
+on:
+ push:
+ branches: [master]
+ pull_request:
+ branches: [master]
+
+jobs:
+ build:
+ runs-on: ubuntu-latest
+
+ strategy:
+ matrix:
+ node-version: [12.x, 14.x]
+
+ steps:
+ - uses: actions/checkout@v2.3.3
+ - name: Use Node.js ${{ matrix.node-version }}
+ uses: actions/setup-node@v1.4.4
+ with:
+ node-version: ${{ matrix.node-version }}
+ - name: Use cached node_modules
+ id: cache
+ uses: actions/cache@v2.1.1
+ with:
+ path: node_modules
+ key: nodeModules-${{ hashFiles('**/yarn.lock') }}-${{ matrix.node-version }}
+ restore-keys: |
+ nodeModules-
+ - name: Install dependencies
+ if: steps.cache.outputs.cache-hit != 'true'
+ run: npm install
+ env:
+ CI: true
+ - run: npm run prepublishOnly
+ - run: npm test
+ env:
+ CI: true
+ - run: bash <(curl -s --retry 5 --retry-delay 2 --connect-timeout 2 https://codecov.io/bash)
diff --git a/.github/workflows/prepare-release.yml b/.github/workflows/prepare-release.yml
deleted file mode 100644
index 24e829afd..000000000
--- a/.github/workflows/prepare-release.yml
+++ /dev/null
@@ -1,307 +0,0 @@
-name: Prepare Release
-
-on:
- workflow_dispatch:
- inputs:
- dry_run:
- description: Skip creating the draft GitHub release
- required: false
- default: true
- type: boolean
- push:
- tags:
- - 'v*'
-
-env:
- APP_NAME: tailwindcss-oxide
- NODE_VERSION: 24
- PNPM_VERSION: '11.9.0'
- OXIDE_LOCATION: ./crates/node
-
-permissions:
- contents: read
-
-concurrency:
- group: ${{ github.workflow }}-${{ github.ref }}
- cancel-in-progress: true
-
-jobs:
- build:
- strategy:
- matrix:
- include:
- # Windows
- - os: windows-latest
- target: x86_64-pc-windows-msvc
- - os: windows-latest
- target: aarch64-pc-windows-msvc
- # macOS
- - os: macos-latest
- target: x86_64-apple-darwin
- strip: strip -x # Must use -x on macOS. This produces larger results on linux.
- - os: macos-latest
- target: aarch64-apple-darwin
- page-size: 14
- strip: strip -x # Must use -x on macOS. This produces larger results on linux.
- # Android
- - os: ubuntu-latest
- target: aarch64-linux-android
- strip: ${ANDROID_NDK_LATEST_HOME}/toolchains/llvm/prebuilt/linux-x86_64/bin/llvm-strip
- - os: ubuntu-latest
- target: armv7-linux-androideabi
- strip: ${ANDROID_NDK_LATEST_HOME}/toolchains/llvm/prebuilt/linux-x86_64/bin/llvm-strip
- # Linux
- - os: ubuntu-latest
- target: x86_64-unknown-linux-gnu
- strip: strip
- build-flags: --use-napi-cross
- - os: ubuntu-latest
- target: aarch64-unknown-linux-gnu
- strip: aarch64-linux-gnu-strip
- build-flags: --use-napi-cross
- - os: ubuntu-latest
- target: armv7-unknown-linux-gnueabihf
- strip: arm-linux-gnueabihf-strip
- build-flags: --use-napi-cross
- - os: ubuntu-latest
- target: aarch64-unknown-linux-musl
- strip-zig: true
- build-flags: -x
- - os: ubuntu-latest
- target: x86_64-unknown-linux-musl
- strip: strip
- build-flags: -x
-
- name: Build ${{ matrix.target }} (oxide)
- runs-on: ${{ matrix.os }}
- timeout-minutes: 15
- steps:
- - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6
- with:
- persist-credentials: false
- - uses: pnpm/action-setup@0ebf47130e4866e96fce0953f49152a61190b271 # v6.0.9
- with:
- version: ${{ env.PNPM_VERSION }}
-
- - name: Use Node.js ${{ env.NODE_VERSION }}
- uses: actions/setup-node@48b55a011bda9f5d6aeb4c2d9c7362e8dae4041e # v6
- with:
- node-version: ${{ env.NODE_VERSION }}
- package-manager-cache: false
-
- - name: Install gcc-arm-linux-gnueabihf
- if: ${{ matrix.target == 'armv7-unknown-linux-gnueabihf' }}
- run: |
- sudo apt-get update
- sudo apt-get install gcc-arm-linux-gnueabihf g++-arm-linux-gnueabihf -y
-
- - name: Install binutils-aarch64-linux-gnu
- if: ${{ matrix.target == 'aarch64-unknown-linux-gnu' }}
- run: |
- sudo apt-get update
- sudo apt-get install binutils-aarch64-linux-gnu -y
-
- - uses: mlugg/setup-zig@d1434d08867e3ee9daa34448df10607b98908d29 # v2
- if: ${{ contains(matrix.target, 'musl') }}
- with:
- version: 0.14.1
- use-cache: false
-
- - name: Install cargo-zigbuild
- uses: taiki-e/install-action@65851e10cd6c377f11a60e600abc07cb08643468 # v2
- if: ${{ contains(matrix.target, 'musl') }}
- env:
- GITHUB_TOKEN: ${{ github.token }}
- with:
- tool: cargo-zigbuild
-
- - name: Setup rust target
- run: rustup target add ${{ matrix.target }}
-
- - name: Install dependencies
- run: pnpm install --ignore-scripts --frozen-lockfile --filter=!./playgrounds/*
-
- - name: Build release
- run: pnpm run --filter ${{ env.OXIDE_LOCATION }} build:platform --target=${{ matrix.target }} ${{ matrix.build-flags }}
- env:
- RUST_TARGET: ${{ matrix.target }}
- JEMALLOC_SYS_WITH_LG_PAGE: ${{ matrix.page-size }}
-
- - name: Strip debug symbols # https://github.com/rust-lang/rust/issues/46034
- if: ${{ matrix.strip || matrix.strip-zig }}
- env:
- STRIP_COMMAND: ${{ matrix.strip }}
- STRIP_ZIG: ${{ matrix.strip-zig }}
- run: |
- if [ "$STRIP_ZIG" = "true" ]; then
- for file in ${{ env.OXIDE_LOCATION }}/*.node; do
- zig objcopy --strip-all "$file" "$file.stripped"
- mv "$file.stripped" "$file"
- done
- exit 0
- fi
-
- eval "$STRIP_COMMAND ${{ env.OXIDE_LOCATION }}/*.node"
-
- - name: Upload artifacts
- uses: actions/upload-artifact@b7c566a772e6b6bfb58ed0dc250532a479d7789f # v6
- with:
- name: bindings-${{ matrix.target }}
- path: ${{ env.OXIDE_LOCATION }}/*.node
-
- build-freebsd:
- name: Build x86_64-unknown-freebsd (OXIDE)
- runs-on: ubuntu-latest
- timeout-minutes: 15
- steps:
- - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6
- with:
- persist-credentials: false
- - name: Build FreeBSD
- uses: cross-platform-actions/action@cdc9ee69ef84a5f2e59c9058335d9c57bcb4ac86 # v0.25.0
- env:
- DEBUG: napi:*
- RUSTUP_HOME: /usr/local/rustup
- CARGO_HOME: /usr/local/cargo
- RUSTUP_IO_THREADS: 1
- RUST_TARGET: x86_64-unknown-freebsd
- with:
- operating_system: freebsd
- version: '14.0'
- memory: 13G
- cpu_count: 3
- environment_variables: 'DEBUG RUSTUP_IO_THREADS'
- shell: bash
- run: |
- sudo pkg install -y -f curl node libnghttp2 npm
- sudo npm install -g pnpm@${{ env.PNPM_VERSION }} --unsafe-perm=true
- curl -sSf https://static.rust-lang.org/rustup/archive/1.27.1/x86_64-unknown-freebsd/rustup-init --output rustup-init
- chmod +x rustup-init
- ./rustup-init -y --profile minimal
- source "$HOME/.cargo/env"
- pnpm install --ignore-scripts --frozen-lockfile --filter=!./playgrounds/* || true
- echo "~~~~ rustc --version ~~~~"
- rustc --version
- echo "~~~~ node -v ~~~~"
- node -v
- echo "~~~~ pnpm --version ~~~~"
- pnpm --version
- pnpm run --filter ${{ env.OXIDE_LOCATION }} build:platform
- strip -x ${{ env.OXIDE_LOCATION }}/*.node
- ls -la ${{ env.OXIDE_LOCATION }}
- - name: Upload artifacts
- uses: actions/upload-artifact@b7c566a772e6b6bfb58ed0dc250532a479d7789f # v6
- with:
- name: bindings-x86_64-unknown-freebsd
- path: ${{ env.OXIDE_LOCATION }}/*.node
-
- prepare:
- runs-on: macos-14
- timeout-minutes: 15
- name: Build and release Tailwind CSS
-
- permissions:
- contents: write # Required for creating releases
-
- needs:
- - build
- - build-freebsd
-
- steps:
- - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6
- with:
- fetch-depth: 20
- persist-credentials: false
-
- - run: git fetch --tags -f
-
- - name: Resolve version
- id: vars
- run: |
- echo "TAG_NAME=$(git describe --tags --abbrev=0)" >> $GITHUB_ENV
-
- - uses: pnpm/action-setup@0ebf47130e4866e96fce0953f49152a61190b271 # v6.0.9
- with:
- version: ${{ env.PNPM_VERSION }}
-
- - name: Use Node.js ${{ env.NODE_VERSION }}
- uses: actions/setup-node@48b55a011bda9f5d6aeb4c2d9c7362e8dae4041e # v6
- with:
- node-version: ${{ env.NODE_VERSION }}
- registry-url: 'https://registry.npmjs.org'
- package-manager-cache: false
-
- - name: Setup WASM target
- run: rustup target add wasm32-wasip1-threads
-
- - name: Install dependencies
- run: pnpm --filter=!./playgrounds/* install --frozen-lockfile
-
- - name: Download artifacts
- uses: actions/download-artifact@37930b1c2abaa49bbe596cd826c3c89aef350131 # v7
- with:
- path: ${{ env.OXIDE_LOCATION }}
-
- - name: Move artifacts
- run: |
- cd ${{ env.OXIDE_LOCATION }}
- cp bindings-x86_64-pc-windows-msvc/* ./npm/win32-x64-msvc/
- cp bindings-aarch64-pc-windows-msvc/* ./npm/win32-arm64-msvc/
- cp bindings-x86_64-apple-darwin/* ./npm/darwin-x64/
- cp bindings-aarch64-apple-darwin/* ./npm/darwin-arm64/
- cp bindings-aarch64-linux-android/* ./npm/android-arm64/
- cp bindings-armv7-linux-androideabi/* ./npm/android-arm-eabi/
- cp bindings-aarch64-unknown-linux-gnu/* ./npm/linux-arm64-gnu/
- cp bindings-aarch64-unknown-linux-musl/* ./npm/linux-arm64-musl/
- cp bindings-armv7-unknown-linux-gnueabihf/* ./npm/linux-arm-gnueabihf/
- cp bindings-x86_64-unknown-linux-gnu/* ./npm/linux-x64-gnu/
- cp bindings-x86_64-unknown-linux-musl/* ./npm/linux-x64-musl/
- cp bindings-x86_64-unknown-freebsd/* ./npm/freebsd-x64/
-
- - name: Build Tailwind CSS
- run: pnpm run build
- env:
- FEATURES_ENV: stable
-
- - name: Run pre-publish optimizations scripts
- run: node ./scripts/pre-publish-optimizations.mjs
-
- - name: Lock pre-release versions
- run: node ./scripts/lock-pre-release-versions.mjs
-
- - name: Get release notes
- run: |
- RELEASE_NOTES=$(node ./scripts/release-notes.mjs)
- echo "RELEASE_NOTES<> $GITHUB_ENV
- echo "$RELEASE_NOTES" >> $GITHUB_ENV
- echo "EOF" >> $GITHUB_ENV
-
- - name: Upload standalone artifacts
- uses: actions/upload-artifact@b7c566a772e6b6bfb58ed0dc250532a479d7789f # v6
- with:
- name: tailwindcss-standalone
- path: packages/@tailwindcss-standalone/dist/
-
- - name: Upload npm package tarballs
- uses: actions/upload-artifact@b7c566a772e6b6bfb58ed0dc250532a479d7789f # v6
- with:
- name: npm-package-tarballs
- path: dist/*.tgz
-
- - name: Prepare GitHub Release
- if: ${{ !inputs.dry_run }}
- env:
- GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
- run: |
- gh release create "${TAG_NAME}" \
- --draft \
- --title "${TAG_NAME}" \
- --notes "${RELEASE_NOTES}" \
- packages/@tailwindcss-standalone/dist/sha256sums.txt \
- packages/@tailwindcss-standalone/dist/tailwindcss-linux-arm64 \
- packages/@tailwindcss-standalone/dist/tailwindcss-linux-arm64-musl \
- packages/@tailwindcss-standalone/dist/tailwindcss-linux-x64 \
- packages/@tailwindcss-standalone/dist/tailwindcss-linux-x64-musl \
- packages/@tailwindcss-standalone/dist/tailwindcss-macos-arm64 \
- packages/@tailwindcss-standalone/dist/tailwindcss-macos-x64 \
- packages/@tailwindcss-standalone/dist/tailwindcss-windows-x64.exe
diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml
deleted file mode 100644
index 2c957d3af..000000000
--- a/.github/workflows/release.yml
+++ /dev/null
@@ -1,358 +0,0 @@
-name: Release
-
-on:
- push:
- branches: [main]
- release:
- types: [published]
- workflow_dispatch:
- inputs:
- channel:
- description: Release channel to publish
- required: true
- default: insiders
- type: choice
- options:
- - insiders
- - release
-
-permissions:
- contents: read
-
-env:
- APP_NAME: tailwindcss-oxide
- NODE_VERSION: 24
- PNPM_VERSION: '11.9.0'
- OXIDE_LOCATION: ./crates/node
-
-concurrency:
- group: ${{ github.workflow }}-${{ github.event_name }}-${{ github.ref }}
- cancel-in-progress: true
-
-jobs:
- build:
- strategy:
- matrix:
- include:
- # Windows
- - os: windows-latest
- target: x86_64-pc-windows-msvc
- - os: windows-latest
- target: aarch64-pc-windows-msvc
- # macOS
- - os: macos-latest
- target: x86_64-apple-darwin
- strip: strip -x # Must use -x on macOS. This produces larger results on linux.
- - os: macos-latest
- target: aarch64-apple-darwin
- page-size: 14
- strip: strip -x # Must use -x on macOS. This produces larger results on linux.
- # Android
- - os: ubuntu-latest
- target: aarch64-linux-android
- strip: ${ANDROID_NDK_LATEST_HOME}/toolchains/llvm/prebuilt/linux-x86_64/bin/llvm-strip
- - os: ubuntu-latest
- target: armv7-linux-androideabi
- strip: ${ANDROID_NDK_LATEST_HOME}/toolchains/llvm/prebuilt/linux-x86_64/bin/llvm-strip
- # Linux
- - os: ubuntu-latest
- target: x86_64-unknown-linux-gnu
- strip: strip
- build-flags: --use-napi-cross
- - os: ubuntu-latest
- target: aarch64-unknown-linux-gnu
- strip: aarch64-linux-gnu-strip
- build-flags: --use-napi-cross
- - os: ubuntu-latest
- target: armv7-unknown-linux-gnueabihf
- strip: arm-linux-gnueabihf-strip
- build-flags: --use-napi-cross
- - os: ubuntu-latest
- target: aarch64-unknown-linux-musl
- strip-zig: true
- build-flags: -x
- - os: ubuntu-latest
- target: x86_64-unknown-linux-musl
- strip: strip
- build-flags: -x
-
- name: Build ${{ matrix.target }} (oxide)
- runs-on: ${{ matrix.os }}
- timeout-minutes: 15
- steps:
- - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6
- with:
- persist-credentials: false
- - uses: pnpm/action-setup@0ebf47130e4866e96fce0953f49152a61190b271 # v6.0.9
- with:
- version: ${{ env.PNPM_VERSION }}
-
- - name: Use Node.js ${{ env.NODE_VERSION }}
- uses: actions/setup-node@48b55a011bda9f5d6aeb4c2d9c7362e8dae4041e # v6
- with:
- node-version: ${{ env.NODE_VERSION }}
- package-manager-cache: false
-
- - name: Install gcc-arm-linux-gnueabihf
- if: ${{ matrix.target == 'armv7-unknown-linux-gnueabihf' }}
- run: |
- sudo apt-get update
- sudo apt-get install gcc-arm-linux-gnueabihf g++-arm-linux-gnueabihf -y
-
- - name: Install binutils-aarch64-linux-gnu
- if: ${{ matrix.target == 'aarch64-unknown-linux-gnu' }}
- run: |
- sudo apt-get update
- sudo apt-get install binutils-aarch64-linux-gnu -y
-
- - uses: mlugg/setup-zig@d1434d08867e3ee9daa34448df10607b98908d29 # v2
- if: ${{ contains(matrix.target, 'musl') }}
- with:
- version: 0.14.1
- use-cache: false
-
- - name: Install cargo-zigbuild
- uses: taiki-e/install-action@65851e10cd6c377f11a60e600abc07cb08643468 # v2
- if: ${{ contains(matrix.target, 'musl') }}
- env:
- GITHUB_TOKEN: ${{ github.token }}
- with:
- tool: cargo-zigbuild
-
- - name: Setup rust target
- run: rustup target add ${{ matrix.target }}
-
- - name: Install dependencies
- run: pnpm install --ignore-scripts --frozen-lockfile --filter=!./playgrounds/*
-
- - name: Build release
- run: pnpm run --filter ${{ env.OXIDE_LOCATION }} build:platform --target=${{ matrix.target }} ${{ matrix.build-flags }}
- env:
- RUST_TARGET: ${{ matrix.target }}
- JEMALLOC_SYS_WITH_LG_PAGE: ${{ matrix.page-size }}
-
- - name: Strip debug symbols # https://github.com/rust-lang/rust/issues/46034
- if: ${{ matrix.strip || matrix.strip-zig }}
- env:
- STRIP_COMMAND: ${{ matrix.strip }}
- STRIP_ZIG: ${{ matrix.strip-zig }}
- run: |
- if [ "$STRIP_ZIG" = "true" ]; then
- for file in ${{ env.OXIDE_LOCATION }}/*.node; do
- zig objcopy --strip-all "$file" "$file.stripped"
- mv "$file.stripped" "$file"
- done
- exit 0
- fi
-
- eval "$STRIP_COMMAND ${{ env.OXIDE_LOCATION }}/*.node"
-
- - name: Upload artifacts
- uses: actions/upload-artifact@b7c566a772e6b6bfb58ed0dc250532a479d7789f # v6
- with:
- name: bindings-${{ matrix.target }}
- path: ${{ env.OXIDE_LOCATION }}/*.node
-
- build-freebsd:
- name: Build x86_64-unknown-freebsd (OXIDE)
- runs-on: ubuntu-latest
- timeout-minutes: 15
- steps:
- - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6
- with:
- persist-credentials: false
- - name: Build FreeBSD
- uses: cross-platform-actions/action@cdc9ee69ef84a5f2e59c9058335d9c57bcb4ac86 # v0.25.0
- env:
- DEBUG: napi:*
- RUSTUP_HOME: /usr/local/rustup
- CARGO_HOME: /usr/local/cargo
- RUSTUP_IO_THREADS: 1
- RUST_TARGET: x86_64-unknown-freebsd
- with:
- operating_system: freebsd
- version: '14.0'
- memory: 13G
- cpu_count: 3
- environment_variables: 'DEBUG RUSTUP_IO_THREADS'
- shell: bash
- run: |
- sudo pkg install -y -f curl node libnghttp2 npm
- sudo npm install -g pnpm@${{ env.PNPM_VERSION }} --unsafe-perm=true
- curl -sSf https://static.rust-lang.org/rustup/archive/1.27.1/x86_64-unknown-freebsd/rustup-init --output rustup-init
- chmod +x rustup-init
- ./rustup-init -y --profile minimal
- source "$HOME/.cargo/env"
- echo "~~~~ rustc --version ~~~~"
- rustc --version
- echo "~~~~ node -v ~~~~"
- node -v
- echo "~~~~ pnpm --version ~~~~"
- pnpm --version
- pnpm install --ignore-scripts --frozen-lockfile --filter=!./playgrounds/* || true
- pnpm run --filter ${{ env.OXIDE_LOCATION }} build:platform
- strip -x ${{ env.OXIDE_LOCATION }}/*.node
- ls -la ${{ env.OXIDE_LOCATION }}
- - name: Upload artifacts
- uses: actions/upload-artifact@b7c566a772e6b6bfb58ed0dc250532a479d7789f # v6
- with:
- name: bindings-x86_64-unknown-freebsd
- path: ${{ env.OXIDE_LOCATION }}/*.node
-
- release:
- runs-on: macos-14
- timeout-minutes: 15
- name: Build and publish Tailwind CSS
-
- permissions:
- contents: read
- # https://docs.npmjs.com/generating-provenance-statements#publishing-packages-with-provenance-via-github-actions
- id-token: write
-
- needs:
- - build
- - build-freebsd
-
- steps:
- - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6
- with:
- fetch-depth: 20
- persist-credentials: false
-
- - uses: pnpm/action-setup@0ebf47130e4866e96fce0953f49152a61190b271 # v6.0.9
- with:
- version: ${{ env.PNPM_VERSION }}
-
- - name: Use Node.js ${{ env.NODE_VERSION }}
- uses: actions/setup-node@48b55a011bda9f5d6aeb4c2d9c7362e8dae4041e # v6
- with:
- node-version: ${{ env.NODE_VERSION }}
- registry-url: 'https://registry.npmjs.org'
- package-manager-cache: false
-
- # npm trusted publishing validates the caller workflow filename, so all npm publishes live here.
- # This workflow rebuilds the publish artifacts instead of depending on prepare-release.yml.
- - name: Resolve release metadata
- env:
- INPUT_CHANNEL: ${{ github.event.inputs.channel || '' }}
- run: |
- if [[ "${{ github.event_name }}" == "release" || "$INPUT_CHANNEL" == "release" ]]; then
- release_channel=$(node ./scripts/release-channel.js)
-
- echo "RELEASE_KIND=release" >> $GITHUB_ENV
- echo "RELEASE_CHANNEL=$release_channel" >> $GITHUB_ENV
- echo "FEATURES_ENV=stable" >> $GITHUB_ENV
- else
- sha_short=$(git rev-parse --short HEAD)
-
- echo "RELEASE_KIND=insiders" >> $GITHUB_ENV
- echo "RELEASE_CHANNEL=insiders" >> $GITHUB_ENV
- echo "SHA_SHORT=$sha_short" >> $GITHUB_ENV
- echo "INSIDERS_VERSION=0.0.0-insiders.$sha_short" >> $GITHUB_ENV
- fi
-
- - name: Setup WASM target
- run: rustup target add wasm32-wasip1-threads
-
- - name: Install dependencies
- run: pnpm --filter=!./playgrounds/* install --frozen-lockfile
-
- - name: Download artifacts
- uses: actions/download-artifact@37930b1c2abaa49bbe596cd826c3c89aef350131 # v7
- with:
- path: ${{ env.OXIDE_LOCATION }}
-
- - name: Move artifacts
- run: |
- cd ${{ env.OXIDE_LOCATION }}
- cp bindings-x86_64-pc-windows-msvc/* ./npm/win32-x64-msvc/
- cp bindings-aarch64-pc-windows-msvc/* ./npm/win32-arm64-msvc/
- cp bindings-x86_64-apple-darwin/* ./npm/darwin-x64/
- cp bindings-aarch64-apple-darwin/* ./npm/darwin-arm64/
- cp bindings-aarch64-linux-android/* ./npm/android-arm64/
- cp bindings-armv7-linux-androideabi/* ./npm/android-arm-eabi/
- cp bindings-aarch64-unknown-linux-gnu/* ./npm/linux-arm64-gnu/
- cp bindings-aarch64-unknown-linux-musl/* ./npm/linux-arm64-musl/
- cp bindings-armv7-unknown-linux-gnueabihf/* ./npm/linux-arm-gnueabihf/
- cp bindings-x86_64-unknown-linux-gnu/* ./npm/linux-x64-gnu/
- cp bindings-x86_64-unknown-linux-musl/* ./npm/linux-x64-musl/
- cp bindings-x86_64-unknown-freebsd/* ./npm/freebsd-x64/
-
- - name: 'Version based on commit: ${{ env.INSIDERS_VERSION }}'
- if: env.RELEASE_KIND == 'insiders'
- run: pnpm run version-packages ${INSIDERS_VERSION}
-
- - name: Build Tailwind CSS
- if: env.RELEASE_KIND == 'insiders'
- run: pnpm run build
-
- - name: Build Tailwind CSS
- if: env.RELEASE_KIND == 'release'
- run: pnpm run build
- env:
- FEATURES_ENV: ${{ env.FEATURES_ENV }}
-
- - name: Run pre-publish optimizations scripts
- run: node ./scripts/pre-publish-optimizations.mjs
-
- - name: Lock pre-release versions
- run: node ./scripts/lock-pre-release-versions.mjs
-
- - name: Upload npm package tarballs
- uses: actions/upload-artifact@b7c566a772e6b6bfb58ed0dc250532a479d7789f # v6
- with:
- name: npm-package-tarballs
- path: dist/*.tgz
-
- - name: Publish
- run: |
- pnpm --recursive --filter="!@tailwindcss/oxide-wasm32-wasi" publish --tag ${RELEASE_CHANNEL} --no-git-checks
- # The wasm package needs a special npm config that isn't read when pnpm --recursive is used
- pushd crates/node/npm/wasm32-wasi; pnpm publish --tag ${RELEASE_CHANNEL} --no-git-checks --config.node-linker=hoisted; popd;
-
- - name: Trigger Tailwind Play update
- uses: actions/github-script@ed597411d8f924073f98dfc5c65a23a2325f34cd # v8
- with:
- github-token: ${{ secrets.TAILWIND_PLAY_TOKEN }}
- script: |
- await github.rest.actions.createWorkflowDispatch({
- owner: 'tailwindlabs',
- repo: 'upgrades',
- ref: 'main',
- workflow_id: 'upgrade-tailwindcss.yml'
- })
-
- notify:
- if: ${{ always() && (needs.build.result == 'failure' || needs.build-freebsd.result == 'failure' || needs.release.result == 'failure') }}
- needs:
- - build
- - build-freebsd
- - release
- runs-on: ubuntu-latest
- steps:
- - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6
- with:
- persist-credentials: false
-
- - name: Resolve release label
- id: release
- env:
- INPUT_CHANNEL: ${{ github.event.inputs.channel || '' }}
- RELEASE_TAG: ${{ github.event.release.tag_name || '' }}
- run: |
- if [[ "${{ github.event_name }}" == "release" ]]; then
- tag_name="${RELEASE_TAG:-${GITHUB_REF_NAME}}"
- echo "label=release ${tag_name}" >> $GITHUB_OUTPUT
- elif [[ "$INPUT_CHANNEL" == "release" ]]; then
- version=$(node -p "require('./packages/tailwindcss/package.json').version")
- echo "label=release v${version}" >> $GITHUB_OUTPUT
- else
- sha_short=$(git rev-parse --short HEAD)
- echo "label=insiders release 0.0.0-insiders.${sha_short}" >> $GITHUB_OUTPUT
- fi
-
- - name: Notify Discord
- uses: discord-actions/message@5c7149c81a83146e5d01f142be1bf87a61831c4d # v2
- with:
- webhookUrl: ${{ secrets.DISCORD_WEBHOOK_URL }}
- message: 'The [most recent ${{ github.workflow }} workflow](<${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }}>) for `${{ steps.release.outputs.label }}` has failed.'
diff --git a/.gitignore b/.gitignore
index bbac7d227..ff8619726 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1,10 +1,11 @@
-node_modules/
-dist/
-coverage/
-.turbo
-test-results/
-playwright-report/
-blob-report/
-playwright/.cache/
-target/
-.debug/
+/node_modules
+/coverage
+/lib
+/example
+tailwind.config.js
+index.html
+package-lock.json
+yarn-error.log
+
+# Perf related files
+isolate*.log
\ No newline at end of file
diff --git a/.prettierignore b/.prettierignore
deleted file mode 100644
index 4f50b932f..000000000
--- a/.prettierignore
+++ /dev/null
@@ -1,9 +0,0 @@
-coverage/
-node_modules/
-pnpm-lock.yaml
-target/
-crates/node/index.d.ts
-crates/node/index.js
-crates/ignore/
-.next
-.fingerprint
diff --git a/CHANGELOG.md b/CHANGELOG.md
index e5e6f6f89..4634a270d 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -7,2931 +7,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
## [Unreleased]
-### Added
-
-- Add `@tailwindcss/turbopack` package to run Tailwind CSS with Next.js ([20367](https://github.com/tailwindlabs/tailwindcss/pull/20367))
-
-### Fixed
-
-- Ensure watch mode detects changes to symlinked `@source` files whose real paths aren't otherwise scanned ([#20356](https://github.com/tailwindlabs/tailwindcss/pull/20356))
-- Ensure custom variants using `@scope` wrap the generated utilities instead of nesting inside them ([#20369](https://github.com/tailwindlabs/tailwindcss/pull/20369))
-- Fix flattening of `@scope` at-rules ([#20369](https://github.com/tailwindlabs/tailwindcss/pull/20369))
-- Fix standalone declarations in `@scope`, wrap them in `:where(:scope)` ([#20369](https://github.com/tailwindlabs/tailwindcss/pull/20369))
-- Always emit a space for empty fallback values in CSS variables (e.g. `var(--tw-blur,)` → `var(--tw-blur, )`) ([#20373](https://github.com/tailwindlabs/tailwindcss/pull/20373))
-- Canonicalization: convert arbitrary breakpoint and container query variants to named equivalents (e.g. `max-[64rem]` → `max-lg`) ([#20380](https://github.com/tailwindlabs/tailwindcss/pull/20380))
-- Prevent `@tailwindcss/vite` from crashing on every edit under Vite's experimental `bundledDev` mode ([#20379](https://github.com/tailwindlabs/tailwindcss/pull/20379))
-- Ensure `@tailwindcss/oxide` falls back to WASM on platforms without native bindings ([#20383](https://github.com/tailwindlabs/tailwindcss/pull/20383))
-- Detect classes in Ruby percent literals using angle brackets or custom delimiters (e.g. `%w`, `%w|flex|`), including in Slim and Haml templates ([#20387](https://github.com/tailwindlabs/tailwindcss/pull/20387))
-- Preserve whitespace in `--default(…)` values in custom functional utilities (e.g. `--default(box alphabetic)` no longer becomes `boxalphabetic`) ([#20392](https://github.com/tailwindlabs/tailwindcss/pull/20392))
-- Don't scan gitignored directories (e.g. `node_modules` and `.git`) when the project uses a safelist-style `.gitignore` (e.g. `/*` followed by `!/…` negations) ([#20397](https://github.com/tailwindlabs/tailwindcss/pull/20397))
-- Ensure root `theme('…')` namespace lookups in JavaScript plugins and config files return the full namespace object instead of the value of its `DEFAULT` key ([#20399](https://github.com/tailwindlabs/tailwindcss/pull/20399))
-- Skip ignored directories entirely when computing watch globs (`scanner.globs`), instead of walking their full contents on every rebuild ([#20408](https://github.com/tailwindlabs/tailwindcss/pull/20408))
-- Oxide: drop invalid UTF-8 candidates ([#20389](https://github.com/tailwindlabs/tailwindcss/pull/20389))
-- `@tailwindcss/vite` no longer forces a full page reload for external files (e.g.: `.php` files) ([#20414](https://github.com/tailwindlabs/tailwindcss/issues/20414))
-- Canonicalization: don't merge utilities that reference different theme variables set to CSS-wide keywords like `unset` ([#20417](https://github.com/tailwindlabs/tailwindcss/pull/20417))
-- Don't generate utilities when a modifier is used that would otherwise be silently ignored (e.g. `rounded-sm/[5]`, `shadow-sm/foo`, `stroke-2/50`) ([#20419](https://github.com/tailwindlabs/tailwindcss/pull/20419))
-- Only normalize top-level `and`, `or`, and `not` keywords in `supports-[…]` variants (e.g. `selector(a: not (.foo))` → `selector(a:not(.foo))`) ([#20420](https://github.com/tailwindlabs/tailwindcss/pull/20420))
-- Don't warn about Angular's `::ng-deep` and `:host-context()` when optimizing CSS ([#20434](https://github.com/tailwindlabs/tailwindcss/pull/20434))
-- Don't generate CSS for candidates containing an empty additional modifier (e.g. `bg-red-500/50/` and `group-hover/foo//bar:flex`) ([#20466](https://github.com/tailwindlabs/tailwindcss/pull/20466))
-- Sort `min-*`, `max-*`, and container query variants with decimal values numerically (e.g. `min-[40.25rem]` before `min-[40.5rem]`) ([#20512](https://github.com/tailwindlabs/tailwindcss/pull/20512))
-- Ensure CSS comments ending with `\*/` are closed correctly instead of swallowing the CSS that follows (e.g. `/* C:\temp\*/`) ([#20508](https://github.com/tailwindlabs/tailwindcss/pull/20508))
-- Improve style invalidation performance of `group-*` and `peer-*` variants ([#20513](https://github.com/tailwindlabs/tailwindcss/pull/20513))
-
-## [4.3.3] - 2026-07-16
-
-### Fixed
-
-- Support `--watch --poll[=ms]` in `@tailwindcss/cli` when filesystem events are unreliable or unavailable ([#20297](https://github.com/tailwindlabs/tailwindcss/pull/20297))
-- Canonicalization: match arbitrary hex colors against theme colors case-insensitively (e.g. `bg-[#fff]` and `bg-[#FFF]` → `bg-white`) ([#20298](https://github.com/tailwindlabs/tailwindcss/pull/20298))
-- Prevent Preflight from overriding Firefox's native `iframe:focus-visible` outline styles ([#20292](https://github.com/tailwindlabs/tailwindcss/pull/20292))
-- Ensure `theme('colors.foo')` in JS plugins resolves correctly when both `--color-foo` and `--color-foo-bar` exist ([#20299](https://github.com/tailwindlabs/tailwindcss/pull/20299))
-- Ensure fractional opacity modifiers work with named shadow sizes like `shadow-sm/12.5`, `text-shadow-sm/12.5`, `drop-shadow-sm/12.5`, and `inset-shadow-sm/12.5` ([#20302](https://github.com/tailwindlabs/tailwindcss/pull/20302))
-- Parse selectors like `[data-foo]div` as two selectors instead of one ([#20303](https://github.com/tailwindlabs/tailwindcss/pull/20303))
-- Ensure `@tailwindcss/postcss` rebuilds when a preprocessor like Sass changes the input CSS without changing the input file on disk ([#20310](https://github.com/tailwindlabs/tailwindcss/pull/20310))
-- Ensure CSS nesting is handled even when Lightning CSS isn't run, such as in `@tailwindcss/browser` and Tailwind Play ([#20124](https://github.com/tailwindlabs/tailwindcss/pull/20124))
-- Prevent achromatic theme colors from shifting hue when mixed in polar color spaces like `oklch` ([#20314](https://github.com/tailwindlabs/tailwindcss/pull/20314))
-- Ensure `--spacing(0)` is optimized to `0px` instead of `0` so it remains a `` when used in `calc(…)` ([#20319](https://github.com/tailwindlabs/tailwindcss/pull/20319))
-- Load `@parcel/watcher` only when needed in `@tailwindcss/cli --watch` mode, so one-off builds and `--watch --poll` work when `@parcel/watcher` can't be loaded ([#20325](https://github.com/tailwindlabs/tailwindcss/pull/20325))
-- Use explicit platform fonts instead of `system-ui` and `ui-sans-serif` so CJK text respects the page's `lang` attribute on Windows ([#20318](https://github.com/tailwindlabs/tailwindcss/pull/20318))
-- Prevent `@tailwindcss/upgrade` from rewriting ignored files when run from a subdirectory ([#20329](https://github.com/tailwindlabs/tailwindcss/pull/20329))
-- Ensure earlier `@source` rules pointing to nested files are scanned when later `@source` rules point to files in parent folders ([#20335](https://github.com/tailwindlabs/tailwindcss/pull/20335))
-- Prevent `@tailwindcss/vite` from triggering full page reloads when scanned files are processed by Vite but haven't been loaded as modules yet ([#20336](https://github.com/tailwindlabs/tailwindcss/pull/20336))
-
-## [4.3.2] - 2026-06-26
-
-### Fixed
-
-- Support bare spacing values for `auto-rows-*` and `auto-cols-*` utilities (e.g. `auto-rows-12` and `auto-cols-16`) ([#20229](https://github.com/tailwindlabs/tailwindcss/pull/20229))
-- Prevent `@tailwindcss/cli` in `--watch` mode from crashing on Windows when `@source` points to a directory that doesn't exist ([#20242](https://github.com/tailwindlabs/tailwindcss/pull/20242))
-- Prevent `@tailwindcss/vite` from crashing in Deno v2.8.x when `context.parentURL` is not a valid URL ([#20245](https://github.com/tailwindlabs/tailwindcss/pull/20245))
-- Ensure `@tailwindcss/cli` in `--watch` mode rebuilds when the input CSS file changes in an ignored directory ([#20246](https://github.com/tailwindlabs/tailwindcss/pull/20246))
-- Allow `@variant` rules used in `addBase(…)` to use custom variants defined later ([#20247](https://github.com/tailwindlabs/tailwindcss/pull/20247))
-- Prevent `@tailwindcss/vite` from crashing during HMR when scanned files or directories are deleted ([#20259](https://github.com/tailwindlabs/tailwindcss/pull/20259))
-- Generate `font-size` instead of `color` declarations for `text-[--spacing(…)]` ([#20260](https://github.com/tailwindlabs/tailwindcss/pull/20260))
-- Prevent `@source` patterns from scanning unrelated sibling files and folders ([#20263](https://github.com/tailwindlabs/tailwindcss/pull/20263))
-- Extract class candidates adjacent to Template Toolkit delimiters like `%]…[%` in `.tt`, `.tt2`, and `.tx` files ([#20269](https://github.com/tailwindlabs/tailwindcss/pull/20269))
-- Extract class candidates from conditional Maud syntax like `p.text-black[condition]` ([#20269](https://github.com/tailwindlabs/tailwindcss/pull/20269))
-- Prevent `@position-try` rules from triggering unknown at-rule warnings when optimizing CSS ([#20277](https://github.com/tailwindlabs/tailwindcss/pull/20277))
-- Support class suggestions for named opacity modifiers from `--opacity` theme values ([#20287](https://github.com/tailwindlabs/tailwindcss/pull/20287))
-- Prevent type errors in `@tailwindcss/postcss` when used with newer PostCSS patch releases ([#20289](https://github.com/tailwindlabs/tailwindcss/pull/20289))
-
-## [4.3.1] - 2026-06-12
-
-### Added
-
-- Add `--silent` option to suppress output in `@tailwindcss/cli` ([#20100](https://github.com/tailwindlabs/tailwindcss/pull/20100))
-
-### Fixed
-
-- Remove deprecation warnings by using `Module#registerHooks` instead of `Module#register` on Node 26+ ([#20028](https://github.com/tailwindlabs/tailwindcss/pull/20028))
-- Canonicalization: don't crash when plugin utilities throw for unsupported values ([#20052](https://github.com/tailwindlabs/tailwindcss/pull/20052))
-- Allow `@apply` to be used with CSS mixins ([#19427](https://github.com/tailwindlabs/tailwindcss/pull/19427))
-- Ensure `not-*` correctly negates `@container` queries, including `style(…)` queries ([#20059](https://github.com/tailwindlabs/tailwindcss/pull/20059))
-- Ensure `drop-shadow-*` color utilities work with custom shadow values containing `calc(…)` ([#20080](https://github.com/tailwindlabs/tailwindcss/pull/20080))
-- Fix 'Sourcemap is likely to be incorrect' warnings when using `@tailwindcss/vite` ([#20103](https://github.com/tailwindlabs/tailwindcss/pull/20103))
-- Ensure `@tailwindcss/webpack` can be installed in Rspack projects without requiring `webpack` as a peer dependency ([#20027](https://github.com/tailwindlabs/tailwindcss/pull/20027))
-- Canonicalization: don't suggest invalid `calc(…)` expressions (e.g. `px-[calc(1rem+0px)]` → `px-[calc(1rem+0)]`) ([#20127](https://github.com/tailwindlabs/tailwindcss/pull/20127))
-- Canonicalization: avoid suggesting large spacing-scale values for arbitrary lengths (e.g. `left-[99999px]` → `left-[99999px]`, not `left-24999.75`) ([#20130](https://github.com/tailwindlabs/tailwindcss/pull/20130))
-- Ensure `@tailwindcss/cli` in `--watch` mode recovers when a tracked dependency is deleted and restored ([#20137](https://github.com/tailwindlabs/tailwindcss/pull/20137))
-- Ensure standalone `@tailwindcss/cli` binaries are ignored when scanning for class candidates ([#20139](https://github.com/tailwindlabs/tailwindcss/pull/20139))
-- Ensure class candidates are extracted from Twig `addClass(…)` and `removeClass(…)` calls ([#20198](https://github.com/tailwindlabs/tailwindcss/pull/20198))
-- Don't crash in the Ruby or Vue preprocessors when scanning files containing invalid UTF-8 bytes ([#19588](https://github.com/tailwindlabs/tailwindcss/pull/19588))
-- Allow `@variant` to be used inside `addBase` ([#19480](https://github.com/tailwindlabs/tailwindcss/pull/19480))
-- Ensure `@source` globs with symlinks are preserved ([#20203](https://github.com/tailwindlabs/tailwindcss/pull/20203))
-- Ensure later `@source` rules can re-include files excluded by earlier `@source not` rules ([#20203](https://github.com/tailwindlabs/tailwindcss/pull/20203))
-- Upgrade: don't migrate empty class rules to invalid `@utility` rules ([#20205](https://github.com/tailwindlabs/tailwindcss/pull/20205))
-- Ensure transitions between `inset-shadow-none` and other inset shadows work correctly ([#20208](https://github.com/tailwindlabs/tailwindcss/pull/20208))
-- Ensure explicitly referenced `@source` directories are scanned even when ignored by git ([#20214](https://github.com/tailwindlabs/tailwindcss/pull/20214))
-- Ensure `@source` globs ending in `**/*` preserve dynamic path segments to avoid scanning too many files ([#20217](https://github.com/tailwindlabs/tailwindcss/pull/20217))
-- Canonicalization: don't fold `calc(…)` divisions when the result would require high precision (e.g. `w-[calc(100%/3.5)]` → `w-[calc(100%/3.5)]`, not `w-[28.571428571428573%]`) ([#20221](https://github.com/tailwindlabs/tailwindcss/pull/20221))
-- Serve ESM type declarations to ESM importers of `@tailwindcss/postcss` ([#20228](https://github.com/tailwindlabs/tailwindcss/pull/20228))
-
-### Changed
-
-- Generate `0` instead of `calc(var(--spacing) * 0)` for spacing utilities like `m-0` and `left-0` ([#20196](https://github.com/tailwindlabs/tailwindcss/pull/20196))
-- Generate `var(--spacing)` instead of `calc(var(--spacing) * 1)` for spacing utilities like `m-1` and `left-1` ([#20196](https://github.com/tailwindlabs/tailwindcss/pull/20196))
-
-## [4.3.0] - 2026-05-08
-
-### Added
-
-- Add `@container-size` utility ([#18901](https://github.com/tailwindlabs/tailwindcss/pull/18901))
-- Add `scrollbar-{auto,thin,none}` utilities for `scrollbar-width`, and `scrollbar-thumb-*` / `scrollbar-track-*` color utilities for `scrollbar-color` ([#19981](https://github.com/tailwindlabs/tailwindcss/pull/19981), [#20019](https://github.com/tailwindlabs/tailwindcss/pull/20019))
-- Add `scrollbar-gutter-*` utilities ([#20018](https://github.com/tailwindlabs/tailwindcss/pull/20018))
-- Add `zoom-*` utilities ([#20020](https://github.com/tailwindlabs/tailwindcss/pull/20020))
-- Add `tab-*` utilities ([#20022](https://github.com/tailwindlabs/tailwindcss/pull/20022))
-- Allow using `@variant` with stacked variants (e.g. `@variant hover:focus { … }`) ([#19996](https://github.com/tailwindlabs/tailwindcss/pull/19996))
-- Allow using `@variant` with compound variants (e.g. `@variant hover, focus { … }`) ([#19996](https://github.com/tailwindlabs/tailwindcss/pull/19996))
-- Support `--default(…)` in `--value(…)` and `--modifier(…)` for functional `@utility` definitions ([#19989](https://github.com/tailwindlabs/tailwindcss/pull/19989))
-
-### Fixed
-
-- Ensure `@plugin` resolves package JavaScript entries instead of browser CSS entries when using `@tailwindcss/vite` ([#19949](https://github.com/tailwindlabs/tailwindcss/pull/19949))
-- Fix relative `@import` and `@plugin` paths resolving from the wrong directory when using `@tailwindcss/vite` ([#19965](https://github.com/tailwindlabs/tailwindcss/pull/19965))
-- Ensure CSS files containing `@variant` are processed by `@tailwindcss/vite` ([#19966](https://github.com/tailwindlabs/tailwindcss/pull/19966))
-- Resolve imports relative to `base` when `result.opts.from` is not provided when using `@tailwindcss/postcss` ([#19980](https://github.com/tailwindlabs/tailwindcss/pull/19980))
-- Canonicalization: preserve significant `_` whitespace in arbitrary values ([#19986](https://github.com/tailwindlabs/tailwindcss/pull/19986))
-- Canonicalization: add parentheses when removing whitespace from arbitrary values would hurt readability (e.g. `w-[calc(100%---spacing(60))]` → `w-[calc(100%-(--spacing(60)))]`) ([#19986](https://github.com/tailwindlabs/tailwindcss/pull/19986))
-- Canonicalization: preserve the original unit in arbitrary values instead of normalizing to base units (e.g. `-mt-[20in]` → `mt-[-20in]`, not `mt-[-1920px]`) ([#19988](https://github.com/tailwindlabs/tailwindcss/pull/19988))
-- Canonicalization: migrate arbitrary `:has()` variants from `[&:has(…)]` to `has-[…]` ([#19991](https://github.com/tailwindlabs/tailwindcss/pull/19991))
-- Upgrade: don’t migrate inline `style` attributes (e.g. `style="flex-grow: 1"` → `style="flex-grow: 1"`, not `style="grow: 1"`) ([#19918](https://github.com/tailwindlabs/tailwindcss/pull/19918))
-- Allow multiple `@utility` definitions with the same name but different value types ([#19777](https://github.com/tailwindlabs/tailwindcss/pull/19777))
-- Export missing `PluginWithConfig` type from `tailwindcss/plugin` to fix errors when inferring plugin config types ([#19707](https://github.com/tailwindlabs/tailwindcss/pull/19707))
-- Ensure `start` and `end` legacy utilities without values do not generate CSS ([#20003](https://github.com/tailwindlabs/tailwindcss/pull/20003))
-- Ensure `--value(…)` is required in functional `@utility` definitions ([#20005](https://github.com/tailwindlabs/tailwindcss/pull/20005))
-- Canonicalization: preserve required whitespace around operators in negated arbitrary values (e.g. `-left-[(var(--a)+var(--b))]`) ([#20011](https://github.com/tailwindlabs/tailwindcss/pull/20011))
-
-## [4.2.4] - 2026-04-21
-
-### Fixed
-
-- Ensure imports in `@import` and `@plugin` still resolve correctly when using Vite aliases in `@tailwindcss/vite` ([#19947](https://github.com/tailwindlabs/tailwindcss/pull/19947))
-
-## [4.2.3] - 2026-04-20
-
-### Fixed
-
-- Canonicalization: improve canonicalization for `tracking-*` utilities by preferring non-negative utilities (e.g. `-tracking-tighter` → `tracking-wider`) ([#19827](https://github.com/tailwindlabs/tailwindcss/pull/19827))
-- Fix crash due to invalid characters in candidate (exceeding valid unicode code point range) ([#19829](https://github.com/tailwindlabs/tailwindcss/pull/19829))
-- Ensure query params in imports are considered unique resources when using `@tailwindcss/webpack` ([#19723](https://github.com/tailwindlabs/tailwindcss/pull/19723))
-- Canonicalization: collapse arbitrary values into shorthand utilities (e.g. `px-[1.2rem] py-[1.2rem]` → `p-[1.2rem]`) ([#19837](https://github.com/tailwindlabs/tailwindcss/pull/19837))
-- Canonicalization: collapse `border-{t,b}-*` into `border-y-*`, `border-{l,r}-*` into `border-x-*`, and `border-{t,r,b,l}-*` into `border-*` ([#19842](https://github.com/tailwindlabs/tailwindcss/pull/19842))
-- Canonicalization: collapse `scroll-m{t,b}-*` into `scroll-my-*`, `scroll-m{l,r}-*` into `scroll-mx-*`, and `scroll-m{t,r,b,l}-*` into `scroll-m-*` ([#19842](https://github.com/tailwindlabs/tailwindcss/pull/19842))
-- Canonicalization: collapse `scroll-p{t,b}-*` into `scroll-py-*`, `scroll-p{l,r}-*` into `scroll-px-*`, and `scroll-p{t,r,b,l}-*` into `scroll-p-*` ([#19842](https://github.com/tailwindlabs/tailwindcss/pull/19842))
-- Canonicalization: collapse `overflow-{x,y}-*` into `overflow-*` ([#19842](https://github.com/tailwindlabs/tailwindcss/pull/19842))
-- Canonicalization: collapse `overscroll-{x,y}-*` into `overscroll-*` ([#19842](https://github.com/tailwindlabs/tailwindcss/pull/19842))
-- Read from `--placeholder-color` instead of `--background-color` for `placeholder-*` utilities ([#19843](https://github.com/tailwindlabs/tailwindcss/pull/19843))
-- Upgrade: ensure files are not emptied out when killing the upgrade process while it's running ([#19846](https://github.com/tailwindlabs/tailwindcss/pull/19846))
-- Upgrade: use `config.content` when migrating from Tailwind CSS v3 to Tailwind CSS v4 ([#19846](https://github.com/tailwindlabs/tailwindcss/pull/19846))
-- Upgrade: never migrate files that are ignored by git ([#19846](https://github.com/tailwindlabs/tailwindcss/pull/19846))
-- Add `.env` and `.env.*` to default ignored content files ([#19846](https://github.com/tailwindlabs/tailwindcss/pull/19846))
-- Canonicalization: migrate `overflow-ellipsis` into `text-ellipsis` ([#19849](https://github.com/tailwindlabs/tailwindcss/pull/19849))
-- Canonicalization: migrate `start-full` → `inset-s-full`, `start-auto` → `inset-s-auto`, `start-px` → `inset-s-px`, and `start-` → `inset-s-` as well as negative versions ([#19849](https://github.com/tailwindlabs/tailwindcss/pull/19849))
-- Canonicalization: migrate `end-full` → `inset-e-full`, `end-auto` → `inset-e-auto`, `end-px` → `inset-e-px`, and `end-` → `inset-e-` as well as negative versions ([#19849](https://github.com/tailwindlabs/tailwindcss/pull/19849))
-- Canonicalization: move the `-` sign inside the arbitrary value `-left-[9rem]` → `left-[-9rem]` ([#19858](https://github.com/tailwindlabs/tailwindcss/pull/19858))
-- Canonicalization: move the `-` sign outside the arbitrary value `ml-[calc(-1*var(--width))]` → `-ml-(--width)` ([#19858](https://github.com/tailwindlabs/tailwindcss/pull/19858))
-- Improve performance when scanning JSONL / NDJSON files ([#19862](https://github.com/tailwindlabs/tailwindcss/pull/19862))
-- Support `NODE_PATH` environment variable in standalone CLI ([#19617](https://github.com/tailwindlabs/tailwindcss/pull/19617))
-
-## [4.2.2] - 2026-03-18
-
-### Fixed
-
-- Don't crash when candidates contain prototype properties like `row-constructor` ([#19725](https://github.com/tailwindlabs/tailwindcss/pull/19725))
-- Canonicalize `calc(var(--spacing)*…)` expressions into `--spacing(…)` ([#19769](https://github.com/tailwindlabs/tailwindcss/pull/19769))
-- Fix crash in canonicalization step when handling utilities containing `@property` at-rules (e.g. `shadow-sm border`) ([#19727](https://github.com/tailwindlabs/tailwindcss/pull/19727))
-- Skip full reload for server only modules scanned by client CSS when using `@tailwindcss/vite` ([#19745](https://github.com/tailwindlabs/tailwindcss/pull/19745))
-- Add support for Vite 8 in `@tailwindcss/vite` ([#19790](https://github.com/tailwindlabs/tailwindcss/pull/19790))
-- Improve canonicalization for bare values exceeding default spacing scale suggestions (e.g. `w-1234 h-1234` → `size-1234`) ([#19809](https://github.com/tailwindlabs/tailwindcss/pull/19809))
-- Fix canonicalization resulting in empty list (e.g. `w-5 h-5 size-5` → `''` instead of `size-5`) ([#19812](https://github.com/tailwindlabs/tailwindcss/pull/19812))
-- Resolve tsconfig paths to allow for `@import '@/path/to/file';` when using `@tailwindcss/vite` ([#19803](https://github.com/tailwindlabs/tailwindcss/pull/19803))
-
-## [4.2.1] - 2026-02-23
-
-### Fixed
-
-- Allow trailing dash in functional utility names for backwards compatibility ([#19696](https://github.com/tailwindlabs/tailwindcss/pull/19696))
-- Properly detect classes containing `.` characters within curly braces in MDX files ([#19711](https://github.com/tailwindlabs/tailwindcss/pull/19711))
-
-## [4.2.0] - 2026-02-18
-
-### Added
-
-- Add mauve, olive, mist, and taupe color palettes to the default theme ([#19627](https://github.com/tailwindlabs/tailwindcss/pull/19627))
-- Add `@tailwindcss/webpack` package to run Tailwind CSS as a webpack plugin ([#19610](https://github.com/tailwindlabs/tailwindcss/pull/19610))
-- Add `pbs-*` and `pbe-*` utilities for `padding-block-start` and `padding-block-end` ([#19601](https://github.com/tailwindlabs/tailwindcss/pull/19601))
-- Add `mbs-*` and `mbe-*` utilities for `margin-block-start` and `margin-block-end` ([#19601](https://github.com/tailwindlabs/tailwindcss/pull/19601))
-- Add `scroll-pbs-*` and `scroll-pbe-*` utilities for `scroll-padding-block-start` and `scroll-padding-block-end` ([#19601](https://github.com/tailwindlabs/tailwindcss/pull/19601))
-- Add `scroll-mbs-*` and `scroll-mbe-*` utilities for `scroll-margin-block-start` and `scroll-margin-block-end` ([#19601](https://github.com/tailwindlabs/tailwindcss/pull/19601))
-- Add `border-bs-*` and `border-be-*` utilities for `border-block-start` and `border-block-end` ([#19601](https://github.com/tailwindlabs/tailwindcss/pull/19601))
-- Add `inline-*`, `min-inline-*`, `max-inline-*` utilities for `inline-size`, `min-inline-size`, and `max-inline-size` ([#19612](https://github.com/tailwindlabs/tailwindcss/pull/19612))
-- Add `block-*`, `min-block-*`, `max-block-*` utilities for `block-size`, `min-block-size`, and `max-block-size` ([#19612](https://github.com/tailwindlabs/tailwindcss/pull/19612))
-- Add `inset-s-*`, `inset-e-*`, `inset-bs-*`, `inset-be-*` utilities for `inset-inline-start`, `inset-inline-end`, `inset-block-start`, and `inset-block-end` ([#19613](https://github.com/tailwindlabs/tailwindcss/pull/19613))
-- Add `font-features-*` utility for `font-feature-settings` ([#19623](https://github.com/tailwindlabs/tailwindcss/pull/19623))
-
-### Fixed
-
-- Prevent double `@supports` wrapper for `color-mix` values ([#19450](https://github.com/tailwindlabs/tailwindcss/pull/19450))
-- Allow whitespace around `@source inline()` argument ([#19461](https://github.com/tailwindlabs/tailwindcss/pull/19461))
-- Emit comment when source maps are saved to files when using `@tailwindcss/cli` ([#19447](https://github.com/tailwindlabs/tailwindcss/pull/19447))
-- Detect utilities containing capital letters followed by numbers ([#19465](https://github.com/tailwindlabs/tailwindcss/pull/19465))
-- Fix class extraction for Rails' strict locals ([#19525](https://github.com/tailwindlabs/tailwindcss/pull/19525))
-- Align `@utility` name validation with Oxide scanner rules ([#19524](https://github.com/tailwindlabs/tailwindcss/pull/19524))
-- Fix infinite loop when using `@variant` inside `@custom-variant` ([#19633](https://github.com/tailwindlabs/tailwindcss/pull/19633))
-- Allow multiples of `.25` in `aspect-*` fractions (e.g. `aspect-8.5/11`) ([#19688](https://github.com/tailwindlabs/tailwindcss/pull/19688))
-- Ensure changes to external files listed via `@source` trigger a full page reload when using `@tailwindcss/vite` ([#19670](https://github.com/tailwindlabs/tailwindcss/pull/19670))
-- Improve performance of Oxide scanner in bigger projects by reducing file system walks ([#19632](https://github.com/tailwindlabs/tailwindcss/pull/19632))
-- Ensure import aliases in Astro v5 work without crashing when using `@tailwindcss/vite` ([#19677](https://github.com/tailwindlabs/tailwindcss/issues/19677))
-- Allow escape characters in `@utility` names to improve support with formatters such as Biome ([#19626](https://github.com/tailwindlabs/tailwindcss/pull/19626))
-- Fix incorrect canonicalization results when canonicalizing multiple times ([#19675](https://github.com/tailwindlabs/tailwindcss/pull/19675))
-- Add `.jj` to default ignored content directories ([#19687](https://github.com/tailwindlabs/tailwindcss/pull/19687))
-
-### Deprecated
-
-- Deprecate `start-*` and `end-*` utilities in favor of `inset-s-*` and `inset-e-*` utilities ([#19613](https://github.com/tailwindlabs/tailwindcss/pull/19613))
-
-## [4.1.18] - 2025-12-11
-
-### Fixed
-
-- Ensure validation of `source(…)` happens relative to the file it is in ([#19274](https://github.com/tailwindlabs/tailwindcss/pull/19274))
-- Include filename and line numbers in CSS parse errors ([#19282](https://github.com/tailwindlabs/tailwindcss/pull/19282))
-- Skip comments in Ruby files when checking for class names ([#19243](https://github.com/tailwindlabs/tailwindcss/pull/19243))
-- Skip over arbitrary property utilities with a top-level `!` in the value ([#19243](https://github.com/tailwindlabs/tailwindcss/pull/19243))
-- Support environment API in `@tailwindcss/vite` ([#18970](https://github.com/tailwindlabs/tailwindcss/pull/18970))
-- Preserve case of theme keys from JS configs and plugins ([#19337](https://github.com/tailwindlabs/tailwindcss/pull/19337))
-- Write source maps correctly on the CLI when using `--watch` ([#19373](https://github.com/tailwindlabs/tailwindcss/pull/19373))
-- Handle special defaults (like `ringColor.DEFAULT`) in JS configs ([#19348](https://github.com/tailwindlabs/tailwindcss/pull/19348))
-- Improve backwards compatibility for `content` theme key from JS configs ([#19381](https://github.com/tailwindlabs/tailwindcss/pull/19381))
-- Upgrade: Handle `future` and `experimental` config keys ([#19344](https://github.com/tailwindlabs/tailwindcss/pull/19344))
-- Try to canonicalize any arbitrary utility to a bare value ([#19379](https://github.com/tailwindlabs/tailwindcss/pull/19379))
-- Validate candidates similarly to Oxide ([#19397](https://github.com/tailwindlabs/tailwindcss/pull/19397))
-- Canonicalization: combine `text-*` and `leading-*` classes ([#19396](https://github.com/tailwindlabs/tailwindcss/pull/19396))
-- Correctly handle duplicate CLI arguments ([#19416](https://github.com/tailwindlabs/tailwindcss/pull/19416))
-- Don’t emit color-mix fallback rules inside `@keyframes` ([#19419](https://github.com/tailwindlabs/tailwindcss/pull/19419))
-- CLI: Don't hang when output is `/dev/stdout` ([#19421](https://github.com/tailwindlabs/tailwindcss/pull/19421))
-
-## [3.4.19] - 2025-12-10
-
-### Fixed
-
-- Don’t break `sibling-*()` functions when used inside `calc(…)` ([#19335](https://github.com/tailwindlabs/tailwindcss/pull/19335))
-
-## [4.1.17] - 2025-11-06
-
-### Fixed
-
-- Substitute `@variant` inside legacy JS APIs ([#19263](https://github.com/tailwindlabs/tailwindcss/pull/19263))
-- Prevent occasional crash on Windows when loaded into a worker thread ([#19242](https://github.com/tailwindlabs/tailwindcss/pull/19242))
-
-## [4.1.16] - 2025-10-23
-
-### Fixed
-
-- Discard candidates with an empty data type ([#19172](https://github.com/tailwindlabs/tailwindcss/pull/19172))
-- Fix canonicalization of arbitrary variants with attribute selectors ([#19176](https://github.com/tailwindlabs/tailwindcss/pull/19176))
-- Fix invalid colors due to nested `&` ([#19184](https://github.com/tailwindlabs/tailwindcss/pull/19184))
-- Improve canonicalization for `& > :pseudo` and `& :pseudo` arbitrary variants ([#19178](https://github.com/tailwindlabs/tailwindcss/pull/19178))
-
-## [4.1.15] - 2025-10-20
-
-### Fixed
-
-- Fix Safari devtools rendering issue due to `color-mix` fallback ([#19069](https://github.com/tailwindlabs/tailwindcss/pull/19069))
-- Suppress Lightning CSS warnings about `:deep`, `:slotted`, and `:global` ([#19094](https://github.com/tailwindlabs/tailwindcss/pull/19094))
-- Fix resolving theme keys when starting with the name of another theme key in JS configs and plugins ([#19097](https://github.com/tailwindlabs/tailwindcss/pull/19097))
-- Allow named groups in combination with `not-*`, `has-*`, and `in-*` ([#19100](https://github.com/tailwindlabs/tailwindcss/pull/19100))
-- Prevent important utilities from affecting other utilities ([#19110](https://github.com/tailwindlabs/tailwindcss/pull/19110))
-- Don’t index into strings with the `theme(…)` function ([#19111](https://github.com/tailwindlabs/tailwindcss/pull/19111))
-- Fix parsing issue when `\t` is used in at-rules ([#19130](https://github.com/tailwindlabs/tailwindcss/pull/19130))
-- Upgrade: Canonicalize utilities containing `0` values ([#19095](https://github.com/tailwindlabs/tailwindcss/pull/19095))
-- Upgrade: Migrate deprecated `break-words` to `wrap-break-word` ([#19157](https://github.com/tailwindlabs/tailwindcss/pull/19157))
-
-### Changed
-
-- Remove the `postinstall` script from oxide ([#19149])(https://github.com/tailwindlabs/tailwindcss/pull/19149)
-
-## [4.1.14] - 2025-10-01
-
-### Fixed
-
-- Handle `'` syntax in ClojureScript when extracting classes ([#18888](https://github.com/tailwindlabs/tailwindcss/pull/18888))
-- Handle `@variant` inside `@custom-variant` ([#18885](https://github.com/tailwindlabs/tailwindcss/pull/18885))
-- Merge suggestions when using `@utility` ([#18900](https://github.com/tailwindlabs/tailwindcss/pull/18900))
-- Ensure that file system watchers created when using the CLI are always cleaned up ([#18905](https://github.com/tailwindlabs/tailwindcss/pull/18905))
-- Do not generate `grid-column` utilities when configuring `grid-column-start` or `grid-column-end` ([#18907](https://github.com/tailwindlabs/tailwindcss/pull/18907))
-- Do not generate `grid-row` utilities when configuring `grid-row-start` or `grid-row-end` ([#18907](https://github.com/tailwindlabs/tailwindcss/pull/18907))
-- Prevent duplicate CSS when overwriting a static utility with a theme key ([#18056](https://github.com/tailwindlabs/tailwindcss/pull/18056))
-- Show Lightning CSS warnings (if any) when optimizing/minifying ([#18918](https://github.com/tailwindlabs/tailwindcss/pull/18918))
-- Use `default` export condition for `@tailwindcss/vite` ([#18948](https://github.com/tailwindlabs/tailwindcss/pull/18948))
-- Re-throw errors from PostCSS nodes ([#18373](https://github.com/tailwindlabs/tailwindcss/pull/18373))
-- Detect classes in markdown inline directives ([#18967](https://github.com/tailwindlabs/tailwindcss/pull/18967))
-- Ensure files with only `@theme` produce no output when built ([#18979](https://github.com/tailwindlabs/tailwindcss/pull/18979))
-- Support Maud templates when extracting classes ([#18988](https://github.com/tailwindlabs/tailwindcss/pull/18988))
-- Upgrade: Do not migrate `variant = 'outline'` during upgrades ([#18922](https://github.com/tailwindlabs/tailwindcss/pull/18922))
-- Upgrade: Show version mismatch (if any) when running upgrade tool ([#19028](https://github.com/tailwindlabs/tailwindcss/pull/19028))
-- Upgrade: Ensure first class inside `className` is migrated ([#19031](https://github.com/tailwindlabs/tailwindcss/pull/19031))
-- Upgrade: Migrate classes inside `*ClassName` and `*Class` attributes ([#19031](https://github.com/tailwindlabs/tailwindcss/pull/19031))
-
-## [3.4.18] - 2025-10-01
-
-### Fixed
-
-- Improve support for raw `supports-[…]` queries in arbitrary values ([#13605](https://github.com/tailwindlabs/tailwindcss/pull/13605))
-- Fix `require.cache` error when loaded through a TypeScript file in Node 22.18+ ([#18665](https://github.com/tailwindlabs/tailwindcss/pull/18665))
-- Support `import.meta.resolve(…)` in configs for new enough Node.js versions ([#18938](https://github.com/tailwindlabs/tailwindcss/pull/18938))
-- Allow using newer versions of `postcss-load-config` for better ESM and TypeScript PostCSS config support with the CLI ([#18938](https://github.com/tailwindlabs/tailwindcss/pull/18938))
-- Remove irrelevant utility rules when matching important classes ([#19030](https://github.com/tailwindlabs/tailwindcss/pull/19030))
-
-## [4.1.13] - 2025-09-03
-
-### Changed
-
-- Drop warning from browser build ([#18731](https://github.com/tailwindlabs/tailwindcss/issues/18731))
-- Drop exact duplicate declarations when emitting CSS ([#18809](https://github.com/tailwindlabs/tailwindcss/issues/18809))
-
-### Fixed
-
-- Don't transition `visibility` when using `transition` ([#18795](https://github.com/tailwindlabs/tailwindcss/pull/18795))
-- Discard matched variants with unknown named values ([#18799](https://github.com/tailwindlabs/tailwindcss/pull/18799))
-- Discard matched variants with non-string values ([#18799](https://github.com/tailwindlabs/tailwindcss/pull/18799))
-- Show suggestions for known `matchVariant` values ([#18798](https://github.com/tailwindlabs/tailwindcss/pull/18798))
-- Replace deprecated `clip` with `clip-path` in `sr-only` ([#18769](https://github.com/tailwindlabs/tailwindcss/pull/18769))
-- Hide internal fields from completions in `matchUtilities` ([#18820](https://github.com/tailwindlabs/tailwindcss/pull/18820))
-- Ignore `.vercel` folders by default (can be overridden by `@source …` rules) ([#18855](https://github.com/tailwindlabs/tailwindcss/pull/18855))
-- Consider variants starting with `@-` to be invalid (e.g. `@-2xl:flex`) ([#18869](https://github.com/tailwindlabs/tailwindcss/pull/18869))
-- Do not allow custom variants to start or end with a `-` or `_` ([#18867](https://github.com/tailwindlabs/tailwindcss/pull/18867), [#18872](https://github.com/tailwindlabs/tailwindcss/pull/18872))
-- Upgrade: Migrate `aria` theme keys to `@custom-variant` ([#18815](https://github.com/tailwindlabs/tailwindcss/pull/18815))
-- Upgrade: Migrate `data` theme keys to `@custom-variant` ([#18816](https://github.com/tailwindlabs/tailwindcss/pull/18816))
-- Upgrade: Migrate `supports` theme keys to `@custom-variant` ([#18817](https://github.com/tailwindlabs/tailwindcss/pull/18817))
-
-## [4.1.12] - 2025-08-13
-
-### Fixed
-
-- Don't consider the global important state in `@apply` ([#18404](https://github.com/tailwindlabs/tailwindcss/pull/18404))
-- Add missing suggestions for `flex-` utilities ([#18642](https://github.com/tailwindlabs/tailwindcss/pull/18642))
-- Fix trailing `)` from interfering with extraction in Clojure keywords ([#18345](https://github.com/tailwindlabs/tailwindcss/pull/18345))
-- Detect classes inside Elixir charlist, word list, and string sigils ([#18432](https://github.com/tailwindlabs/tailwindcss/pull/18432))
-- Track source locations through `@plugin` and `@config` ([#18345](https://github.com/tailwindlabs/tailwindcss/pull/18345))
-- Allow boolean values of `process.env.DEBUG` in `@tailwindcss/node` ([#18485](https://github.com/tailwindlabs/tailwindcss/pull/18485))
-- Ignore consecutive semicolons in the CSS parser ([#18532](https://github.com/tailwindlabs/tailwindcss/pull/18532))
-- Center the dropdown icon added to an input with a paired datalist by default ([#18511](https://github.com/tailwindlabs/tailwindcss/pull/18511))
-- Extract candidates in Slang templates ([#18565](https://github.com/tailwindlabs/tailwindcss/pull/18565))
-- Improve error messages when encountering invalid functional utility names ([#18568](https://github.com/tailwindlabs/tailwindcss/pull/18568))
-- Discard CSS AST objects with `false` or `undefined` properties ([#18571](https://github.com/tailwindlabs/tailwindcss/pull/18571))
-- Allow users to disable URL rebasing in `@tailwindcss/postcss` via `transformAssetUrls: false` ([#18321](https://github.com/tailwindlabs/tailwindcss/pull/18321))
-- Fix false-positive migrations in `addEventListener` and JavaScript variable names ([#18718](https://github.com/tailwindlabs/tailwindcss/pull/18718))
-- Fix Standalone CLI showing default Bun help when run via symlink on Windows ([#18723](https://github.com/tailwindlabs/tailwindcss/pull/18723))
-- Read from `--border-color-*` theme keys in `divide-*` utilities for backwards compatibility ([#18704](https://github.com/tailwindlabs/tailwindcss/pull/18704/))
-- Don't scan `.hdr` and `.exr` files for classes by default ([#18734](https://github.com/tailwindlabs/tailwindcss/pull/18734))
-
-## [4.1.11] - 2025-06-26
-
-### Fixed
-
-- Add heuristic to skip candidate migrations inside `emit(…)` ([#18330](https://github.com/tailwindlabs/tailwindcss/pull/18330))
-- Extract candidates with variants in Clojure/ClojureScript keywords ([#18338](https://github.com/tailwindlabs/tailwindcss/pull/18338))
-- Document `--watch=always` in the CLI's usage ([#18337](https://github.com/tailwindlabs/tailwindcss/pull/18337))
-- Add support for Vite 7 to `@tailwindcss/vite` ([#18384](https://github.com/tailwindlabs/tailwindcss/pull/18384))
-
-## [4.1.10] - 2025-06-11
-
-### Fixed
-
-- Fix incorrectly generated CSS when using percentages in arbitrary values with calc (e.g. `w-[calc(100%-var(--offset))]`) ([#18289](https://github.com/tailwindlabs/tailwindcss/pull/18289))
-
-## [4.1.9] - 2025-06-11
-
-### Fixed
-
-- Correctly parse custom properties with strings containing semicolons ([#18251](https://github.com/tailwindlabs/tailwindcss/pull/18251))
-- Upgrade: Migrate arbitrary modifiers without percentage signs to bare values (e.g. `/[0.16]` → `/16`) ([#18184](https://github.com/tailwindlabs/tailwindcss/pull/18184))
-- Upgrade: Migrate CSS variable shorthands where fallback value contains function call ([#18184](https://github.com/tailwindlabs/tailwindcss/pull/18184))
-- Upgrade: Migrate negative arbitrary values to negative bare values (e.g. `mb-[-32rem]` → `-mb-128`) ([#18212](https://github.com/tailwindlabs/tailwindcss/pull/18212))
-- Upgrade: Do not migrate `blur` in `wire:model.blur` ([#18216](https://github.com/tailwindlabs/tailwindcss/pull/18216))
-- Don't add spaces around CSS dashed idents when formatting math expressions ([#18220](https://github.com/tailwindlabs/tailwindcss/pull/18220))
-
-## [4.1.8] - 2025-05-27
-
-### Added
-
-- Improve error messages when `@apply` fails ([#18059](https://github.com/tailwindlabs/tailwindcss/pull/18059))
-
-### Fixed
-
-- Upgrade: Do not migrate declarations that look like candidates in `