From 9bce51f651aad297ef9eb6df832bfdaf1de05d84 Mon Sep 17 00:00:00 2001
From: WXL <wl_5969728@163.com>
Date: 星期三, 22 四月 2026 14:27:54 +0800
Subject: [PATCH] 青岛推送

---
 node_modules/webpack/lib/css/CssParser.js | 1605 +++++++++++++++++++++++++++++++++++++++++-----------------
 1 files changed, 1,131 insertions(+), 474 deletions(-)

diff --git a/node_modules/webpack/lib/css/CssParser.js b/node_modules/webpack/lib/css/CssParser.js
index 4ae35d8..488095e 100644
--- a/node_modules/webpack/lib/css/CssParser.js
+++ b/node_modules/webpack/lib/css/CssParser.js
@@ -7,7 +7,6 @@
 
 const vm = require("vm");
 const CommentCompilationWarning = require("../CommentCompilationWarning");
-const CssModule = require("../CssModule");
 const ModuleDependencyWarning = require("../ModuleDependencyWarning");
 const { CSS_MODULE_TYPE_AUTO } = require("../ModuleTypeConstants");
 const Parser = require("../Parser");
@@ -15,11 +14,7 @@
 const WebpackError = require("../WebpackError");
 const ConstDependency = require("../dependencies/ConstDependency");
 const CssIcssExportDependency = require("../dependencies/CssIcssExportDependency");
-const CssIcssFromIdentifierDependency = require("../dependencies/CssIcssFromIdentifierDependency");
-const CssIcssGlobalIdentifierDependency = require("../dependencies/CssIcssGlobalIdentifierDependency");
 const CssIcssImportDependency = require("../dependencies/CssIcssImportDependency");
-const CssIcssLocalIdentifierDependency = require("../dependencies/CssIcssLocalIdentifierDependency");
-const CssIcssSelfLocalIdentifierDependency = require("../dependencies/CssIcssSelfLocalIdentifierDependency");
 const CssIcssSymbolDependency = require("../dependencies/CssIcssSymbolDependency");
 const CssImportDependency = require("../dependencies/CssImportDependency");
 const CssUrlDependency = require("../dependencies/CssUrlDependency");
@@ -37,7 +32,8 @@
 /** @typedef {import("../Parser").ParserState} ParserState */
 /** @typedef {import("../Parser").PreparsedAst} PreparsedAst */
 /** @typedef {import("./walkCssTokens").CssTokenCallbacks} CssTokenCallbacks */
-/** @typedef {import("../../declarations/WebpackOptions").CssParserExportType} CssParserExportType */
+/** @typedef {import("../../declarations/WebpackOptions").CssModuleParserOptions} CssModuleParserOptions */
+/** @typedef {import("../CssModule")} CssModule */
 
 /** @typedef {[number, number]} Range */
 /** @typedef {{ line: number, column: number }} Position */
@@ -46,28 +42,53 @@
 const CC_COLON = ":".charCodeAt(0);
 const CC_SEMICOLON = ";".charCodeAt(0);
 const CC_COMMA = ",".charCodeAt(0);
-const CC_SLASH = "/".charCodeAt(0);
 const CC_LEFT_PARENTHESIS = "(".charCodeAt(0);
 const CC_RIGHT_PARENTHESIS = ")".charCodeAt(0);
 const CC_LOWER_F = "f".charCodeAt(0);
 const CC_UPPER_F = "F".charCodeAt(0);
 const CC_RIGHT_CURLY = "}".charCodeAt(0);
+const CC_HYPHEN_MINUS = "-".charCodeAt(0);
+const CC_TILDE = "~".charCodeAt(0);
+const CC_EQUAL = "=".charCodeAt(0);
+const CC_FULL_STOP = ".".charCodeAt(0);
+const CC_EXCLAMATION = "!".charCodeAt(0);
 
 // https://www.w3.org/TR/css-syntax-3/#newline
 // We don't have `preprocessing` stage, so we need specify all of them
 const STRING_MULTILINE = /\\[\n\r\f]/g;
 // https://www.w3.org/TR/css-syntax-3/#whitespace
 const TRIM_WHITE_SPACES = /(^[ \t\n\r\f]*|[ \t\n\r\f]*$)/g;
-const UNESCAPE = /\\([0-9a-fA-F]{1,6}[ \t\n\r\f]?|[\s\S])/g;
-const IMAGE_SET_FUNCTION = /^(-\w+-)?image-set$/i;
-const OPTIONALLY_VENDOR_PREFIXED_KEYFRAMES_AT_RULE = /^@(-\w+-)?keyframes$/;
-const OPTIONALLY_VENDOR_PREFIXED_ANIMATION_PROPERTY =
-	/^(-\w+-)?animation(-name)?$/i;
-const COMPOSES_PROPERTY = /^(composes|compose-with)$/i;
-const IS_MODULES = /\.module(s)?\.[^.]+$/i;
-const CSS_COMMENT = /\/\*((?!\*\/).*?)\*\//g;
+const UNESCAPE = /\\([0-9a-f]{1,6}[ \t\n\r\f]?|[\s\S])/gi;
+const IMAGE_SET_FUNCTION = /^(?:-\w+-)?image-set$/i;
+const OPTIONALLY_VENDOR_PREFIXED_KEYFRAMES_AT_RULE = /^@(?:-\w+-)?keyframes$/;
+const COMPOSES_PROPERTY = /^(?:composes|compose-with)$/i;
+const IS_MODULES = /\.modules?\.[^.]+$/i;
+const CSS_COMMENT = /\/\*((?!\*\/)[\s\S]*?)\*\//g;
 
 /**
+ * Returns matches.
+ * @param {RegExp} regexp a regexp
+ * @param {string} str a string
+ * @returns {RegExpExecArray[]} matches
+ */
+const matchAll = (regexp, str) => {
+	/** @type {RegExpExecArray[]} */
+	const result = [];
+
+	/** @type {null | RegExpExecArray} */
+	let match;
+
+	// Use a while loop with exec() to find all matches
+	while ((match = regexp.exec(str)) !== null) {
+		result.push(match);
+	}
+	// Return an array to be easily iterable (note: a true spec-compliant polyfill
+	// returns an iterator object, but an array spread often suffices for basic use)
+	return result;
+};
+
+/**
+ * Returns normalized url.
  * @param {string} str url string
  * @param {boolean} isString is url wrapped in quotes
  * @returns {string} normalized url
@@ -107,12 +128,12 @@
 	return str;
 };
 
-// eslint-disable-next-line no-useless-escape
-const regexSingleEscape = /[ -,.\/:-@[\]\^`{-~]/;
+const regexSingleEscape = /[ -,./:-@[\]^`{-~]/;
 const regexExcessiveSpaces =
 	/(^|\\+)?(\\[A-F0-9]{1,6})\u0020(?![a-fA-F0-9\u0020])/g;
 
 /**
+ * Returns escaped identifier.
  * @param {string} str string
  * @returns {string} escaped identifier
  */
