import * as dataTypes from "tailwindcss/lib/util/dataTypes.js";
import plugin from "tailwindcss/plugin.js";
import { componentsCSSProps, getCSSPropRawValue } from "./cssProps.js";
import { twToRem } from "./theme.js";
import { objectEntries } from "../../utils/objectEntries.js";
import { camelToKebab } from "../../utils/camelToKebab.js";
const customPlugin = plugin(function({
  theme,
  addBase,
  addComponents,
  addUtilities,
  matchComponents,
  matchUtilities,
  addVariant,
  matchVariant,
  e: escape
}) {
  const themeValues = {
    spacing: theme("spacing") ?? {},
    colors: theme("colors") ?? {},
    opacity: theme("opacity") ?? {},
    fontWeight: theme("fontWeight") ?? {},
    translate: theme("translate") ?? {},
    rotate: theme("rotate") ?? {},
    scale: theme("scale") ?? {},
    transitionDuration: theme("transitionDuration") ?? {},
    transitionDelay: theme("transitionDelay") ?? {},
    transitionTimingFunction: theme("transitionTimingFunction") ?? {}
  };
  addBase({
    ":root": {
      "--gds-color-black": "0 0 0",
      // #000000
      "--gds-color-white": "255 255 255",
      // #FFFFFF
      "--gds-color-space-100": "243 243 244",
      // #F3F3F4
      "--gds-color-space-200": "219 219 219",
      // #DBDBDB (TODO: Why is this one perfectly gray but not `space-100`?)
      "--gds-color-space-300": "197 196 198",
      // #C5C4C6
      "--gds-color-space-400": "182 181 185",
      // #B6B5B9
      "--gds-color-space-500": "167 165 174",
      // #A7A5AE
      "--gds-color-space-600": "145 143 157",
      // #918F9D
      "--gds-color-space-700": "132 129 146",
      // #848192
      "--gds-color-space-800": "117 114 133",
      // #757285
      "--gds-color-space-900": "102 99 120",
      // #666378
      "--gds-color-space-1000": "89 85 108",
      // #59556C
      "--gds-color-space-1100": "73 70 93",
      // #49465D
      "--gds-color-space-1200": "58 55 77",
      // #3A374D
      "--gds-color-space-1300": "45 42 63",
      // #2D2A3F
      "--gds-color-space-1400": "36 34 54",
      // #242236
      "--gds-color-space-1500": "29 26 48",
      // #1D1A30
      "--gds-color-space-1600": "22 19 42",
      // #16132A
      "--gds-color-space-1700": "12 10 29",
      // #0C0A1D
      "--gds-color-space-1800": "8 6 24",
      // #080618
      "--gds-color-purple-100": "226 219 255",
      // #E2DBFF
      "--gds-color-purple-200": "197 183 255",
      // #C5B7FF
      "--gds-color-purple-300": "169 148 255",
      // #A994FF
      "--gds-color-purple-400": "140 112 255",
      // #8C70FF
      "--gds-color-purple-500": "111 76 255",
      // #6F4CFF
      "--gds-color-purple-600": "101 69 232",
      // #6545E8
      "--gds-color-purple-700": "81 56 186",
      // #5138BA
      "--gds-color-purple-800": "61 43 140",
      // #3D2B8C
      "--gds-color-purple-900": "51 36 118",
      // #332476
      "--gds-color-purple-1000": "40 28 92",
      // #281C5C
      "--gds-color-purple-1100": "25 18 58",
      // #19123A
      "--gds-color-purple-1200": "20 15 47",
      // #140F2F
      "--gds-color-starfield-100": "219 244 230",
      // #DBF4E6
      "--gds-color-starfield-200": "183 234 205",
      // #B7EACD
      "--gds-color-starfield-300": "147 223 179",
      // #93DFB3
      "--gds-color-starfield-400": "111 213 154",
      // #6FD59A
      "--gds-color-starfield-500": "75 202 129",
      // #4BCA81
      "--gds-color-starfield-600": "62 163 108",
      // #3EA36C
      "--gds-color-starfield-700": "49 125 88",
      // #317D58
      "--gds-color-starfield-800": "37 86 67",
      // #255643
      "--gds-color-starfield-900": "24 48 47",
      // #18302F
      "--gds-color-starfield-1000": "17 34 33",
      // #112221
      "--gds-color-starfield-1100": "14 27 27",
      // #0E1B1B
      "--gds-color-solar-100": "255 238 204",
      // #FFEECC
      "--gds-color-solar-200": "255 220 153",
      // #FFDC99
      "--gds-color-solar-300": "255 203 103",
      // #FFCB67
      "--gds-color-solar-400": "255 185 52",
      // #FFB934
      "--gds-color-solar-500": "255 168 1",
      // #FFA801
      "--gds-color-solar-600": "206 136 6",
      // #CE8806
      "--gds-color-solar-700": "157 104 11",
      // #9D680B
      "--gds-color-solar-800": "109 73 16",
      // #6D4910
      "--gds-color-solar-900": "60 41 21",
      // #3C2915
      "--gds-color-solar-1000": "39 27 27",
      // #271B1B
      "--gds-color-solar-1100": "29 22 26",
      // #1D161A
      "--gds-color-sonja-100": "251 219 226",
      // #FBDBE2
      "--gds-color-sonja-200": "248 183 197",
      // #F8B7C5
      "--gds-color-sonja-300": "244 146 167",
      // #F492A7
      "--gds-color-sonja-400": "241 110 138",
      // #F16E8A
      "--gds-color-sonja-500": "237 74 109",
      // #ED4A6D
      "--gds-color-sonja-600": "192 61 92",
      // #C03D5C
      "--gds-color-sonja-700": "147 48 76",
      // #93304C
      "--gds-color-sonja-800": "101 35 59",
      // #65233B
      "--gds-color-sonja-900": "56 22 43",
      // #38162B
      "--gds-color-sonja-1000": "37 14 37",
      // #250E25
      "--gds-color-sonja-1100": "24 11 29",
      // #180B1D
      "--gds-color-galactic-100": "219 236 255",
      // #DBECFF
      "--gds-color-galactic-200": "183 216 255",
      // #B7D8FF
      "--gds-color-galactic-300": "148 197 255",
      // #94C5FF
      "--gds-color-galactic-400": "112 177 255",
      // #70B1FF
      "--gds-color-galactic-500": "76 158 255",
      // #4C9EFF
      "--gds-color-galactic-600": "63 128 209",
      // #3F80D1
      "--gds-color-galactic-700": "50 98 163",
      // #3262A3
      "--gds-color-galactic-800": "37 69 118",
      // #254576
      "--gds-color-galactic-900": "24 39 72",
      // #182748
      "--gds-color-galactic-1000": "15 25 46",
      // #0F192E
      "--gds-color-galactic-1100": "13 21 38",
      // #0D1526
      "--gds-color-astro-100": "219 224 255",
      // #DBE0FF
      "--gds-color-astro-200": "183 194 255",
      // #B7C2FF
      "--gds-color-astro-300": "148 163 255",
      // #94A3FF
      "--gds-color-astro-400": "112 133 255",
      // #7085FF
      "--gds-color-astro-500": "76 102 255",
      // #4C66FF
      "--gds-color-astro-600": "63 83 209",
      // #3F53D1
      "--gds-color-astro-700": "50 65 163",
      // #3241A3
      "--gds-color-astro-800": "37 46 118",
      // #252E76
      "--gds-color-astro-900": "24 28 72",
      // #181C48
      "--gds-color-focus": "111 76 255",
      // same as `purple-500`
      "--gds-color-white-4": "22 20 38",
      // #161426,
      "--gds-color-white-8": "32 30 48",
      // #201E30,
      "--gds-color-white-12": "42 39 57",
      // #2A2739,
      "--gds-color-midnight": "12 10 29",
      // #0C0A1D
      "--gds-color-midnight-dark": "12 10 25",
      // #0C0A19,
      "--gds-color-purple": "111 76 255",
      // #6F4CFF
      "--gds-color-blue": "76 102 255",
      // #4C66FF
      "--gds-color-turquoise": "102 216 255",
      // #66D8FF
      "--gds-color-green": "75 202 129",
      // #4BCA81
      "--gds-color-yellow": "255 168 1",
      // #FFA801
      "--gds-color-red": "237 74 109",
      // #ED4A6D
      "--gds-color-pink": "255 121 198",
      // #FF79C6
      "--gds-color-gray": "73 71 85",
      // #494755
      "--gds-color-overlay": "27 24 52"
      // #1B1834
    }
  });
  addUtilities(
    Object.fromEntries(
      Object.entries(themeValues.fontWeight).map(([key, value]) => [
        `.font-${key}`,
        { fontWeight: value, "--gds-font-weight": value }
      ])
    )
  );
  addUtilities({
    ".italic": {
      fontStyle: "italic",
      fontVariationSettings: '"slnt" -11, "ital" 1'
    },
    ".not-italic": {
      fontStyle: "normal",
      fontVariationSettings: "initial"
    }
  });
  addComponents({
    ".text-h128": {
      "@apply font-sans font-medium text-128 text-balance": ""
    },
    ".text-h96": {
      "@apply font-sans font-medium text-96 text-balance": ""
    },
    ".text-h64": {
      "@apply font-sans font-medium text-64 text-balance": ""
    },
    ".text-h48": {
      "@apply font-sans font-medium text-48 text-balance": ""
    },
    ".text-h40": {
      "@apply font-sans font-medium text-40 text-balance": ""
    },
    ".text-h32": {
      "@apply font-sans font-medium text-32 text-balance": ""
    },
    ".text-h24": {
      "@apply font-sans font-medium text-24 text-balance": ""
    },
    ".text-h20": {
      "@apply font-sans font-medium text-20 text-balance": ""
    },
    ".text-h18": {
      "@apply font-sans font-medium text-18 text-balance": ""
    },
    ".text-h16": {
      "@apply font-sans font-medium text-16 text-balance": ""
    },
    ".text-h14": {
      "@apply font-sans font-medium text-14 text-balance": ""
    },
    ".text-h12": {
      "@apply font-sans font-medium text-12 text-balance": ""
    },
    ".text-p32": {
      "@apply font-sans font-regular text-32 text-pretty": ""
    },
    ".text-p24": {
      "@apply font-sans font-regular text-24 text-pretty": ""
    },
    ".text-p20": {
      "@apply font-sans font-regular text-20 text-pretty": ""
    },
    ".text-p18": {
      "@apply font-sans font-regular text-18 text-pretty": ""
    },
    ".text-p16": {
      "@apply font-sans font-regular text-16 text-pretty": ""
    },
    ".text-p14": {
      "@apply font-sans font-regular text-14 text-pretty": ""
    },
    ".text-p12": {
      "@apply font-sans font-regular text-12 text-pretty": ""
    },
    ".text-c16": {
      "@apply font-sans font-medium text-16 leading-6 uppercase tracking-caption": ""
    },
    ".text-c14": {
      "@apply font-sans font-medium text-14 leading-5 uppercase tracking-caption": ""
    },
    ".text-c12": {
      "@apply font-sans font-medium text-12 uppercase tracking-caption": ""
    },
    ".text-c10": {
      "@apply font-sans font-medium text-10 uppercase tracking-caption": ""
    },
    ".text-m20": {
      "@apply font-mono font-regular text-20": ""
    },
    ".text-m18": {
      "@apply font-mono font-regular text-18": ""
    },
    ".text-m16": {
      "@apply font-mono font-regular text-16": ""
    },
    ".text-m14": {
      "@apply font-mono font-regular text-14": ""
    },
    ".text-m12": {
      "@apply font-mono font-regular text-12": ""
    }
  });
  addUtilities({
    ".pointer-events-none > *": {
      "--gds-pointer-events": "none"
    },
    ".pointer-events-auto > *": {
      "--gds-pointer-events": "auto"
    },
    ".pointer-events-none": {
      "--gds-previous-pointer-events": "var(--gds-pointer-events)",
      "pointer-events": "none"
    },
    ".pointer-events-auto": {
      "--gds-previous-pointer-events": "var(--gds-pointer-events)",
      "pointer-events": "auto"
    },
    ".pointer-events-previous": {
      "--gds-previous-pointer-events": "revert",
      "--gds-pointer-events": "var(--gds-previous-pointer-events)",
      "pointer-events": "var(--gds-pointer-events)"
    }
  });
  const animateKeyframes = ["from", "via", "to"];
  const animateProperties = {
    color: {
      propertyName: "color",
      type: "color",
      values: themeValues.colors,
      defaultValue: "currentColor"
    },
    bg: {
      propertyName: "background-color",
      type: "color",
      values: themeValues.colors,
      defaultValue: "transparent"
    },
    border: {
      propertyName: "border-color",
      type: "color",
      values: themeValues.colors,
      defaultValue: "transparent"
    },
    outline: {
      propertyName: "outline-color",
      type: "color",
      values: themeValues.colors,
      defaultValue: "transparent"
    },
    opacity: {
      propertyName: "opacity",
      values: themeValues.opacity,
      defaultValue: "1"
    },
    "translate-x": {
      propertyName: "transform",
      values: themeValues.translate,
      defaultValue: "0"
    },
    "translate-y": {
      propertyName: "transform",
      values: themeValues.translate,
      defaultValue: "0"
    },
    rotate: {
      propertyName: "transform",
      values: themeValues.rotate,
      defaultValue: "0"
    },
    scale: {
      propertyName: "transform",
      values: themeValues.scale,
      defaultValue: "1",
      isShorthandFor: ["scale-x", "scale-y"]
    },
    "scale-x": {
      propertyName: "transform",
      values: themeValues.scale,
      defaultValue: "1"
    },
    "scale-y": {
      propertyName: "transform",
      values: themeValues.scale,
      defaultValue: "1"
    }
  };
  const animationsToGenerate = objectEntries(animateProperties).reduce(
    (result, [propertyShortName, property]) => {
      if (property.propertyName !== "transform" && !("isShorthandFor" in property)) {
        return [...result, propertyShortName];
      }
      return result;
    },
    ["", "transform"]
  );
  animationsToGenerate.forEach((animation) => {
    const variantsToGenerate = ["", "with-via"];
    variantsToGenerate.forEach((variant) => {
      const keyframes = variant === "with-via" ? {
        "0%": "from",
        "50%": "via",
        "100%": "to"
      } : {
        "0%": "from",
        "100%": "to"
      };
      const propertiesToAnimate = animation === "" ? animationsToGenerate.filter((animation2) => animation2 !== "") : [animation];
      addBase({
        [`@keyframes gds-animate${animation ? `-${animation}` : ""}${variant ? `-${variant}` : ""}`]: Object.fromEntries(
          Object.entries(keyframes).map(([keyframePercentage, keyframe]) => [
            keyframePercentage,
            Object.fromEntries(
              propertiesToAnimate.map((propertyToAnimate) => {
                const propertyName = propertyToAnimate === "transform" ? "transform" : animateProperties[propertyToAnimate].propertyName;
                const propertyValue = propertyToAnimate === "transform" ? `translate(var(--gds-animate-translate-x-${keyframe}), var(--gds-animate-translate-y-${keyframe})) rotate(var(--gds-animate-rotate-${keyframe})) scaleX(var(--gds-animate-scale-x-${keyframe})) scaleY(var(--gds-animate-scale-y-${keyframe}))` : `var(--gds-animate-${propertyToAnimate}-${keyframe})`;
                return [propertyName, propertyValue];
              })
            )
          ])
        )
      });
    });
  });
  objectEntries(animateProperties).forEach(([propertyShortName, property]) => {
    animateKeyframes.forEach((keyframe) => {
      addBase({
        [`@property --gds-animate-${propertyShortName}-${keyframe}`]: {
          syntax: `"*"`,
          inherits: "false",
          "initial-value": property.defaultValue
        }
      });
      const animationSuffix = keyframe === "via" ? "-with-via" : "";
      matchComponents(
        {
          [`animate-${propertyShortName}-${keyframe}`]: (value) => {
            return {
              ...Object.fromEntries(
                (property.isShorthandFor ?? [propertyShortName]).map((propertyToAnimate) => [
                  `--gds-animate-${propertyToAnimate}-${keyframe}`,
                  value
                ])
              ),
              [`--gds-animate-animation${animationSuffix}`]: `gds-animate-${property.propertyName === "transform" ? "transform" : propertyShortName}${animationSuffix}`,
              animation: `var(--gds-animate-animation-with-via, var(--gds-animate-animation)) var(--gds-animate-duration, 1s) var(--gds-animate-timing-function, ${themeValues.transitionTimingFunction.DEFAULT})`
            };
          }
        },
        {
          type: property.type ?? "any",
          values: property.values
        }
      );
    });
  });
  addUtilities({
    ".animate": {
      "--gds-animate-animation": "gds-animate"
    },
    ".animate-with-via": {
      "--gds-animate-animation-with-via": "gds-animate-with-via"
    },
    ".animate-running": {
      animationPlayState: "running"
    },
    ".animate-paused": {
      animationPlayState: "paused"
    },
    ".animate-normal": {
      animationDirection: "normal"
    },
    ".animate-reverse": {
      animationDirection: "reverse"
    },
    ".animate-alternate": {
      animationDirection: "alternate"
    },
    ".animate-fill-none": {
      animationFillMode: "none"
    },
    ".animate-fill-forwards": {
      animationFillMode: "forwards"
    },
    ".animate-fill-backwards": {
      animationFillMode: "backwards"
    },
    ".animate-fill-both": {
      animationFillMode: "both"
    }
  });
  matchUtilities(
    {
      "animate-duration": (value) => ({
        animationDuration: value,
        "--gds-animate-duration": value
      })
    },
    {
      values: themeValues.transitionDuration
    }
  );
  matchUtilities(
    {
      "animate-delay": (value) => ({
        animationDelay: value
      })
    },
    {
      values: themeValues.transitionDelay
    }
  );
  matchUtilities(
    {
      "animate-ease": (value) => ({
        animationTimingFunction: value,
        "--gds-animate-timing-function": value
      })
    },
    {
      values: themeValues.transitionTimingFunction
    }
  );
  matchUtilities(
    {
      "animate-repeat": (value) => ({
        animationIterationCount: value
      })
    },
    {
      values: {
        "1": "1",
        infinite: "infinite"
      }
    }
  );
  addUtilities({
    // The default `outline-none` resets the outline width and offset to 2px, which are not the values we want (see `globalStyles.css`)
    ".outline-none": {
      outline: "1px solid transparent",
      outlineOffset: "1px"
    },
    // TODO: Remove after Tailwind 4 upgrade
    ".transition-allow-discrete": {
      transitionBehavior: "allow-discrete"
    },
    ".transition-behavior-normal": {
      transitionBehavior: "normal"
    },
    // TODO: After Tailwind 4 upgrade, remove when this PR is merged and released: https://github.com/tailwindlabs/tailwindcss/pull/14183
    ".scrollbar-none": {
      scrollbarWidth: "none",
      "&::-webkit-scrollbar": {
        display: "none"
      }
    },
    ".scrollbar-thin": {
      scrollbarWidth: "thin"
    },
    ".scrollbar-width-auto": {
      scrollbarWidth: "auto"
    }
  });
  addComponents({
    ".border-bg": {
      "@apply border-transparent bg-origin-border": "",
      "mask-image": "linear-gradient(#fff 0 0), linear-gradient(#fff 0 0)",
      "mask-clip": "padding-box, border-box",
      "mask-composite": "exclude, exclude"
    },
    ".gradient-mask-x": {
      "@keyframes gradient-mask-left": {
        "from, to": { "--gds-gradient-mask-left": "transparent" }
      },
      "@keyframes gradient-mask-right": {
        "from, to": { "--gds-gradient-mask-right": "transparent" }
      },
      "--gds-gradient-mask-left": "black",
      "--gds-gradient-mask-right": "black",
      "--gds-gradient-mask-size": "32px",
      animation: "gradient-mask-left linear, gradient-mask-right linear",
      "animation-timeline": "scroll(x self), scroll(x self)",
      "animation-range": "1px 100%, 0 calc(100% - 1px)",
      "mask-image": "linear-gradient(to right, var(--gds-gradient-mask-left), black var(--gds-gradient-mask-size), black calc(100% - var(--gds-gradient-mask-size)), var(--gds-gradient-mask-right))"
    },
    ".gradient-mask-y": {
      "@keyframes gradient-mask-top": {
        "from, to": { "--gds-gradient-mask-top": "transparent" }
      },
      "@keyframes gradient-mask-bottom": {
        "from, to": { "--gds-gradient-mask-bottom": "transparent" }
      },
      "--gds-gradient-mask-top": "black",
      "--gds-gradient-mask-bottom": "black",
      "--gds-gradient-mask-size": "32px",
      animation: "gradient-mask-top linear, gradient-mask-bottom linear",
      "animation-timeline": "scroll(y self), scroll(y self)",
      "animation-range": "1px 100%, 0 calc(100% - 1px)",
      "mask-image": "linear-gradient(to bottom, var(--gds-gradient-mask-top), black var(--gds-gradient-mask-size), black calc(100% - var(--gds-gradient-mask-size)), var(--gds-gradient-mask-bottom))"
    }
  });
  matchUtilities(
    {
      "gradient-mask": (value) => ({
        "--gds-gradient-mask-size": value
      })
    },
    {
      values: themeValues.spacing
    }
  );
  const enabled = `:not(:disabled, [aria-disabled='true'])`;
  const disabled = `:is(:disabled, [aria-disabled='true'])`;
  const clickable = `:is(:where(a[href], [role='link'], button, [role='button'])${enabled}, label:has(:where(input[type='checkbox'], input[type='radio']:not(:checked))${enabled}))`;
  const variants = {
    first: "&:first-child",
    last: "&:last-child",
    only: "&:only-child",
    odd: "&:nth-child(odd)",
    even: "&:nth-child(even)",
    "first-of-type": "&:first-of-type",
    "last-of-type": "&:last-of-type",
    "only-of-type": "&:only-of-type",
    target: "&:target",
    open: "&[open]",
    default: "&:default",
    checked: "&:checked",
    indeterminate: "&:indeterminate",
    "placeholder-shown": "&:placeholder-shown",
    autofill: "&:autofill",
    optional: "&:optional",
    required: "&:required",
    valid: "&:valid",
    invalid: "&:invalid",
    "in-range": "&:in-range",
    "out-of-range": "&:out-of-range",
    "read-only": "&:read-only",
    empty: "&:empty",
    "hocus-within": "&:is(:hover, :focus-within)",
    // custom
    "hocus-visible-within": "&:is(:hover, :has(:focus-visible))",
    // custom
    hocus: "&:is(:hover, :focus)",
    // custom
    "hocus-visible": "&:is(:hover, :focus-visible)",
    // custom
    "focus-within": "&:focus-within",
    "focus-visible-within": "&:has(:focus-visible)",
    // custom
    hover: "&:hover",
    focus: "&:focus",
    "focus-visible": `&:focus-visible`,
    active: "&:active",
    enabled: `&${enabled}`,
    // overridden, default is `:enabled`
    disabled: `&${disabled}`,
    // overridden, default is `:disabled`
    // All the following are custom
    inert: "&[inert]",
    "icon-only": "&:is(.gds-icon, .gds-Icon):where(:only-child:not(.gds-icon *))",
    // `gds-Icon` is for legacy interoperability
    clickable: `&${clickable}`,
    "clickable-hocus-within": `&${clickable}:is(:hover, :focus-within)`,
    "clickable-hocus-visible-within": `&${clickable}:is(:hover, :has(:focus-visible))`,
    "clickable-hocus": `&${clickable}:is(:hover, :focus)`,
    "clickable-hocus-visible": `&${clickable}:is(:hover, :focus-visible)`,
    "clickable-focus-within": `&${clickable}:focus-within`,
    "clickable-focus-visible-within": `&${clickable}:has(:focus-visible)`,
    "clickable-hover": `&${clickable}:hover`,
    "clickable-focus": `&${clickable}:focus`,
    "clickable-focus-visible": `&${clickable}:focus-visible`,
    "clickable-active": `&${clickable}:active`
  };
  const normalizeSelector = (selector) => {
    let normalizedSelector = dataTypes.normalize(selector);
    if (normalizedSelector.startsWith("&")) {
      normalizedSelector = normalizedSelector.slice(1);
    }
    return normalizedSelector.trim();
  };
  const is = (selector) => {
    const normalizedSelector = normalizeSelector(selector);
    if (/^[+~>]/.test(normalizedSelector)) {
      return normalizedSelector;
    }
    return normalizedSelector ? `:is(${normalizedSelector})` : "";
  };
  const isNot = (selector) => {
    const normalizedSelector = normalizeSelector(selector);
    return normalizedSelector ? `:not(${normalizedSelector})` : "";
  };
  const normalizeAttributeSelector = (attributeSelector) => {
    return dataTypes.normalizeAttributeSelectors(dataTypes.normalize(attributeSelector));
  };
  const groupSelector = (modifier) => modifier ? `.${escape(`group/${modifier}`)}` : ".group";
  const nestedSelector = (modifier) => modifier ? `.${escape(`nested/${modifier}`)}` : "";
  const valuesDefault = { values: { DEFAULT: "" } };
  const valuesVariants = { values: variants };
  const valuesVariantsWithDefault = { values: { DEFAULT: "", ...variants } };
  const valuesVariantsExceptClickable = {
    values: Object.fromEntries(objectEntries(variants).filter(([variant]) => !variant.startsWith("clickable")))
  };
  const valuesVariantsExceptClickableWithDefault = { values: { DEFAULT: "", ...valuesVariantsExceptClickable.values } };
  const undocumentedAddVariant = addVariant;
  undocumentedAddVariant("hocus-within", variants["hocus-within"], { before: "focus-within" });
  undocumentedAddVariant("hocus-visible-within", variants["hocus-visible-within"], { before: "focus-within" });
  undocumentedAddVariant("hocus", variants["hocus"], { before: "focus-within" });
  undocumentedAddVariant("hocus-visible", variants["hocus-visible"], { before: "focus-within" });
  undocumentedAddVariant("focus-visible", variants["focus-visible"], { before: "active" });
  undocumentedAddVariant("focus-visible-within", variants["focus-visible-within"], { before: "active" });
  addVariant("enabled", variants["enabled"]);
  addVariant("disabled", variants["disabled"]);
  addVariant("inert", variants["inert"]);
  addVariant("icon-only", variants["icon-only"]);
  matchVariant("clickable", (selector) => `&${clickable}${is(selector)}`, valuesVariantsExceptClickableWithDefault);
  matchVariant("clickable-not", (selector) => `&${clickable}${isNot(selector)}`, valuesVariantsExceptClickable);
  addVariant("**", "& *");
  addVariant("starting", "@starting-style");
  addVariant("can-hover", "@media (hover: hover)");
  addVariant("cannot-hover", "@media (hover: none)");
  addVariant("safari", "@supports (-webkit-hyphens: none)");
  addVariant("not-safari", "@supports not (-webkit-hyphens: none)");
  addVariant("firefox", "@supports (-moz-orient: inline)");
  addVariant("not-firefox", "@supports not (-moz-orient: inline)");
  addVariant("-", "html :where(&)");
  addVariant("--", ":where(&)");
  matchVariant("is", (selector) => `&${is(selector)}`, valuesVariants);
  matchVariant("not", (selector) => `&${isNot(selector)}`, valuesVariants);
  matchVariant("not-data", (attributeSelector) => `&:not([data-${normalizeAttributeSelector(attributeSelector)}])`);
  matchVariant("in", (selector) => `&:is(${is(selector)} *)`, valuesVariantsExceptClickable);
  matchVariant("not-in", (selector) => `&:not(${is(selector)} *)`, valuesVariantsExceptClickable);
  matchVariant(
    "in-clickable",
    (selector) => `&:is(${clickable}${is(selector)} *)`,
    valuesVariantsExceptClickableWithDefault
  );
  matchVariant(
    "in-clickable-not",
    (selector) => `&:is(${clickable}${isNot(selector)} *)`,
    valuesVariantsExceptClickable
  );
  matchVariant(
    "not-in-clickable",
    (selector) => `&:not(${clickable}${is(selector)} *)`,
    valuesVariantsExceptClickableWithDefault
  );
  matchVariant("has", (selector) => `&:has(${is(selector)})`, valuesVariantsExceptClickable);
  matchVariant("not-has", (selector) => `&:not(:has(${is(selector)}))`, valuesVariantsExceptClickable);
  matchVariant(
    "has-clickable",
    (selector) => `&:has(${clickable}${is(selector)})`,
    valuesVariantsExceptClickableWithDefault
  );
  matchVariant(
    "has-clickable-not",
    (selector) => `&:has(${clickable}${isNot(selector)})`,
    valuesVariantsExceptClickable
  );
  matchVariant(
    "not-has-clickable",
    (selector) => `&:not(:has(${clickable}${is(selector)}))`,
    valuesVariantsExceptClickableWithDefault
  );
  matchVariant("group", (selector, { modifier }) => `&:is(${groupSelector(modifier)}${is(selector)} *)`, valuesVariants);
  matchVariant(
    "group-not",
    (selector, { modifier }) => `&:is(${groupSelector(modifier)}${isNot(selector)} *)`,
    valuesVariants
  );
  matchVariant(
    "group-not-data",
    (attributeSelector, { modifier }) => `&:is(${groupSelector(modifier)}:not([data-${normalizeAttributeSelector(attributeSelector)}]) *)`
  );
  matchVariant(
    "in-group",
    (selector, { modifier }) => selector !== "" ? null : `&:is(${groupSelector(modifier)} *)`,
    valuesDefault
  );
  matchVariant(
    "not-in-group",
    (selector, { modifier }) => `&:not(${groupSelector(modifier)}${is(selector)} *)`,
    valuesVariantsWithDefault
  );
  matchVariant(
    "not-in-group-data",
    (attributeSelector, { modifier }) => `&:not(${groupSelector(modifier)}[data-${normalizeAttributeSelector(attributeSelector)}] *)`
  );
  matchVariant(
    "group-has",
    (selector, { modifier }) => `&:is(${groupSelector(modifier)}:has(${is(selector)}) *)`,
    valuesVariants
  );
  matchVariant(
    "group-not-has",
    (selector, { modifier }) => `&:is(${groupSelector(modifier)}:not(:has(${is(selector)})) *)`,
    valuesVariants
  );
  matchVariant(
    "nested",
    (selector, { modifier }) => !selector && !modifier ? null : `& :merge(${nestedSelector(modifier)})${is(selector)}`,
    valuesVariantsWithDefault
  );
  matchVariant(
    "nested-not",
    (selector, { modifier }) => `& :merge(${nestedSelector(modifier)})${isNot(selector)}`,
    valuesVariants
  );
  matchVariant(
    "has-nested",
    (selector, { modifier }) => !selector && !modifier ? null : `&:has(${nestedSelector(modifier)}${is(selector)})`,
    valuesVariantsWithDefault
  );
  matchVariant(
    "has-nested-not",
    (selector, { modifier }) => `&:has(${nestedSelector(modifier)}${isNot(selector)})`,
    valuesVariants
  );
  matchVariant(
    "group-has-nested",
    (selector, { modifier }) => !selector && !modifier ? null : `&:is(${groupSelector(modifier)}:has(${nestedSelector(modifier)}${is(selector)}) *)`,
    valuesVariantsWithDefault
  );
  matchVariant(
    "group-has-nested-not",
    (selector, { modifier }) => `&:is(${groupSelector(modifier)}:has(${nestedSelector(modifier)}${isNot(selector)}) *)`,
    valuesVariants
  );
  matchVariant(
    "nearest-group",
    (selector, { modifier }) => `@scope (${groupSelector(modifier)}) to (${groupSelector(modifier)}) { &:is(:scope${is(selector)} *) }`,
    valuesVariants
  );
  matchVariant(
    "nearest-group-not",
    (selector, { modifier }) => `@scope (${groupSelector(modifier)}) to (${groupSelector(modifier)}) { &:is(:scope${isNot(selector)} *) }`,
    valuesVariants
  );
  for (let i = 1; i <= 5; i++) {
    addVariant("+".repeat(i), `&:is(:is(:scope, ${"#i".repeat(i)}) *)`);
  }
  matchUtilities(
    {
      "@container-style": (_, { modifier }) => modifier ? { "container-name": modifier } : null
    },
    {
      values: { DEFAULT: "" },
      modifiers: "any"
    }
  );
  matchVariant(
    "@style",
    (condition, { modifier }) => `@container ${modifier ?? ""} style(${condition.replace("=", ":")})`
  );
  const componentsCSSPropsByPropName = objectEntries(componentsCSSProps).reduce((result, [componentName, props]) => {
    Object.entries(props).forEach(([propName, prop]) => {
      if (!result[propName]) {
        result[propName] = {};
      }
      result[propName][componentName] = prop;
    });
    return result;
  }, {});
  const propNames = Object.keys(componentsCSSPropsByPropName);
  propNames.forEach((propName) => {
    const kebabCasePropName = camelToKebab(propName);
    addBase({
      [`@property --gds-default-${kebabCasePropName}`]: {
        syntax: `"*"`,
        inherits: "false"
      },
      [`@property --gds-passed-${kebabCasePropName}`]: {
        syntax: `"*"`,
        inherits: "false"
      },
      [`@property --gds-prop-${kebabCasePropName}`]: {
        syntax: `"*"`,
        inherits: "false"
      }
    });
  });
  Object.entries(componentsCSSProps).forEach(([componentName, props]) => {
    Object.entries(props).forEach(([propName, prop]) => {
      const kebabCasePropName = camelToKebab(propName);
      addBase({
        [`@property --gds-${componentName}-${kebabCasePropName}`]: {
          syntax: (() => {
            switch (prop.type) {
              case "values":
                return `"${prop.values.map((value) => `gds-${value}`).join(" | ")}"`;
              case "length":
                return `"<length-percentage>"`;
              case "color":
                return `"<color>"`;
            }
          })(),
          /**
           * We want this to inherit to access the value on nested elements, especially for non-`values` props (since `values` props are not
           * usually accessed on nested elements other than through style queries, which doesn't require the property to inherit - though it's
           * still useful for the CSS props polyfill; see `polyfillElementStyle`). There are two downsides to this, which seem acceptable:
           * 1. Performance is slightly worse, but non-registered custom properties always inherit and people don't hesitate to use them.
           * 2. An invalid value will fall back to the parent's value instead of the initial value. However, this is very much an edge case
           * because an invalid value is a mistake in the first place, and most of the time that exact custom property won't be set on the
           * parent anyway (there would have to be an ancestor that is the same component, which rarely makes sense).
           */
          inherits: "true",
          "initial-value": (() => {
            if (prop.type === "length" && typeof prop.defaultValue === "string" && /(cap|ch|em|ex|ic|lh)$/.test(prop.defaultValue)) {
              return "100%";
            }
            return getCSSPropRawValue(prop, prop.defaultValue);
          })()
        }
      });
    });
    addComponents({
      [`.gds-${componentName}`]: {
        [`@apply @container-style/${componentName}`]: "",
        "@apply [--style-queries-test:testing]": "",
        ...Object.entries(props).reduce((rules, [propName, prop]) => {
          const kebabCasePropName = camelToKebab(propName);
          const defaultValue = prop.type === "length" ? `[${typeof prop.defaultValue === "number" ? twToRem(prop.defaultValue) : prop.defaultValue}]` : prop.defaultValue;
          return {
            ...rules,
            [`@apply --:default-${kebabCasePropName}-${defaultValue}`]: "",
            // setting `--gds-default-<prop>` to the default value
            [`@apply --:prop-${kebabCasePropName}-[var(--gds-passed-${kebabCasePropName},var(--gds-default-${kebabCasePropName}))]`]: "",
            // setting `--gds-prop-<prop>` to `--gds-passed-<prop>` if it exists, otherwise `--gds-default-<prop>`
            [`@apply [--gds-${componentName}-${kebabCasePropName}:var(--gds-prop-${kebabCasePropName})]`]: ""
            // setting `--gds-<component>-<prop>` to `--gds-prop-<prop>`
          };
        }, {})
      }
    });
  });
  Object.entries(componentsCSSPropsByPropName).forEach(([propName, components]) => {
    const kebabCasePropName = camelToKebab(propName);
    const propTypes = Object.values(components).map((componentProps) => componentProps.type);
    const propValues = Object.values(components).flatMap((componentProps) => componentProps.values ?? []).map(String);
    const matchUtilitiesType = ["any"];
    if (propTypes.includes("length")) {
      matchUtilitiesType.unshift("length");
    }
    if (propTypes.includes("color")) {
      matchUtilitiesType.unshift("color");
    }
    const matchUtilitiesValues = {};
    if (propTypes.includes("values")) {
      propValues.forEach((value) => {
        matchUtilitiesValues[value] = value;
      });
    }
    if (propTypes.includes("length")) {
      Object.entries(themeValues.spacing).forEach(([key, value]) => {
        matchUtilitiesValues[key] = value;
      });
    }
    if (propTypes.includes("color")) {
      Object.entries(themeValues.colors).forEach(([key, value]) => {
        matchUtilitiesValues[key] = value;
      });
    }
    matchUtilities(
      Object.fromEntries(
        ["prop", "default"].map((utilityType) => [
          `${utilityType}-${kebabCasePropName}`,
          (value) => ({
            [`--gds-${utilityType}-${kebabCasePropName}`]: (
              // Prefix `values` with `gds-` because cssnano (which Next.js uses) incorrectly minifies `--gds-prop-variant: white` to `--gds-prop-variant: #fff`
              propTypes.includes("values") && propValues.indexOf(value) !== -1 ? `gds-${value}` : value
            ),
            [`--gds-${utilityType}-polyfill-${kebabCasePropName}`]: propTypes.includes("values") ? propValues.indexOf(value) + 1 + "px" : null
          })
        ])
      ),
      {
        type: matchUtilitiesType,
        values: matchUtilitiesValues
      }
    );
  });
  const componentNames = Object.keys(componentsCSSProps);
  componentNames.forEach((componentName) => {
    addVariant(`nested-${componentName}`, `& :merge(.gds-${componentName})`);
    addVariant(`in-${componentName}`, `&:is(.gds-${componentName} *)`);
    addVariant(`not-in-${componentName}`, `&:not(.gds-${componentName} *)`);
    addVariant(`has-${componentName}`, `&:has(.gds-${componentName})`);
    addVariant(`not-has-${componentName}`, `&:not(:has(.gds-${componentName}))`);
  });
  const undocumentedMatchVariant = matchVariant;
  undocumentedMatchVariant(
    "@prop",
    (kebabCasePropNameAndValue, { modifier: componentName, container: postCssContainer }) => {
      if (!Array.isArray(kebabCasePropNameAndValue) || !componentName || !componentNames.includes(componentName))
        return [];
      const [kebabCasePropName, value] = kebabCasePropNameAndValue;
      const selectors = [];
      const postCssContainerString = String(postCssContainer);
      const isNewSelector = !postCssContainerString.includes("__not_new");
      const isExistingStyleQuerySelector = !isNewSelector && componentNames.some((componentName2) => postCssContainerString.startsWith(`@container ${componentName2} style(`));
      const isExistingPolyfillSelector = !isNewSelector && !isExistingStyleQuerySelector;
      if (isNewSelector || isExistingStyleQuerySelector) {
        selectors.push(
          // Prefix the value with `gds-` because cssnano (which Next.js uses) incorrectly minifies `--gds-prop-variant: white` to `--gds-prop-variant: #fff`
          `@container ${componentName} style(--gds-${componentName}-${kebabCasePropName}: gds-${value}) { & }`
        );
      }
      if (isNewSelector) {
        postCssContainer.append({ text: "__not_new" });
        selectors.push(
          `@supports not (view-transition-name: none) { &:where(.gds-${componentName}[data-prop-polyfill-${kebabCasePropName}=${escape(String(value))}] *) }`
        );
      } else if (isExistingPolyfillSelector) {
        selectors.push(
          `&:where(.gds-${componentName}[data-prop-polyfill-${kebabCasePropName}=${escape(String(value))}] *)`
        );
      }
      if (selectors.length === 1) return selectors[0];
      return selectors;
    },
    {
      values: Object.fromEntries(
        Object.entries(componentsCSSPropsByPropName).flatMap(([propName, components]) => {
          const kebabCasePropName = camelToKebab(propName);
          const propValues = Object.values(components).flatMap((componentProps) => componentProps.values ?? []);
          if (propValues.length === 0) return [];
          return propValues.map((value) => [`${kebabCasePropName}-${value}`, [kebabCasePropName, value]]);
        })
      )
    }
  );
  matchUtilities(
    {
      ...Object.fromEntries(
        ["if-prop", "children-if-prop"].map((utilityType) => [
          utilityType,
          (value, { modifier: componentName }) => {
            if (!componentName || !componentNames.includes(componentName)) return null;
            const declarations = `${value},a=a()`.split(/(?:\),)?[a-zA-Z0-9-]+=[a-zA-Z0-9-]+\(/g);
            declarations.shift();
            const conditions = (value.match(/[a-zA-Z0-9-]+=[a-zA-Z0-9-]+/g) ?? []).flatMap((condition) => {
              const [ifProp, ifValue] = condition.split("=");
              const declaration = declarations.shift();
              if (!ifProp || !ifValue || !declaration) return [];
              const [thenProperty, thenValue] = declaration.split(":");
              if (!thenProperty || !thenValue) return [];
              return [{ ifProp, ifValue, thenProperty, thenValue }];
            });
            if (conditions.length === 0) return null;
            if (conditions.some((condition) => condition.thenProperty !== conditions[0].thenProperty)) return null;
            return Object.fromEntries(
              conditions.map((condition) => {
                return [
                  /**
                   * The `:where()` is to ensure that the unimportant variants work as expected with these utilities, because any selector part
                   * added by a utility seems to be generated at the end of the final selector (after variants are applied), affecting specificity
                   * in ways that variants can't control.
                   */
                  `&:where(.gds-${componentName}[data-prop-polyfill-${condition.ifProp}=${escape(condition.ifValue)}])${utilityType === "children-if-prop" ? " > *" : ""}`,
                  {
                    [condition.thenProperty]: condition.thenValue
                  }
                ];
              })
            );
          }
        ])
      )
    },
    {
      modifiers: "any"
    }
  );
});
export {
  customPlugin
};
