diff --git a/CHANGELOG.md b/CHANGELOG.md
index a6e987d0e19b..4371274c84cd 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -11,6 +11,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
 
 - Don't remove keyframe stops when using important utilities ([#12639](https://github.com/tailwindlabs/tailwindcss/pull/12639))
 - Don't add spaces to gradients and grid track names when followed by `calc()` ([#12704](https://github.com/tailwindlabs/tailwindcss/pull/12704))
+- Improve glob handling for folders with `(`, `)`, `[` or `]` in the file path ([#12715](https://github.com/tailwindlabs/tailwindcss/pull/12715))
 
 ### Added
 
diff --git a/package-lock.json b/package-lock.json
index fe2cafef5108..b5bd962f1c0e 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -35,7 +35,7 @@
         "postcss-js": "^4.0.1",
         "postcss-load-config": "^4.0.2",
         "postcss-nested": "^6.0.1",
-        "postcss-selector-parser": "^6.0.12",
+        "postcss-selector-parser": "^6.0.15",
         "postcss-value-parser": "^4.2.0",
         "resolve": "^1.22.8",
         "sucrase": "^3.35.0"
@@ -12996,9 +12996,9 @@
       }
     },
     "node_modules/postcss-selector-parser": {
-      "version": "6.0.12",
-      "resolved": "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-6.0.12.tgz",
-      "integrity": "sha512-NdxGCAZdRrwVI1sy59+Wzrh+pMMHxapGnpfenDVlMEXoOcvt4pGE0JLK9YY2F5dLxcFYA/YbVQKhcGU+FtSYQg==",
+      "version": "6.0.15",
+      "resolved": "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-6.0.15.tgz",
+      "integrity": "sha512-rEYkQOMUCEMhsKbK66tbEU9QVIxbhN18YiniAwA7XQYTVBqrBy+P2p5JcdqsHgKM2zWylp8d7J6eszocfds5Sw==",
       "dependencies": {
         "cssesc": "^3.0.0",
         "util-deprecate": "^1.0.2"
@@ -26116,9 +26116,9 @@
       }
     },
     "postcss-selector-parser": {
-      "version": "6.0.12",
-      "resolved": "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-6.0.12.tgz",
-      "integrity": "sha512-NdxGCAZdRrwVI1sy59+Wzrh+pMMHxapGnpfenDVlMEXoOcvt4pGE0JLK9YY2F5dLxcFYA/YbVQKhcGU+FtSYQg==",
+      "version": "6.0.15",
+      "resolved": "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-6.0.15.tgz",
+      "integrity": "sha512-rEYkQOMUCEMhsKbK66tbEU9QVIxbhN18YiniAwA7XQYTVBqrBy+P2p5JcdqsHgKM2zWylp8d7J6eszocfds5Sw==",
       "requires": {
         "cssesc": "^3.0.0",
         "util-deprecate": "^1.0.2"
@@ -27819,7 +27819,7 @@
         "postcss-js": "^4.0.1",
         "postcss-load-config": "^4.0.2",
         "postcss-nested": "^6.0.1",
-        "postcss-selector-parser": "^6.0.12",
+        "postcss-selector-parser": "^6.0.15",
         "postcss-value-parser": "^4.2.0",
         "prettier": "^2.8.8",
         "resolve": "^1.22.8",
@@ -36993,9 +36993,9 @@
           }
         },
         "postcss-selector-parser": {
-          "version": "6.0.12",
-          "resolved": "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-6.0.12.tgz",
-          "integrity": "sha512-NdxGCAZdRrwVI1sy59+Wzrh+pMMHxapGnpfenDVlMEXoOcvt4pGE0JLK9YY2F5dLxcFYA/YbVQKhcGU+FtSYQg==",
+          "version": "6.0.15",
+          "resolved": "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-6.0.15.tgz",
+          "integrity": "sha512-rEYkQOMUCEMhsKbK66tbEU9QVIxbhN18YiniAwA7XQYTVBqrBy+P2p5JcdqsHgKM2zWylp8d7J6eszocfds5Sw==",
           "requires": {
             "cssesc": "^3.0.0",
             "util-deprecate": "^1.0.2"
diff --git a/src/lib/content.js b/src/lib/content.js
index 9979d251d12d..737dd09e4416 100644
--- a/src/lib/content.js
+++ b/src/lib/content.js
@@ -4,11 +4,48 @@ import fs from 'fs'
 import path from 'path'
 import isGlob from 'is-glob'
 import fastGlob from 'fast-glob'
-import normalizePath from 'normalize-path'
 import { parseGlob } from '../util/parseGlob'
 import { env } from './sharedState'
 import { resolveContentPaths } from '@tailwindcss/oxide'
 
+/*!
+ * Modified version of normalize-path, original license below
+ *
+ * normalize-path <https://github.com/jonschlinkert/normalize-path>
+ *
+ * Copyright (c) 2014-2018, Jon Schlinkert.
+ * Released under the MIT License.
+ */
+
+function normalizePath(path) {
+  if (typeof path !== 'string') {
+    throw new TypeError('expected path to be a string')
+  }
+
+  if (path === '\\' || path === '/') return '/'
+
+  var len = path.length
+  if (len <= 1) return path
+
+  // ensure that win32 namespaces has two leading slashes, so that the path is
+  // handled properly by the win32 version of path.parse() after being normalized
+  // https://msdn.microsoft.com/library/windows/desktop/aa365247(v=vs.85).aspx#namespaces
+  var prefix = ''
+  if (len > 4 && path[3] === '\\') {
+    var ch = path[2]
+    if ((ch === '?' || ch === '.') && path.slice(0, 2) === '\\\\') {
+      path = path.slice(2)
+      prefix = '//'
+    }
+  }
+
+  // Modified part: instead of purely splitting on `\\` and `/`, we split on
+  // `/` and `\\` that is _not_ followed by any of the following characters: ()[]
+  // This is to ensure that we keep the escaping of brackets and parentheses
+  let segs = path.split(/[/\\]+(?![\(\)\[\]])/)
+  return prefix + segs.join('/')
+}
+
 /** @typedef {import('../../types/config.js').RawFile} RawFile */
 /** @typedef {import('../../types/config.js').FilePath} FilePath */
 
@@ -105,6 +142,10 @@ export function parseCandidateFiles(context, tailwindConfig) {
  * @returns {ContentPath}
  */
 function parseFilePath(filePath, ignore) {
+  // Escape special characters in the file path such as: ()[]
+  // But only if the special character isn't already escaped
+  filePath = filePath.replace(/(?<!\\)([\[\]\(\)])/g, '\\$1')
+
   let contentPath = {
     original: filePath,
     base: filePath,