@@ -123,10 +144,10 @@
 	while (counter < str.length) {
 		const character = str.charAt(counter++);
 
+		/** @type {string} */
 		let value;
 
-		// eslint-disable-next-line no-control-regex
-		if (/[\t\n\f\r\u000B]/.test(character)) {
+		if (/[\t\n\f\r\v]/.test(character)) {
 			const codePoint = character.charCodeAt(0);
 
 			value = `\\${codePoint.toString(16).toUpperCase()} `;
@@ -166,6 +187,7 @@
 const CONTAINS_ESCAPE = /\\/;
 
 /**
+ * Returns hex.
  * @param {string} str string
  * @returns {[string, number] | undefined} hex
  */
@@ -203,6 +225,7 @@
 };
 
 /**
+ * Unescape identifier.
  * @param {string} str string
  * @returns {string} unescaped string
  */
@@ -238,32 +261,90 @@
 	return ret;
 };
 
+/**
+ * A custom property is any property whose name starts with two dashes (U+002D HYPHEN-MINUS), like --foo.
+ * The <custom-property-name> production corresponds to this:
+ * it鈥檚 defined as any <dashed-ident> (a valid identifier that starts with two dashes),
+ * except -- itself, which is reserved for future use by CSS.
+ * @param {string} identifier identifier
+ * @returns {boolean} true when identifier is dashed, otherwise false
+ */
+const isDashedIdentifier = (identifier) =>
+	identifier.startsWith("--") && identifier.length >= 3;
+
 /** @type {Record<string, number>} */
-const ANIMATION_KEYWORDS = {
-	// animation-direction
-	normal: 1,
-	reverse: 1,
-	alternate: 1,
-	"alternate-reverse": 1,
-	// animation-fill-mode
-	forwards: 1,
-	backwards: 1,
-	both: 1,
-	// animation-iteration-count
-	infinite: 1,
-	// animation-play-state
-	paused: 1,
-	running: 1,
-	// animation-timing-function
-	ease: 1,
-	"ease-in": 1,
-	"ease-out": 1,
-	"ease-in-out": 1,
-	linear: 1,
-	"step-end": 1,
-	"step-start": 1,
-	// Special
-	none: Infinity, // No matter how many times you write none, it will never be an animation name
+const PREDEFINED_COUNTER_STYLES = {
+	decimal: 1,
+	"decimal-leading-zero": 1,
+	"arabic-indic": 1,
+	armenian: 1,
+	"upper-armenian": 1,
+	"lower-armenian": 1,
+	bengali: 1,
+	cambodian: 1,
+	khmer: 1,
+	"cjk-decimal": 1,
+	devanagari: 1,
+	georgian: 1,
+	gujarati: 1,
+	/* cspell:disable-next-line */
+	gurmukhi: 1,
+	hebrew: 1,
+	kannada: 1,
+	lao: 1,
+	malayalam: 1,
+	mongolian: 1,
+	myanmar: 1,
+	oriya: 1,
+	persian: 1,
+	"lower-roman": 1,
+	"upper-roman": 1,
+	tamil: 1,
+	telugu: 1,
+	thai: 1,
+	tibetan: 1,
+
+	"lower-alpha": 1,
+	"lower-latin": 1,
+	"upper-alpha": 1,
+	"upper-latin": 1,
+	"lower-greek": 1,
+	hiragana: 1,
+	/* cspell:disable-next-line */
+	"hiragana-iroha": 1,
+	katakana: 1,
+	/* cspell:disable-next-line */
+	"katakana-iroha": 1,
+
+	disc: 1,
+	circle: 1,
+	square: 1,
+	"disclosure-open": 1,
+	"disclosure-closed": 1,
+
+	"cjk-earthly-branch": 1,
+	"cjk-heavenly-stem": 1,
+
+	"japanese-informal": 1,
+	"japanese-formal": 1,
+
+	"korean-hangul-formal": 1,
+	/* cspell:disable-next-line */
+	"korean-hanja-informal": 1,
+	/* cspell:disable-next-line */
+	"korean-hanja-formal": 1,
+
+	"simp-chinese-informal": 1,
+	"simp-chinese-formal": 1,
+	"trad-chinese-informal": 1,
+	"trad-chinese-formal": 1,
+	"cjk-ideographic": 1,
+
+	"ethiopic-numeric": 1
+};
+
+/** @type {Record<string, number>} */
+const GLOBAL_VALUES = {
 	// Global values
 	initial: Infinity,
 	inherit: Infinity,
@@ -272,8 +353,187 @@
 	"revert-layer": Infinity
 };
 
+/** @type {Record<string, number>} */
+const GRID_AREA_OR_COLUMN_OR_ROW = {
+	auto: Infinity,
+	span: Infinity,
+	...GLOBAL_VALUES
+};
+
+/** @type {Record<string, number>} */
+const GRID_AUTO_COLUMNS_OR_ROW = {
+	"min-content": Infinity,
+	"max-content": Infinity,
+	auto: Infinity,
+	...GLOBAL_VALUES
+};
+
+/** @type {Record<string, number>} */
+const GRID_AUTO_FLOW = {
+	row: 1,
+	column: 1,
+	dense: 1,
+	...GLOBAL_VALUES
+};
+
+/** @type {Record<string, number>} */
+const GRID_TEMPLATE_AREAS = {
+	// Special
+	none: 1,
+	...GLOBAL_VALUES
+};
+
+/** @type {Record<string, number>} */
+const GRID_TEMPLATE_COLUMNS_OR_ROWS = {
+	none: 1,
+	subgrid: 1,
+	masonry: 1,
+	"max-content": Infinity,
+	"min-content": Infinity,
+	auto: Infinity,
+	...GLOBAL_VALUES
+};
+
+/** @type {Record<string, number>} */
+const GRID_TEMPLATE = {
+	...GRID_TEMPLATE_AREAS,
+	...GRID_TEMPLATE_COLUMNS_OR_ROWS
+};
+
+/** @type {Record<string, number>} */
+const GRID = {
+	"auto-flow": 1,
+	dense: 1,
+	...GRID_AUTO_COLUMNS_OR_ROW,
+	...GRID_AUTO_FLOW,
+	...GRID_TEMPLATE_AREAS,
+	...GRID_TEMPLATE_COLUMNS_OR_ROWS
+};
+
+/**
+ * Gets known properties.
+ * @param {{ animation?: boolean, container?: boolean, customIdents?: boolean, grid?: boolean }=} options options
+ * @returns {Map<string, Record<string, number>>} list of known properties
+ */
+const getKnownProperties = (options = {}) => {
+	/** @type {Map<string, Record<string, number>>} */
+	const knownProperties = new Map();
+
+	if (options.animation) {
+		knownProperties.set("animation", {
+			// animation-direction
+			normal: 1,
+			reverse: 1,
+			alternate: 1,
+			"alternate-reverse": 1,
+			// animation-fill-mode
+			forwards: 1,
+			backwards: 1,
+			both: 1,
+			// animation-iteration-count
+			infinite: 1,
+			// animation-play-state
+			paused: 1,
+			running: 1,
+			// animation-timing-function
+			ease: 1,
+			"ease-in": 1,
+			"ease-out": 1,
+			"ease-in-out": 1,
+			linear: 1,
+			"step-end": 1,
+			"step-start": 1,
+			// Special
+			none: Infinity, // No matter how many times you write none, it will never be an animation name
+			...GLOBAL_VALUES
+		});
+		knownProperties.set("animation-name", {
+			// Special
+			none: Infinity, // No matter how many times you write none, it will never be an animation name
+			...GLOBAL_VALUES
+		});
+	}
+
+	if (options.container) {
+		knownProperties.set("container", {
+			// container-type
+			normal: 1,
+			size: 1,
+			"inline-size": 1,
+			"scroll-state": 1,
+			// Special
+			none: Infinity,
+			...GLOBAL_VALUES
+		});
+		knownProperties.set("container-name", {
+			// Special
+			none: Infinity,
+			...GLOBAL_VALUES
+		});
+	}
+
+	if (options.customIdents) {
+		knownProperties.set("list-style", {
+			// list-style-position
+			inside: 1,
+			outside: 1,
+			// list-style-type
+			...PREDEFINED_COUNTER_STYLES,
+			// Special
+			none: Infinity,
+			...GLOBAL_VALUES
+		});
+		knownProperties.set("list-style-type", {
+			// list-style-type
+			...PREDEFINED_COUNTER_STYLES,
+			// Special
+			none: Infinity,
+			...GLOBAL_VALUES
+		});
+		knownProperties.set("system", {
+			cyclic: 1,
+			numeric: 1,
+			alphabetic: 1,
+			symbolic: 1,
+			additive: 1,
+			fixed: 1,
+			extends: 1,
+			...PREDEFINED_COUNTER_STYLES
+		});
+		knownProperties.set("fallback", {
+			...PREDEFINED_COUNTER_STYLES
+		});
+		knownProperties.set("speak-as", {
+			auto: 1,
+			bullets: 1,
+			numbers: 1,
+			words: 1,
+			"spell-out": 1,
+			...PREDEFINED_COUNTER_STYLES
+		});
+	}
+
+	if (options.grid) {
+		knownProperties.set("grid", GRID);
+		knownProperties.set("grid-area", GRID_AREA_OR_COLUMN_OR_ROW);
+		knownProperties.set("grid-column", GRID_AREA_OR_COLUMN_OR_ROW);
+		knownProperties.set("grid-column-end", GRID_AREA_OR_COLUMN_OR_ROW);
+		knownProperties.set("grid-column-start", GRID_AREA_OR_COLUMN_OR_ROW);
+		knownProperties.set("grid-row", GRID_AREA_OR_COLUMN_OR_ROW);
+		knownProperties.set("grid-row-end", GRID_AREA_OR_COLUMN_OR_ROW);
+		knownProperties.set("grid-row-start", GRID_AREA_OR_COLUMN_OR_ROW);
+		knownProperties.set("grid-template", GRID_TEMPLATE);
+		knownProperties.set("grid-template-areas", GRID_TEMPLATE_AREAS);
+		knownProperties.set("grid-template-columns", GRID_TEMPLATE_COLUMNS_OR_ROWS);
+		knownProperties.set("grid-template-rows", GRID_TEMPLATE_COLUMNS_OR_ROWS);
+	}
+
+	return knownProperties;
+};
+
 class LocConverter {
 	/**
+	 * Creates an instance of LocConverter.
 	 * @param {string} input input
 	 */
 	constructor(input) {
@@ -284,6 +544,7 @@
 	}
 
 	/**
+	 * Returns location converter.
 	 * @param {number} pos position
 	 * @returns {LocConverter} location converter
 	 */
@@ -323,42 +584,48 @@
 const CSS_MODE_TOP_LEVEL = 0;
 const CSS_MODE_IN_BLOCK = 1;
 
+const LOCAL_MODE = 0;
+const GLOBAL_MODE = 1;
+
 const eatUntilSemi = walkCssTokens.eatUntil(";");
 const eatUntilLeftCurly = walkCssTokens.eatUntil("{");
-const eatSemi = walkCssTokens.eatUntil(";");
 
 /**
- * @typedef {object} CssParserOptions
- * @property {boolean=} importOption need handle `@import`
- * @property {boolean=} url need handle URLs
+ * Defines the css parser own options type used by this module.
+ * @typedef {object} CssParserOwnOptions
  * @property {("pure" | "global" | "local" | "auto")=} defaultMode default mode
- * @property {boolean=} namedExports is named exports
- * @property {CssParserExportType=} exportType export type
  */
+
+/** @typedef {CssModuleParserOptions & CssParserOwnOptions} CssParserOptions */
 
 class CssParser extends Parser {
 	/**
+	 * Creates an instance of CssParser.
 	 * @param {CssParserOptions=} options options
 	 */
-	constructor({
-		defaultMode = "pure",
-		importOption = true,
-		url = true,
-		namedExports = true,
-		exportType
-	} = {}) {
+	constructor(options = {}) {
 		super();
-		this.defaultMode = defaultMode;
-		this.import = importOption;
-		this.url = url;
-		this.namedExports = namedExports;
-		this.exportType = exportType;
+		this.defaultMode =
+			typeof options.defaultMode !== "undefined" ? options.defaultMode : "pure";
+		this.options = {
+			url: true,
+			import: true,
+			namedExports: true,
+			animation: true,
+			container: true,
+			customIdents: true,
+			dashedIdents: true,
+			function: true,
+			grid: true,
+			...options
+		};
 		/** @type {Comment[] | undefined} */
 		this.comments = undefined;
 		this.magicCommentContext = createMagicCommentContext();
 	}
 
 	/**
+	 * Processes the provided state.
 	 * @param {ParserState} state parser state
 	 * @param {string} message warning message
 	 * @param {LocConverter} locConverter location converter
@@ -378,6 +645,7 @@
 	}
 
 	/**
+	 * Parses the provided source and updates the parser state.
 	 * @param {string | Buffer | PreparsedAst} source the source to parse
 	 * @param {ParserState} state the parser state
 	 * @returns {ParserState} the parser state
@@ -407,6 +675,12 @@
 		}
 
 		const isModules = mode === "global" || mode === "local";
+		const knownProperties = getKnownProperties({
+			animation: this.options.animation,
+			container: this.options.container,
+			customIdents: this.options.customIdents,
+			grid: this.options.grid
+		});
 
 		/** @type {BuildMeta} */
 		(module.buildMeta).isCSSModule = isModules;
@@ -417,7 +691,7 @@
 		let scope = CSS_MODE_TOP_LEVEL;
 		/** @type {boolean} */
 		let allowImportAtRule = true;
-		/** @type {[string, number, number][]} */
+		/** @type {[string, number, number, boolean?][]} */
 		const balanced = [];
 		let lastTokenEndForComments = 0;
 
@@ -425,78 +699,59 @@
 		let isNextRulePrelude = isModules;
 		/** @type {number} */
 		let blockNestingLevel = 0;
-		/** @type {"local" | "global" | undefined} */
+		/** @type {0 | 1 | undefined} */
 		let modeData;
-		/** @type {Set<string>} */
-		const declaredCssVariables = new Set();
+		/** @type {number} */
+		let counter = 0;
 
 		/** @type {string[]} */
 		let lastLocalIdentifiers = [];
 
-		/** @typedef {{ value: string, isReference?: boolean }} IcssDefinition */
+		/** @typedef {{ value?: string, importName?: string, localName?: string }} IcssDefinition */
 		/** @type {Map<string, IcssDefinition>} */
 		const icssDefinitions = new Map();
 
 		/**
+		 * Checks whether this css parser is next nested syntax.
 		 * @param {string} input input
 		 * @param {number} pos position
 		 * @returns {boolean} true, when next is nested syntax
 		 */
 		const isNextNestedSyntax = (input, pos) => {
-			pos = walkCssTokens.eatWhitespaceAndComments(input, pos);
+			pos = walkCssTokens.eatWhitespaceAndComments(input, pos)[0];
 
-			if (input[pos] === "}") {
+			if (
+				input.charCodeAt(pos) === CC_RIGHT_CURLY ||
+				(input.charCodeAt(pos) === CC_HYPHEN_MINUS &&
+					input.charCodeAt(pos + 1) === CC_HYPHEN_MINUS)
+			) {
 				return false;
 			}
 
-			// According spec only identifier can be used as a property name
-			const isIdentifier = walkCssTokens.isIdentStartCodePoint(
-				input.charCodeAt(pos)
-			);
+			const identifier = walkCssTokens.eatIdentSequence(input, pos);
 
-			return !isIdentifier;
+			if (!identifier) {
+				return true;
+			}
+
+			const leftCurly = eatUntilLeftCurly(input, pos);
+			const content = input.slice(identifier[0], leftCurly);
+
+			if (content.includes(";") || content.includes("}")) {
+				return false;
+			}
+
+			return true;
 		};
 		/**
+		 * Checks whether this css parser is local mode.
 		 * @returns {boolean} true, when in local scope
 		 */
 		const isLocalMode = () =>
-			modeData === "local" || (mode === "local" && modeData === undefined);
+			modeData === LOCAL_MODE || (mode === "local" && modeData === undefined);
 
 		/**
-		 * @param {string} input input
-		 * @param {number} pos start position
-		 * @param {(input: string, pos: number) => number} eater eater
-		 * @returns {[number,string]} new position and text
-		 */
-		const eatText = (input, pos, eater) => {
-			let text = "";
-			for (;;) {
-				if (input.charCodeAt(pos) === CC_SLASH) {
-					const newPos = walkCssTokens.eatComments(input, pos);
-					if (pos !== newPos) {
-						pos = newPos;
-						if (pos === input.length) break;
-					} else {
-						text += "/";
-						pos++;
-						if (pos === input.length) break;
-					}
-				}
-				const newPos = eater(input, pos);
-				if (pos !== newPos) {
-					text += input.slice(pos, newPos);
-					pos = newPos;
-				} else {
-					break;
-				}
-				if (pos === input.length) break;
-			}
-			return [pos, text.trimEnd()];
-		};
-
-		const eatPropertyName = walkCssTokens.eatUntil(":{};");
-
-		/**
+		 * Returns end.
 		 * @param {string} input input
 		 * @param {number} start start
 		 * @param {number} end end
@@ -523,6 +778,7 @@
 		// Vanilla CSS stuff
 
 		/**
+		 * Processes the provided input.
 		 * @param {string} input input
 		 * @param {number} start name start position
 		 * @param {number} end name end position
@@ -591,12 +847,14 @@
 				return newline;
 			}
 
+			/** @type {undefined | string} */
 			let layer;
 
 			if (tokens[1]) {
 				layer = input.slice(tokens[1][0] + 6, tokens[1][1] - 1).trim();
 			}
 
+			/** @type {undefined | string} */
 			let supports;
 
 			if (tokens[2]) {
@@ -604,8 +862,12 @@
 			}
 
 			const last = tokens[2] || tokens[1] || tokens[0];
-			const mediaStart = walkCssTokens.eatWhitespaceAndComments(input, last[1]);
+			const mediaStart = walkCssTokens.eatWhitespaceAndComments(
+				input,
+				last[1]
+			)[0];
 
+			/** @type {undefined | string} */
 			let media;
 
 			if (mediaStart !== semi - 1) {
@@ -629,6 +891,7 @@
 		};
 
 		/**
+		 * Process url function.
 		 * @param {string} input input
 		 * @param {number} end end position
 		 * @param {string} name the name of function
@@ -691,6 +954,7 @@
 		};
 
 		/**
+		 * Process old url function.
 		 * @param {string} input input
 		 * @param {number} start start position
 		 * @param {number} end end position
@@ -753,6 +1017,7 @@
 		};
 
 		/**
+		 * Process image set function.
 		 * @param {string} input input
 		 * @param {number} start start position
 		 * @param {number} end end position
@@ -817,13 +1082,48 @@
 		// CSS modules stuff
 
 		/**
+		 * Returns resolved reexport (localName and importName).
+		 * @param {string} value value to resolve
+		 * @param {string=} localName override local name
+		 * @param {boolean=} isCustomProperty true when it is custom property, otherwise false
+		 * @returns {string | [string, string]} resolved reexport (`localName` and `importName`)
+		 */
+		const getReexport = (value, localName, isCustomProperty) => {
+			const reexport = icssDefinitions.get(
+				isCustomProperty ? `--${value}` : value
+			);
+
+			if (reexport) {
+				if (reexport.importName) {
+					return [
+						reexport.localName || (isCustomProperty ? `--${value}` : value),
+						reexport.importName
+					];
+				}
+
+				if (isCustomProperty) {
+					return /** @type {string} */ (reexport.value).slice(2);
+				}
+
+				return /** @type {string} */ (reexport.value);
+			}
+
+			if (localName) {
+				return [localName, value];
+			}
+
+			return value;
+		};
+
+		/**
+		 * Process import or export.
 		 * @param {0 | 1} type import or export
 		 * @param {string} input input
 		 * @param {number} pos start position
 		 * @returns {number} position after parse
 		 */
 		const processImportOrExport = (type, input, pos) => {
-			pos = walkCssTokens.eatWhitespaceAndComments(input, pos);
+			pos = walkCssTokens.eatWhitespaceAndComments(input, pos)[0];
 			/** @type {string | undefined} */
 			let request;
 			if (type === 0) {
@@ -844,7 +1144,7 @@
 				if (!str) {
 					this._emitWarning(
 						state,
-						`Unexpected '${input[pos]}' at ${pos} during parsing of '${type ? ":import" : ":export"}' (expected string)`,
+						`Unexpected '${input[pos]}' at ${pos} during parsing of '${type === 0 ? ":import" : ":export"}' (expected string)`,
 						locConverter,
 						stringStart,
 						pos
@@ -853,7 +1153,7 @@
 				}
 				request = input.slice(str[0] + 1, str[1] - 1);
 				pos = str[1];
-				pos = walkCssTokens.eatWhitespaceAndComments(input, pos);
+				pos = walkCssTokens.eatWhitespaceAndComments(input, pos)[0];
 				cc = input.charCodeAt(pos);
 				if (cc !== CC_RIGHT_PARENTHESIS) {
 					this._emitWarning(
@@ -866,10 +1166,11 @@
 					return pos;
 				}
 				pos++;
-				pos = walkCssTokens.eatWhitespaceAndComments(input, pos);
+				pos = walkCssTokens.eatWhitespaceAndComments(input, pos)[0];
 			}
 
 			/**
+			 * Creates a dep from the provided name.
 			 * @param {string} name name
 			 * @param {string} value value
 			 * @param {number} start start of position
@@ -883,22 +1184,17 @@
 						[0, 0],
 						/** @type {"local" | "global"} */
 						(mode),
-						value
+						value,
+						name
 					);
 					const { line: sl, column: sc } = locConverter.get(start);
 					const { line: el, column: ec } = locConverter.get(end);
 					dep.setLoc(sl, sc, el, ec);
 					module.addDependency(dep);
 
-					icssDefinitions.set(name, { value, isReference: true });
+					icssDefinitions.set(name, { importName: value });
 				} else if (type === 1) {
-					const reexport = icssDefinitions.get(value);
-					const dep = new CssIcssExportDependency(
-						name,
-						value,
-						reexport && reexport.isReference ? reexport.value : undefined,
-						undefined
-					);
+					const dep = new CssIcssExportDependency(name, getReexport(value));
 					const { line: sl, column: sc } = locConverter.get(start);
 					const { line: el, column: ec } = locConverter.get(end);
 					dep.setLoc(sl, sc, el, ec);
@@ -989,7 +1285,79 @@
 			return pos;
 		};
 
+		/** @typedef {{ from: string, items: ({ localName: string, importName: string })[] }} ValueAtRuleImport */
+		/** @typedef {{ localName: string, value: string }} ValueAtRuleValue */
 		/**
+		 * Parses value at rule params.
+		 * @param {string} str value at-rule params
+		 * @returns {ValueAtRuleImport | ValueAtRuleValue} parsed result
+		 */
+		const parseValueAtRuleParams = (str) => {
+			if (/from(\/\*|\s)(?:[\s\S]+)$/i.test(str)) {
+				str = str.replace(CSS_COMMENT, " ").trim().replace(/;$/, "");
+				const fromIdx = str.lastIndexOf("from");
+				const path = str
+					.slice(fromIdx + 5)
+					.trim()
+					.replace(/['"]/g, "");
+				let content = str.slice(0, fromIdx).trim();
+
+				if (content.startsWith("(") && content.endsWith(")")) {
+					content = content.slice(1, -1);
+				}
+
+				return {
+					from: path,
+					items: content.split(",").map((item) => {
+						item = item.trim();
+
+						if (item.includes(":")) {
+							const [local, remote] = item.split(":");
+
+							return { localName: local.trim(), importName: remote.trim() };
+						}
+
+						const asParts = item.split(/\s+as\s+/);
+
+						if (asParts.length === 2) {
+							return {
+								localName: asParts[1].trim(),
+								importName: asParts[0].trim()
+							};
+						}
+
+						return { localName: item, importName: item };
+					})
+				};
+			}
+
+			/** @type {string} */
+			let localName;
+			/** @type {string} */
+			let value;
+
+			const idx = str.indexOf(":");
+
+			if (idx !== -1) {
+				localName = str.slice(0, idx).replace(CSS_COMMENT, "").trim();
+				value = str.slice(idx + 1);
+			} else {
+				const mask = str.replace(CSS_COMMENT, (m) => " ".repeat(m.length));
+				const idx = mask.search(/\S\s/) + 1;
+
+				localName = str.slice(0, idx).replace(CSS_COMMENT, "").trim();
+				value = str.slice(idx + (str[idx] === " " ? 1 : 0));
+			}
+
+			if (value.length > 0 && !/^\s+$/.test(value.replace(CSS_COMMENT, ""))) {
+				value = value.trim();
+			}
+
+			return { localName, value };
+		};
+
+		/**
+		 * Processes the provided input.
 		 * @param {string} input input
 		 * @param {number} start name start position
 		 * @param {number} end name end position
@@ -999,83 +1367,12 @@
 			const semi = eatUntilSemi(input, end);
 			const atRuleEnd = semi + 1;
 			const params = input.slice(end, semi);
-			let [alias, request] = params.split(/\s*from\s*/);
+			const parsed = parseValueAtRuleParams(params);
 
-			if (request) {
-				const aliases = alias
-					.replace(CSS_COMMENT, " ")
-					.trim()
-					.replace(/^\(\s*|\s*\)$/g, "")
-					.split(/\s*,\s*/);
-
-				request = request.replace(CSS_COMMENT, "").trim();
-
-				const isExplicitImport = request[0] === "'" || request[0] === '"';
-
-				if (isExplicitImport) {
-					request = request.slice(1, -1);
-				}
-
-				for (const alias of aliases) {
-					const [name, aliasName] = alias.split(/\s+as\s+/);
-
-					{
-						const reexport = icssDefinitions.get(request);
-
-						if (reexport) {
-							request = reexport.value.slice(1, -1);
-						}
-
-						const dep = new CssIcssImportDependency(
-							request,
-							[0, 0],
-							/** @type {"local" | "global"} */
-							(mode),
-							name
-						);
-						const { line: sl, column: sc } = locConverter.get(start);
-						const { line: el, column: ec } = locConverter.get(end);
-						dep.setLoc(sl, sc, el, ec);
-						module.addDependency(dep);
-
-						icssDefinitions.set(aliasName || name, {
-							value: name,
-							isReference: true
-						});
-					}
-
-					if (aliasName) {
-						const reexport = icssDefinitions.get(aliasName);
-						const dep = new CssIcssExportDependency(
-							aliasName,
-							name,
-							reexport && reexport.isReference ? reexport.value : undefined,
-							undefined
-						);
-						const { line: sl, column: sc } = locConverter.get(start);
-						const { line: el, column: ec } = locConverter.get(end);
-						dep.setLoc(sl, sc, el, ec);
-						module.addDependency(dep);
-					}
-
-					{
-						const reexport = icssDefinitions.get(name);
-						const dep = new CssIcssExportDependency(
-							name,
-							name,
-							reexport && reexport.isReference ? reexport.value : undefined,
-							undefined
-						);
-						const { line: sl, column: sc } = locConverter.get(start);
-						const { line: el, column: ec } = locConverter.get(end);
-						dep.setLoc(sl, sc, el, ec);
-						module.addDependency(dep);
-					}
-				}
-			} else {
-				const ident = walkCssTokens.eatIdentSequence(alias, 0);
-
-				if (!ident) {
+			if (
+				typeof (/** @type {ValueAtRuleImport} */ (parsed).from) !== "undefined"
+			) {
+				if (/** @type {ValueAtRuleImport} */ (parsed).from.length === 0) {
 					this._emitWarning(
 						state,
 						`Broken '@value' at-rule: ${input.slice(start, atRuleEnd)}'`,
@@ -1089,33 +1386,87 @@
 					return atRuleEnd;
 				}
 
-				const pos = walkCssTokens.eatWhitespaceAndComments(alias, ident[1]);
+				let { from, items } = /** @type {ValueAtRuleImport} */ (parsed);
 
-				const name = alias.slice(ident[0], ident[1]);
-				let value =
-					alias.charCodeAt(pos) === CC_COLON
-						? alias.slice(pos + 1)
-						: alias.slice(ident[1]);
+				for (const { importName, localName } of items) {
+					{
+						const reexport = icssDefinitions.get(from);
 
-				if (value && !/^\s+$/.test(value.replace(CSS_COMMENT, ""))) {
-					value = value.trim();
+						if (reexport && reexport.value) {
+							from = reexport.value.slice(1, -1);
+						}
+
+						const dep = new CssIcssImportDependency(
+							from,
+							[0, 0],
+							/** @type {"local" | "global"} */
+							(mode),
+							importName,
+							localName
+						);
+						const { line: sl, column: sc } = locConverter.get(start);
+						const { line: el, column: ec } = locConverter.get(end);
+						dep.setLoc(sl, sc, el, ec);
+						module.addDependency(dep);
+
+						icssDefinitions.set(localName, { importName });
+					}
+
+					{
+						const dep = new CssIcssExportDependency(
+							localName,
+							getReexport(localName),
+							undefined,
+							false,
+							CssIcssExportDependency.EXPORT_MODE.REPLACE
+						);
+						const { line: sl, column: sc } = locConverter.get(start);
+						const { line: el, column: ec } = locConverter.get(end);
+						dep.setLoc(sl, sc, el, ec);
+						module.addDependency(dep);
+					}
 				}
+			} else {
+				if (/** @type {ValueAtRuleValue} */ (parsed).localName.length === 0) {
+					this._emitWarning(
+						state,
+						`Broken '@value' at-rule: ${input.slice(start, atRuleEnd)}'`,
+						locConverter,
+						start,
+						atRuleEnd
+					);
+
+					const dep = new ConstDependency("", [start, atRuleEnd]);
+					module.addPresentationalDependency(dep);
+					return atRuleEnd;
+				}
+
+				const { localName, value } = /** @type {ValueAtRuleValue} */ (parsed);
+				const { line: sl, column: sc } = locConverter.get(start);
+				const { line: el, column: ec } = locConverter.get(end);
 
 				if (icssDefinitions.has(value)) {
 					const def =
 						/** @type {IcssDefinition} */
 						(icssDefinitions.get(value));
 
-					value = def.value;
+					def.localName = value;
+
+					icssDefinitions.set(localName, def);
+
+					const dep = new CssIcssExportDependency(
+						localName,
+						getReexport(value)
+					);
+					dep.setLoc(sl, sc, el, ec);
+					module.addDependency(dep);
+				} else {
+					icssDefinitions.set(localName, { value });
+
+					const dep = new CssIcssExportDependency(localName, value);
+					dep.setLoc(sl, sc, el, ec);
+					module.addDependency(dep);
 				}
-
-				icssDefinitions.set(name, { value });
-
-				const dep = new CssIcssExportDependency(name, value);
-				const { line: sl, column: sc } = locConverter.get(start);
-				const { line: el, column: ec } = locConverter.get(end);
-				dep.setLoc(sl, sc, el, ec);
-				module.addDependency(dep);
 			}
 
 			const dep = new ConstDependency("", [start, atRuleEnd]);
@@ -1124,22 +1475,23 @@
 		};
 
 		/**
+		 * Process icss symbol.
 		 * @param {string} name ICSS symbol name
 		 * @param {number} start start position
 		 * @param {number} end end position
 		 * @returns {number} position after handling
 		 */
 		const processICSSSymbol = (name, start, end) => {
-			const { value, isReference } =
+			const def =
 				/** @type {IcssDefinition} */
 				(icssDefinitions.get(name));
 			const { line: sl, column: sc } = locConverter.get(start);
 			const { line: el, column: ec } = locConverter.get(end);
 			const dep = new CssIcssSymbolDependency(
-				name,
-				value,
+				def.localName || name,
 				[start, end],
-				isReference
+				def.value,
+				def.importName
 			);
 			dep.setLoc(sl, sc, el, ec);
 			module.addDependency(dep);
@@ -1147,6 +1499,7 @@
 		};
 
 		/**
+		 * Process local or global function.
 		 * @param {string} input input
 		 * @param {1 | 2} type type of function
 		 * @param {number} start start position
@@ -1164,23 +1517,36 @@
 			end = walkCssTokens.consumeUntil(
 				input,
 				start,
-				type === 1
-					? {
-							identifier(input, start, end) {
-								const name = unescapeIdentifier(input.slice(start, end));
-								const { line: sl, column: sc } = locConverter.get(start);
-								const { line: el, column: ec } = locConverter.get(end);
-								const dep = new CssIcssLocalIdentifierDependency(name, [
-									start,
-									end
-								]);
-								dep.setLoc(sl, sc, el, ec);
-								module.addDependency(dep);
+				{
+					identifier(input, start, end) {
+						if (type === 1) {
+							let identifier = unescapeIdentifier(input.slice(start, end));
+							const { line: sl, column: sc } = locConverter.get(start);
+							const { line: el, column: ec } = locConverter.get(end);
+							const isDashedIdent = isDashedIdentifier(identifier);
 
-								return end;
+							if (isDashedIdent) {
+								identifier = identifier.slice(2);
 							}
+
+							const dep = new CssIcssExportDependency(
+								identifier,
+								getReexport(identifier),
+								[start, end],
+								true,
+								CssIcssExportDependency.EXPORT_MODE.ONCE,
+								isDashedIdent
+									? CssIcssExportDependency.EXPORT_TYPE.CUSTOM_VARIABLE
+									: CssIcssExportDependency.EXPORT_TYPE.NORMAL
+							);
+
+							dep.setLoc(sl, sc, el, ec);
+							module.addDependency(dep);
 						}
-					: {},
+
+						return end;
+					}
+				},
 				{},
 				{ onlyTopLevel: true, functionValue: true }
 			);
@@ -1195,37 +1561,72 @@
 		};
 
 		/**
+		 * Process local at rule.
 		 * @param {string} input input
 		 * @param {number} end name end position
-		 * @param {{ string?: boolean, identifier: boolean, validate?: (name: string) => boolean, dashed?: boolean }} options types which allowed to handle
+		 * @param {{ string?: boolean, identifier?: boolean | RegExp }} options types which allowed to handle
 		 * @returns {number} position after handling
 		 */
 		const processLocalAtRule = (input, end, options) => {
-			/** @type {[number, number, boolean] | undefined} */
-			let value;
 			let found = false;
 
-			walkCssTokens.consumeUntil(
+			return walkCssTokens.consumeUntil(
 				input,
 				end,
 				{
 					string(_input, start, end) {
 						if (!found && options.string) {
+							const value = unescapeIdentifier(input.slice(start + 1, end - 1));
+							const { line: sl, column: sc } = locConverter.get(start);
+							const { line: el, column: ec } = locConverter.get(end);
+							const dep = new CssIcssExportDependency(
+								value,
+								value,
+								[start, end],
+								true,
+								CssIcssExportDependency.EXPORT_MODE.ONCE
+							);
+							dep.setLoc(sl, sc, el, ec);
+							module.addDependency(dep);
 							found = true;
-							value = [start, end, true];
 						}
 						return end;
 					},
-					identifier(_input, start, end) {
-						if (!found && options.identifier) {
-							found = true;
-							value = [start, end, false];
+					identifier(input, start, end) {
+						if (!found) {
+							const value = input.slice(start, end);
+
+							if (options.identifier) {
+								const identifier = unescapeIdentifier(value);
+
+								if (
+									options.identifier instanceof RegExp &&
+									options.identifier.test(identifier)
+								) {
+									return end;
+								}
+
+								const { line: sl, column: sc } = locConverter.get(start);
+								const { line: el, column: ec } = locConverter.get(end);
+
+								const dep = new CssIcssExportDependency(
+									identifier,
+									getReexport(identifier),
+									[start, end],
+									true,
+									CssIcssExportDependency.EXPORT_MODE.ONCE,
+									CssIcssExportDependency.EXPORT_TYPE.NORMAL
+								);
+								dep.setLoc(sl, sc, el, ec);
+								module.addDependency(dep);
+								found = true;
+							}
 						}
 						return end;
 					}
 				},
 				{
-					function(input, start, end) {
+					function: (input, start, end) => {
 						// No need to handle `:` (COLON), because it's always a function
 						const name = input
 							.slice(start, end - 1)
@@ -1240,53 +1641,37 @@
 							return processLocalOrGlobalFunction(input, type, start, end);
 						}
 
+						if (
+							this.options.dashedIdents &&
+							isLocalMode() &&
+							(name === "var" || name === "style")
+						) {
+							return processDashedIdent(input, end, end);
+						}
+
 						return end;
 					}
 				},
 				{ onlyTopLevel: true, atRulePrelude: true }
 			);
-			if (!value) return end;
-			let name = value[2]
-				? input.slice(value[0] + 1, value[1] - 1)
-				: input.slice(value[0], value[1]);
-			if (options.validate && !options.validate(name)) return end;
-			name = unescapeIdentifier(name);
-			const { line: sl, column: sc } = locConverter.get(value[0]);
-			const { line: el, column: ec } = locConverter.get(value[1]);
-			if (options.dashed) {
-				name = name.slice(2);
-				declaredCssVariables.add(name);
-			}
-			const dep = new CssIcssLocalIdentifierDependency(
-				name,
-				[value[0], value[1]],
-				options.dashed ? "--" : ""
-			);
-			dep.setLoc(sl, sc, el, ec);
-			module.addDependency(dep);
-			return value[1];
 		};
 		/**
+		 * Process dashed ident.
 		 * @param {string} input input
+		 * @param {number} start start position
 		 * @param {number} end end position
 		 * @returns {number} position after handling
 		 */
-		const processVarFunction = (input, end) => {
-			const customIdent = walkCssTokens.eatIdentSequence(input, end);
+		const processDashedIdent = (input, start, end) => {
+			const customIdent = walkCssTokens.eatIdentSequence(input, start);
 			if (!customIdent) return end;
-			let name = input.slice(customIdent[0], customIdent[1]);
-			// A custom property is any property whose name starts with two dashes (U+002D HYPHEN-MINUS), like --foo.
-			// The <custom-property-name> production corresponds to this:
-			// it鈥檚 defined as any <dashed-ident> (a valid identifier that starts with two dashes),
-			// except -- itself, which is reserved for future use by CSS.
-			if (!name.startsWith("--") || name.length < 3) return end;
-			name = unescapeIdentifier(
+			const identifier = unescapeIdentifier(
 				input.slice(customIdent[0] + 2, customIdent[1])
 			);
 			const afterCustomIdent = walkCssTokens.eatWhitespaceAndComments(
 				input,
 				customIdent[1]
-			);
+			)[0];
 			if (
 				input.charCodeAt(afterCustomIdent) === CC_LOWER_F ||
 				input.charCodeAt(afterCustomIdent) === CC_UPPER_F
@@ -1303,7 +1688,7 @@
 				}
 				const from = walkCssTokens.eatIdentSequenceOrString(
 					input,
-					walkCssTokens.eatWhitespaceAndComments(input, fromWord[1])
+					walkCssTokens.eatWhitespaceAndComments(input, fromWord[1])[0]
 				);
 				if (!from) {
 					return end;
@@ -1316,18 +1701,35 @@
 				} else if (from[2] === false) {
 					const { line: sl, column: sc } = locConverter.get(customIdent[0]);
 					const { line: el, column: ec } = locConverter.get(from[1] - 1);
-					const dep = new CssIcssFromIdentifierDependency(
-						path.slice(1, -1),
-						/** @type {"local" | "global"} */
-						(mode),
-						[customIdent[0], from[1] - 1],
-						name,
-						name,
-						"--"
-					);
+					const localName = `__ICSS_IMPORT_${counter++}__`;
 
-					dep.setLoc(sl, sc, el, ec);
-					module.addDependency(dep);
+					{
+						const dep = new CssIcssImportDependency(
+							path.slice(1, -1),
+							[customIdent[0], from[1] - 1],
+							/** @type {"local" | "global"} */
+							(mode),
+							identifier,
+							localName
+						);
+
+						dep.setLoc(sl, sc, el, ec);
+						module.addDependency(dep);
+					}
+
+					{
+						const dep = new CssIcssExportDependency(
+							identifier,
+							getReexport(identifier, localName, true),
+							[customIdent[0], from[1] - 1],
+							true,
+							CssIcssExportDependency.EXPORT_MODE.ONCE,
+							CssIcssExportDependency.EXPORT_TYPE.CUSTOM_VARIABLE
+						);
+
+						dep.setLoc(sl, sc, el, ec);
+						module.addDependency(dep);
+					}
 
 					{
 						const dep = new ConstDependency("", [fromWord[0], from[1]]);
@@ -1338,12 +1740,13 @@
 			} else {
 				const { line: sl, column: sc } = locConverter.get(customIdent[0]);
 				const { line: el, column: ec } = locConverter.get(customIdent[1]);
-				const dep = new CssIcssSelfLocalIdentifierDependency(
-					name,
-					undefined,
+				const dep = new CssIcssExportDependency(
+					identifier,
+					getReexport(identifier, undefined, true),
 					[customIdent[0], customIdent[1]],
-					"--",
-					declaredCssVariables
+					true,
+					CssIcssExportDependency.EXPORT_MODE.ONCE,
+					CssIcssExportDependency.EXPORT_TYPE.CUSTOM_VARIABLE
 				);
 				dep.setLoc(sl, sc, el, ec);
 				module.addDependency(dep);
@@ -1353,86 +1756,148 @@
 			return end;
 		};
 		/**
+		 * Process local declaration.
 		 * @param {string} input input
 		 * @param {number} pos name start position
 		 * @param {number} end name end position
 		 * @returns {number} position after handling
 		 */
 		const processLocalDeclaration = (input, pos, end) => {
-			modeData = undefined;
-			pos = walkCssTokens.eatWhitespaceAndComments(input, pos);
-			const propertyNameStart = pos;
-			const [propertyNameEnd, propertyName] = eatText(
-				input,
-				pos,
-				eatPropertyName
-			);
-			if (input.charCodeAt(propertyNameEnd) !== CC_COLON) return end;
-			pos = propertyNameEnd + 1;
-			if (propertyName.startsWith("--") && propertyName.length >= 3) {
-				// CSS Variable
-				const { line: sl, column: sc } = locConverter.get(propertyNameStart);
-				const { line: el, column: ec } = locConverter.get(propertyNameEnd);
-				const name = unescapeIdentifier(propertyName.slice(2));
-				const dep = new CssIcssLocalIdentifierDependency(
-					name,
-					[propertyNameStart, propertyNameEnd],
-					"--"
-				);
-				dep.setLoc(sl, sc, el, ec);
-				module.addDependency(dep);
-				declaredCssVariables.add(name);
-			} else if (
-				OPTIONALLY_VENDOR_PREFIXED_ANIMATION_PROPERTY.test(propertyName)
-			) {
-				/** @type {[number, number, boolean][]} */
-				const animationNames = [];
+			pos = walkCssTokens.eatWhitespaceAndComments(input, pos)[0];
+			const identifier = walkCssTokens.eatIdentSequence(input, pos);
+
+			if (!identifier) {
+				return end;
+			}
+
+			const propertyNameStart = identifier[0];
+
+			pos = walkCssTokens.eatWhitespaceAndComments(input, identifier[1])[0];
+
+			if (input.charCodeAt(pos) !== CC_COLON) {
+				return end;
+			}
+
+			pos += 1;
+
+			// Remove prefix and lowercase
+			const propertyName = input
+				.slice(identifier[0], identifier[1])
+				.replace(/^(-\w+-)/, "")
+				.toLowerCase();
+
+			if (isLocalMode() && knownProperties.has(propertyName)) {
+				/** @type {[number, number, boolean?][]} */
+				const values = [];
 				/** @type {Record<string, number>} */
-				let parsedAnimationKeywords = Object.create(null);
+				let parsedKeywords = Object.create(null);
+
+				const isGridProperty = Boolean(propertyName.startsWith("grid"));
+				const isGridTemplate = isGridProperty
+					? Boolean(
+							propertyName === "grid" ||
+							propertyName === "grid-template" ||
+							propertyName === "grid-template-columns" ||
+							propertyName === "grid-template-rows"
+						)
+					: false;
+
+				let afterExclamation = false;
 
 				const end = walkCssTokens.consumeUntil(
 					input,
 					pos,
 					{
+						delim(input, start, end) {
+							afterExclamation = input.charCodeAt(start) === CC_EXCLAMATION;
+							return end;
+						},
+						leftSquareBracket(input, start, end) {
+							let i = end;
+
+							while (true) {
+								i = walkCssTokens.eatWhitespaceAndComments(input, i)[0];
+								const name = walkCssTokens.eatIdentSequence(input, i);
+
+								if (!name) {
+									break;
+								}
+
+								values.push(name);
+								i = name[1];
+							}
+
+							return end;
+						},
 						string(_input, start, end) {
-							animationNames.push([start, end, true]);
+							if (
+								propertyName === "animation" ||
+								propertyName === "animation-name"
+							) {
+								values.push([start, end, true]);
+							}
+
+							if (
+								propertyName === "grid" ||
+								propertyName === "grid-template" ||
+								propertyName === "grid-template-areas"
+							) {
+								const areas = unescapeIdentifier(
+									input.slice(start + 1, end - 1)
+								);
+								const matches = matchAll(/\b\w+\b/g, areas);
+
+								for (const match of matches) {
+									const areaStart = start + 1 + match.index;
+									values.push([areaStart, areaStart + match[0].length, false]);
+								}
+							}
 
 							return end;
 						},
 						identifier(input, start, end) {
-							const keyword = input.slice(start, end).toLowerCase();
+							if (isGridTemplate) {
+								return end;
+							}
 
-							parsedAnimationKeywords[keyword] =
-								typeof parsedAnimationKeywords[keyword] !== "undefined"
-									? parsedAnimationKeywords[keyword] + 1
+							if (afterExclamation) {
+								afterExclamation = false;
+								return end;
+							}
+
+							const identifier = input.slice(start, end);
+							const keyword = identifier.toLowerCase();
+
+							parsedKeywords[keyword] =
+								typeof parsedKeywords[keyword] !== "undefined"
+									? parsedKeywords[keyword] + 1
 									: 0;
+							const keywords =
+								/** @type {Record<string, number>} */
+								(knownProperties.get(propertyName));
 
 							if (
-								ANIMATION_KEYWORDS[keyword] &&
-								parsedAnimationKeywords[keyword] < ANIMATION_KEYWORDS[keyword]
+								keywords[keyword] &&
+								parsedKeywords[keyword] < keywords[keyword]
 							) {
 								return end;
 							}
 
-							animationNames.push([start, end, false]);
+							values.push([start, end]);
 							return end;
 						},
 						comma(_input, _start, end) {
-							parsedAnimationKeywords = {};
+							parsedKeywords = {};
 
 							return end;
 						}
 					},
 					{
-						function(input, start, end) {
+						function: (input, start, end) => {
 							const name = input
 								.slice(start, end - 1)
 								.replace(/\\/g, "")
 								.toLowerCase();
-
-							if (isLocalMode() && name === "var") {
-								return processVarFunction(input, end);
-							}
 
 							const type =
 								name === "local" ? 1 : name === "global" ? 2 : undefined;
@@ -1441,26 +1906,50 @@
 								return processLocalOrGlobalFunction(input, type, start, end);
 							}
 
+							if (
+								this.options.dashedIdents &&
+								isLocalMode() &&
+								name === "var"
+							) {
+								return processDashedIdent(input, end, end);
+							}
+
+							if (this.options.url) {
+								if (name === "src" || name === "url") {
+									return processURLFunction(input, end, name);
+								} else if (IMAGE_SET_FUNCTION.test(name)) {
+									return processImageSetFunction(input, start, end);
+								}
+							}
+
 							return end;
 						}
 					},
-					{ onlyTopLevel: true, declarationValue: true }
+					{
+						onlyTopLevel: !isGridTemplate,
+						declarationValue: true
+					}
 				);
 
-				if (animationNames.length > 0) {
-					for (const animationName of animationNames) {
-						const { line: sl, column: sc } = locConverter.get(animationName[0]);
-						const { line: el, column: ec } = locConverter.get(animationName[1]);
-						const [start, end, isString] = animationName;
+				if (values.length > 0) {
+					for (const value of values) {
+						const { line: sl, column: sc } = locConverter.get(value[0]);
+						const { line: el, column: ec } = locConverter.get(value[1]);
+						const [start, end, isString] = value;
 						const name = unescapeIdentifier(
 							isString
 								? input.slice(start + 1, end - 1)
 								: input.slice(start, end)
 						);
-						const dep = new CssIcssSelfLocalIdentifierDependency(
+						const dep = new CssIcssExportDependency(
 							name,
-							undefined,
-							[start, end]
+							getReexport(name),
+							[start, end],
+							true,
+							CssIcssExportDependency.EXPORT_MODE.ONCE,
+							isGridProperty
+								? CssIcssExportDependency.EXPORT_TYPE.GRID_CUSTOM_IDENTIFIER
+								: CssIcssExportDependency.EXPORT_TYPE.NORMAL
 						);
 						dep.setLoc(sl, sc, el, ec);
 						module.addDependency(dep);
@@ -1491,7 +1980,7 @@
 				const classNames = new Set();
 
 				while (true) {
-					pos = walkCssTokens.eatWhitespaceAndComments(input, pos);
+					pos = walkCssTokens.eatWhitespaceAndComments(input, pos)[0];
 
 					let className = walkCssTokens.eatIdentSequence(input, pos);
 
@@ -1509,14 +1998,20 @@
 						pos = walkCssTokens.eatWhitespaceAndComments(
 							input,
 							className[1] + 1
-						);
+						)[0];
 						className = walkCssTokens.eatIdentSequence(input, pos);
 						if (className) {
-							pos = walkCssTokens.eatWhitespaceAndComments(input, className[1]);
+							pos = walkCssTokens.eatWhitespaceAndComments(
+								input,
+								className[1]
+							)[0];
 							pos += 1;
 						}
 					} else if (className) {
-						pos = walkCssTokens.eatWhitespaceAndComments(input, className[1]);
+						pos = walkCssTokens.eatWhitespaceAndComments(
+							input,
+							className[1]
+						)[0];
 						pos = className[1];
 					}
 
@@ -1533,26 +2028,16 @@
 						for (const className of classNames) {
 							const [start, end] = className;
 							const identifier = unescapeIdentifier(input.slice(start, end));
-							const reexport = icssDefinitions.get(identifier);
-							const dep = isGlobalFunction
-								? new CssIcssGlobalIdentifierDependency(
-										lastLocalIdentifier,
-										identifier,
-										reexport && reexport.isReference
-											? reexport.value
-											: undefined,
-										[start, end]
-									)
-								: new CssIcssSelfLocalIdentifierDependency(
-										lastLocalIdentifier,
-										identifier,
-										[start, end],
-										undefined,
-										undefined,
-										reexport && reexport.isReference
-											? reexport.value
-											: undefined
-									);
+							const dep = new CssIcssExportDependency(
+								lastLocalIdentifier,
+								getReexport(identifier),
+								[start, end],
+								!isGlobalFunction,
+								isGlobalFunction
+									? CssIcssExportDependency.EXPORT_MODE.APPEND
+									: CssIcssExportDependency.EXPORT_MODE.SELF_REFERENCE,
+								CssIcssExportDependency.EXPORT_TYPE.COMPOSES
+							);
 							const { line: sl, column: sc } = locConverter.get(start);
 							const { line: el, column: ec } = locConverter.get(end);
 							dep.setLoc(sl, sc, el, ec);
@@ -1582,19 +2067,35 @@
 							for (const className of classNames) {
 								const [start, end] = className;
 								const identifier = unescapeIdentifier(input.slice(start, end));
-								const dep = new CssIcssFromIdentifierDependency(
-									request,
-									/** @type {"local" | "global"} */
-									(mode),
-									[start, end],
-									identifier,
-									/** @type {string} */
-									(lastLocalIdentifier)
-								);
 								const { line: sl, column: sc } = locConverter.get(start);
 								const { line: el, column: ec } = locConverter.get(end);
-								dep.setLoc(sl, sc, el, ec);
-								module.addDependency(dep);
+								const localName = `__ICSS_IMPORT_${counter++}__`;
+
+								{
+									const dep = new CssIcssImportDependency(
+										request,
+										[start, end],
+										/** @type {"local" | "global"} */
+										(mode),
+										identifier,
+										localName
+									);
+									dep.setLoc(sl, sc, el, ec);
+									module.addDependency(dep);
+								}
+
+								{
+									const dep = new CssIcssExportDependency(
+										lastLocalIdentifier,
+										getReexport(identifier, localName),
+										[start, end],
+										true,
+										CssIcssExportDependency.EXPORT_MODE.APPEND,
+										CssIcssExportDependency.EXPORT_TYPE.COMPOSES
+									);
+									dep.setLoc(sl, sc, el, ec);
+									module.addDependency(dep);
+								}
 							}
 
 							classNames.clear();
@@ -1608,15 +2109,14 @@
 									const identifier = unescapeIdentifier(
 										input.slice(start, end)
 									);
-									const reexport = icssDefinitions.get(identifier);
-									const dep = new CssIcssGlobalIdentifierDependency(
+									const dep = new CssIcssExportDependency(
 										/** @type {string} */
 										(lastLocalIdentifier),
-										identifier,
-										reexport && reexport.isReference
-											? reexport.value
-											: undefined,
-										[start, end]
+										getReexport(identifier),
+										[start, end],
+										false,
+										CssIcssExportDependency.EXPORT_MODE.APPEND,
+										CssIcssExportDependency.EXPORT_TYPE.COMPOSES
 									);
 									const { line: sl, column: sc } = locConverter.get(start);
 									const { line: el, column: ec } = locConverter.get(end);
@@ -1657,24 +2157,122 @@
 				const dep = new ConstDependency("", [propertyNameStart, end]);
 				module.addPresentationalDependency(dep);
 			}
+
 			return pos;
 		};
 
 		/**
+		 * Process id selector.
 		 * @param {string} input input
 		 * @param {number} start start position
 		 * @param {number} end end position
 		 * @returns {number} position after handling
 		 */
-		const processHashID = (input, start, end) => {
+		const processIdSelector = (input, start, end) => {
 			const valueStart = start + 1;
 			const name = unescapeIdentifier(input.slice(valueStart, end));
-			const dep = new CssIcssLocalIdentifierDependency(name, [valueStart, end]);
+			const dep = new CssIcssExportDependency(
+				name,
+				getReexport(name),
+				[valueStart, end],
+				true,
+				CssIcssExportDependency.EXPORT_MODE.ONCE
+			);
 			const { line: sl, column: sc } = locConverter.get(start);
 			const { line: el, column: ec } = locConverter.get(end);
 			dep.setLoc(sl, sc, el, ec);
 			module.addDependency(dep);
 			return end;
+		};
+
+		/**
+		 * Process class selector.
+		 * @param {string} input input
+		 * @param {number} start start position
+		 * @param {number} end end position
+		 * @returns {number} position after handling
+		 */
+		const processClassSelector = (input, start, end) => {
+			const ident = walkCssTokens.skipCommentsAndEatIdentSequence(input, end);
+			if (!ident) return end;
+			const name = unescapeIdentifier(input.slice(ident[0], ident[1]));
+			lastLocalIdentifiers.push(name);
+			const dep = new CssIcssExportDependency(
+				name,
+				getReexport(name),
+				[ident[0], ident[1]],
+				true,
+				CssIcssExportDependency.EXPORT_MODE.ONCE
+			);
+			const { line: sl, column: sc } = locConverter.get(ident[0]);
+			const { line: el, column: ec } = locConverter.get(ident[1]);
+			dep.setLoc(sl, sc, el, ec);
+			module.addDependency(dep);
+			return ident[1];
+		};
+
+		/**
+		 * Process attribute selector.
+		 * @param {string} input input
+		 * @param {number} start start position
+		 * @param {number} end end position
+		 * @returns {number} position after handling
+		 */
+		const processAttributeSelector = (input, start, end) => {
+			end = walkCssTokens.eatWhitespaceAndComments(input, end)[0];
+			const identifier = walkCssTokens.eatIdentSequence(input, end);
+			if (!identifier) return end;
+			const name = unescapeIdentifier(
+				input.slice(identifier[0], identifier[1])
+			);
+			if (name.toLowerCase() !== "class") {
+				return end;
+			}
+			end = walkCssTokens.eatWhitespaceAndComments(input, identifier[1])[0];
+
+			const isTilde = input.charCodeAt(end) === CC_TILDE;
+
+			if (
+				input.charCodeAt(end) !== CC_EQUAL &&
+				input.charCodeAt(end) !== CC_TILDE
+			) {
+				return end;
+			}
+
+			end += 1;
+
+			if (isTilde) {
+				if (input.charCodeAt(end) !== CC_EQUAL) {
+					return end;
+				}
+
+				end += 1;
+			}
+
+			end = walkCssTokens.eatWhitespaceAndComments(input, end)[0];
+			const value = walkCssTokens.eatIdentSequenceOrString(input, end);
+
+			if (!value) {
+				return end;
+			}
+
+			const classNameStart = value[2] ? value[0] : value[0] + 1;
+			const classNameEnd = value[2] ? value[1] : value[1] - 1;
+			const className = unescapeIdentifier(
+				input.slice(classNameStart, classNameEnd)
+			);
+			const dep = new CssIcssExportDependency(
+				className,
+				getReexport(className),
+				[classNameStart, classNameEnd],
+				true,
+				CssIcssExportDependency.EXPORT_MODE.NONE
+			);
+			const { line: sl, column: sc } = locConverter.get(classNameStart);
+			const { line: el, column: ec } = locConverter.get(classNameEnd);
+			dep.setLoc(sl, sc, el, ec);
+			module.addDependency(dep);
+			return value[2] ? classNameEnd : classNameEnd + 1;
 		};
 
 		walkCssTokens(source, 0, {
@@ -1722,7 +2320,7 @@
 				return end;
 			},
 			url: (input, start, end, contentStart, contentEnd) => {
-				if (!this.url) {
+				if (!this.options.url) {
 					return end;
 				}
 
@@ -1749,9 +2347,32 @@
 
 						return eatUntilSemi(input, start);
 					}
+					case "@charset": {
+						const atRuleEnd = eatUntilSemi(input, start);
+
+						if (/** @type {CssModule} */ (module).exportType === "style") {
+							return atRuleEnd;
+						}
+
+						const dep = new ConstDependency("", [start, atRuleEnd + 1]);
+						module.addPresentationalDependency(dep);
+
+						const value = walkCssTokens.eatString(input, end);
+
+						if (!value) {
+							return atRuleEnd;
+						}
+
+						/** @type {BuildInfo} */
+						(module.buildInfo).charset = input
+							.slice(value[0] + 1, value[1] - 1)
+							.toUpperCase();
+
+						return atRuleEnd;
+					}
 					case "@import": {
-						if (!this.import) {
-							return eatSemi(input, end);
+						if (!this.options.import) {
+							return eatUntilSemi(input, end);
 						}
 
 						if (!allowImportAtRule) {
@@ -1762,7 +2383,7 @@
 								start,
 								end
 							);
-							return end;
+							return eatUntilSemi(input, end);
 						}
 
 						return processAtImport(input, start, end);
@@ -1772,6 +2393,7 @@
 							if (name === "@value") {
 								return processAtValue(input, start, end);
 							} else if (
+								this.options.animation &&
 								OPTIONALLY_VENDOR_PREFIXED_KEYFRAMES_AT_RULE.test(name) &&
 								isLocalMode()
 							) {
@@ -1779,11 +2401,21 @@
 									string: true,
 									identifier: true
 								});
-							} else if (name === "@property" && isLocalMode()) {
+							} else if (
+								this.options.customIdents &&
+								name === "@counter-style" &&
+								isLocalMode()
+							) {
 								return processLocalAtRule(input, end, {
-									identifier: true,
-									dashed: true,
-									validate: (name) => name.startsWith("--") && name.length >= 3
+									identifier: true
+								});
+							} else if (
+								this.options.container &&
+								name === "@container" &&
+								isLocalMode()
+							) {
+								return processLocalAtRule(input, end, {
+									identifier: /^(none|and|or|not)$/
 								});
 							} else if (name === "@scope") {
 								isNextRulePrelude = true;
@@ -1805,15 +2437,23 @@
 			},
 			identifier: (input, start, end) => {
 				if (isModules) {
-					const name = input.slice(start, end);
+					const identifier = input.slice(start, end);
 
-					if (icssDefinitions.has(name)) {
-						return processICSSSymbol(name, start, end);
+					if (
+						this.options.dashedIdents &&
+						isLocalMode() &&
+						isDashedIdentifier(identifier)
+					) {
+						return processDashedIdent(input, start, end);
+					}
+
+					if (icssDefinitions.has(identifier)) {
+						return processICSSSymbol(identifier, start, end);
 					}
 
 					switch (scope) {
 						case CSS_MODE_IN_BLOCK: {
-							if (isLocalMode()) {
+							if (isModules && !isNextRulePrelude) {
 								// Handle only top level values and not inside functions
 								return processLocalDeclaration(input, start, end);
 							}
@@ -1825,30 +2465,19 @@
 				return end;
 			},
 			delim: (input, start, end) => {
-				if (isNextRulePrelude && isLocalMode()) {
-					const ident = walkCssTokens.skipCommentsAndEatIdentSequence(
-						input,
-						end
-					);
-					if (!ident) return end;
-					const name = unescapeIdentifier(input.slice(ident[0], ident[1]));
-					lastLocalIdentifiers.push(name);
-					const dep = new CssIcssLocalIdentifierDependency(name, [
-						ident[0],
-						ident[1]
-					]);
-					const { line: sl, column: sc } = locConverter.get(ident[0]);
-					const { line: el, column: ec } = locConverter.get(ident[1]);
-					dep.setLoc(sl, sc, el, ec);
-					module.addDependency(dep);
-					return ident[1];
+				if (
+					input.charCodeAt(start) === CC_FULL_STOP &&
+					isNextRulePrelude &&
+					isLocalMode()
+				) {
+					return processClassSelector(input, start, end);
 				}
 
 				return end;
 			},
 			hash: (input, start, end, isID) => {
 				if (isNextRulePrelude && isLocalMode() && isID) {
-					return processHashID(input, start, end);
+					return processIdSelector(input, start, end);
 				}
 
 				return end;
@@ -1883,18 +2512,23 @@
 
 								if (isFn && name === "local") {
 									// Eat extra whitespace
-									const end = walkCssTokens.eatWhitespace(input, ident[1] + 1);
-									modeData = "local";
+									const end = walkCssTokens.eatWhitespaceAndComments(
+										input,
+										ident[1] + 1
+									)[0];
+									modeData = LOCAL_MODE;
 									const dep = new ConstDependency("", [start, end]);
 									module.addPresentationalDependency(dep);
-									balanced.push([":local", start, end]);
+									balanced.push([":local", start, end, true]);
 									return end;
 								} else if (name === "local") {
-									modeData = "local";
-									// Eat extra whitespace
-									end = walkCssTokens.eatWhitespace(input, ident[1]);
+									modeData = LOCAL_MODE;
+									const found = walkCssTokens.eatWhitespaceAndComments(
+										input,
+										ident[1]
+									);
 
-									if (ident[1] === end) {
+									if (!found[1]) {
 										this._emitWarning(
 											state,
 											`Missing whitespace after ':local' in '${input.slice(
@@ -1907,23 +2541,30 @@
 										);
 									}
 
+									end = walkCssTokens.eatWhitespace(input, ident[1]);
 									const dep = new ConstDependency("", [start, end]);
 									module.addPresentationalDependency(dep);
 									return end;
 								} else if (isFn && name === "global") {
 									// Eat extra whitespace
-									const end = walkCssTokens.eatWhitespace(input, ident[1] + 1);
-									modeData = "global";
+									const end = walkCssTokens.eatWhitespaceAndComments(
+										input,
+										ident[1] + 1
+									)[0];
+									modeData = GLOBAL_MODE;
 									const dep = new ConstDependency("", [start, end]);
 									module.addPresentationalDependency(dep);
-									balanced.push([":global", start, end]);
+									balanced.push([":global", start, end, true]);
 									return end;
 								} else if (name === "global") {
-									modeData = "global";
+									modeData = GLOBAL_MODE;
 									// Eat extra whitespace
-									end = walkCssTokens.eatWhitespace(input, ident[1]);
+									const found = walkCssTokens.eatWhitespaceAndComments(
+										input,
+										ident[1]
+									);
 
-									if (ident[1] === end) {
+									if (!found[1]) {
 										this._emitWarning(
 											state,
 											`Missing whitespace after ':global' in '${input.slice(
@@ -1936,6 +2577,7 @@
 										);
 									}
 
+									end = walkCssTokens.eatWhitespace(input, ident[1]);
 									const dep = new ConstDependency("", [start, end]);
 									module.addPresentationalDependency(dep);
 									return end;
@@ -1960,21 +2602,42 @@
 				switch (name) {
 					case "src":
 					case "url": {
-						if (!this.url) {
+						if (!this.options.url) {
 							return end;
 						}
 
 						return processURLFunction(input, end, name);
 					}
 					default: {
-						if (this.url && IMAGE_SET_FUNCTION.test(name)) {
+						if (this.options.url && IMAGE_SET_FUNCTION.test(name)) {
 							return processImageSetFunction(input, start, end);
-						} else if (isLocalMode() && name === "var") {
-							return processVarFunction(input, end);
+						}
+
+						if (isModules) {
+							if (
+								this.options.function &&
+								isLocalMode() &&
+								isDashedIdentifier(name)
+							) {
+								return processDashedIdent(input, start, end);
+							}
+
+							const type =
+								name === "local" ? 1 : name === "global" ? 2 : undefined;
+
+							if (type && !isNextRulePrelude) {
+								return processLocalOrGlobalFunction(input, type, start, end);
+							}
 						}
 					}
 				}
 
+				return end;
+			},
+			leftSquareBracket: (input, start, end) => {
+				if (isNextRulePrelude && isLocalMode()) {
+					return processAttributeSelector(input, start, end);
+				}
 				return end;
 			},
 			leftParenthesis: (input, start, end) => {
@@ -1985,29 +2648,35 @@
 			rightParenthesis: (input, start, end) => {
 				const popped = balanced.pop();
 
-				if (
-					isModules &&
-					popped &&
-					(popped[0] === ":local" || popped[0] === ":global")
-				) {
-					modeData = balanced[balanced.length - 1]
-						? /** @type {"local" | "global"} */
-							(balanced[balanced.length - 1][0])
-						: undefined;
-					const dep = new ConstDependency("", [start, end]);
-					module.addPresentationalDependency(dep);
+				if (isModules && popped) {
+					const isLocal = popped[0] === ":local";
+					const isGlobal = popped[0] === ":global";
+					if (isLocal || isGlobal) {
+						modeData = balanced[balanced.length - 1]
+							? balanced[balanced.length - 1][0] === ":local"
+								? LOCAL_MODE
+								: balanced[balanced.length - 1][0] === ":global"
+									? GLOBAL_MODE
+									: undefined
+							: undefined;
+						if (popped[3] && isLocal) {
+							while (walkCssTokens.isWhiteSpace(input.charCodeAt(start - 1))) {
+								start -= 1;
+							}
+						}
+						const dep = new ConstDependency("", [start, end]);
+						module.addPresentationalDependency(dep);
+					} else if (isNextRulePrelude) {
+						modeData = undefined;
+					}
 				}
 
 				return end;
 			},
 			comma: (input, start, end) => {
-				if (isModules) {
-					const popped = balanced.pop();
-
-					if (!popped) {
-						// Reset stack for `:global .class :local .class-other` selector after
-						modeData = undefined;
-					}
+				if (isModules && balanced.length === 0) {
+					// Reset stack for `:global .class :local .class-other` selector after
+					modeData = undefined;
 				}
 
 				lastTokenEndForComments = start;
@@ -2021,29 +2690,14 @@
 
 		const buildMeta = /** @type {BuildMeta} */ (state.module.buildMeta);
 
-		buildMeta.exportsType = this.namedExports ? "namespace" : "default";
-		buildMeta.defaultObject = this.namedExports ? false : "redirect-warn";
-		buildMeta.exportType = this.exportType;
+		buildMeta.exportsType = this.options.namedExports ? "namespace" : "default";
+		buildMeta.defaultObject = this.options.namedExports
+			? false
+			: "redirect-warn";
 
-		if (!buildMeta.exportType) {
-			// Inherit exportType from parent module to ensure consistency.
-			// When a CSS file is imported with syntax like `import "./basic.css" with { type: "css" }`,
-			// the parent module's exportType is set to "css-style-sheet".
-			// Child modules imported via @import should inherit this exportType
-			// instead of using the default "link", ensuring that the entire
-			// import chain uses the same export format.
-			const parent = state.compilation.moduleGraph.getIssuer(module);
-			if (parent instanceof CssModule) {
-				buildMeta.exportType = /** @type {BuildMeta} */ (
-					parent.buildMeta
-				).exportType;
-			}
-		}
-
-		// TODO this.namedExports?
 		if (
-			buildMeta.exportType === "text" ||
-			buildMeta.exportType === "css-style-sheet"
+			/** @type {CssModule} */ (module).exportType === "text" ||
+			/** @type {CssModule} */ (module).exportType === "css-style-sheet"
 		) {
 			module.addDependency(new StaticExportsDependency(["default"], true));
 		} else {
@@ -2054,6 +2708,7 @@
 	}
 
 	/**
+	 * Returns comments in the range.
 	 * @param {Range} range range
 	 * @returns {Comment[]} comments in the range
 	 */
@@ -2061,6 +2716,7 @@
 		if (!this.comments) return [];
 		const [rangeStart, rangeEnd] = range;
 		/**
+		 * Returns compared.
 		 * @param {Comment} comment comment
 		 * @param {number} needle needle
 		 * @returns {number} compared
@@ -2083,6 +2739,7 @@
 	}
 
 	/**
+	 * Parses comment options.
 	 * @param {Range} range range of the comment
 	 * @returns {{ options: Record<string, EXPECTED_ANY> | null, errors: (Error & { comment: Comment })[] | null }} result
 	 */
@@ -2091,7 +2748,7 @@
 		if (comments.length === 0) {
 			return EMPTY_COMMENT_OPTIONS;
 		}
-		/** @type {Record<string, EXPECTED_ANY> } */
+		/** @type {Record<string, EXPECTED_ANY>} */
 		const options = {};
 		/** @type {(Error & { comment: Comment })[]} */
 		const errors = [];

--
Gitblit v1.9.3