import plugin from "tailwindcss/plugin"; const md3Plugin = plugin(({ addBase, addComponents, addUtilities }) => { addBase({ ":root": { "--color-m3-primary": "var(--md-sys-color-primary)", "--color-m3-on-primary": "var(--md-sys-color-on-primary)", "--color-m3-primary-container": "var(--md-sys-color-primary-container)", "--color-m3-on-primary-container": "var(--md-sys-color-on-primary-container)", "--color-m3-secondary": "var(--md-sys-color-secondary)", "--color-m3-on-secondary": "var(--md-sys-color-on-secondary)", "--color-m3-secondary-container": "var(--md-sys-color-secondary-container)", "--color-m3-on-secondary-container": "var(--md-sys-color-on-secondary-container)", "--color-m3-tertiary": "var(--md-sys-color-tertiary)", "--color-m3-on-tertiary": "var(--md-sys-color-on-tertiary)", "--color-m3-tertiary-container": "var(--md-sys-color-tertiary-container)", "--color-m3-on-tertiary-container": "var(--md-sys-color-on-tertiary-container)", "--color-m3-error": "var(--md-sys-color-error)", "--color-m3-on-error": "var(--md-sys-color-on-error)", "--color-m3-error-container": "var(--md-sys-color-error-container)", "--color-m3-on-error-container": "var(--md-sys-color-on-error-container)", "--color-m3-surface": "var(--md-sys-color-surface)", "--color-m3-surface-dim": "var(--md-sys-color-surface-dim)", "--color-m3-surface-bright": "var(--md-sys-color-surface-bright)", "--color-m3-on-surface": "var(--md-sys-color-on-surface)", "--color-m3-surface-variant": "var(--md-sys-color-surface-variant)", "--color-m3-on-surface-variant": "var(--md-sys-color-on-surface-variant)", "--color-m3-surface-container-lowest": "var(--md-sys-color-surface-container-lowest)", "--color-m3-surface-container-low": "var(--md-sys-color-surface-container-low)", "--color-m3-surface-container": "var(--md-sys-color-surface-container)", "--color-m3-surface-container-high": "var(--md-sys-color-surface-container-high)", "--color-m3-surface-container-highest": "var(--md-sys-color-surface-container-highest)", "--color-m3-inverse-surface": "var(--md-sys-color-inverse-surface)", "--color-m3-inverse-on-surface": "var(--md-sys-color-inverse-on-surface)", "--color-m3-inverse-primary": "var(--md-sys-color-inverse-primary)", "--color-m3-outline": "var(--md-sys-color-outline)", "--color-m3-outline-variant": "var(--md-sys-color-outline-variant)", "--color-m3-shadow": "var(--md-sys-color-shadow)", "--color-m3-scrim": "var(--md-sys-color-scrim)", "--color-m3-surface-tint": "var(--md-sys-color-surface-tint)", // Background "--color-m3-background": "var(--md-sys-color-background)", "--color-m3-on-background": "var(--md-sys-color-on-background)", // Primary Fixed (brand-stable — invariant across light/dark) "--color-m3-primary-fixed": "var(--md-sys-color-primary-fixed)", "--color-m3-primary-fixed-dim": "var(--md-sys-color-primary-fixed-dim)", "--color-m3-on-primary-fixed": "var(--md-sys-color-on-primary-fixed)", "--color-m3-on-primary-fixed-variant": "var(--md-sys-color-on-primary-fixed-variant)", // Secondary Fixed (brand-stable — invariant across light/dark) "--color-m3-secondary-fixed": "var(--md-sys-color-secondary-fixed)", "--color-m3-secondary-fixed-dim": "var(--md-sys-color-secondary-fixed-dim)", "--color-m3-on-secondary-fixed": "var(--md-sys-color-on-secondary-fixed)", "--color-m3-on-secondary-fixed-variant": "var(--md-sys-color-on-secondary-fixed-variant)", // Tertiary Fixed (brand-stable — invariant across light/dark) "--color-m3-tertiary-fixed": "var(--md-sys-color-tertiary-fixed)", "--color-m3-tertiary-fixed-dim": "var(--md-sys-color-tertiary-fixed-dim)", "--color-m3-on-tertiary-fixed": "var(--md-sys-color-on-tertiary-fixed)", "--color-m3-on-tertiary-fixed-variant": "var(--md-sys-color-on-tertiary-fixed-variant)", // Expressive Dim tones (v0.4.0+ SpecVersion 2025) "--color-m3-primary-dim": "var(--md-sys-color-primary-dim)", "--color-m3-secondary-dim": "var(--md-sys-color-secondary-dim)", "--color-m3-tertiary-dim": "var(--md-sys-color-tertiary-dim)", // Bottom Sheet component tokens "--m3-bottom-sheet-max-width": "var(--md-comp-bottom-sheet-max-width, 640px)", "--m3-bottom-sheet-peek-height": "var(--md-comp-bottom-sheet-peek-height, 56px)", "--m3-bottom-sheet-top-margin": "var(--md-comp-bottom-sheet-top-margin, 72px)", "--color-m3-indicator-active": "var(--md-sys-color-indicator-active)", "--color-m3-indicator-container": "var(--md-sys-color-indicator-container)", "--color-m3-indicator-contained-active": "var(--md-sys-color-indicator-contained-active)", "--color-m3-indicator-contained-container": "var(--md-sys-color-indicator-contained-container)", "--color-m3-indicator-track": "var(--md-sys-color-indicator-track)", "--color-m3-indicator-stop": "var(--md-sys-color-indicator-stop)", "--radius-m3-none": "var(--md-sys-shape-corner-none, 0px)", "--radius-m3-xs": "var(--md-sys-shape-corner-extra-small, 4px)", "--radius-m3-sm": "var(--md-sys-shape-corner-small, 8px)", "--radius-m3-md": "var(--md-sys-shape-corner-medium, 12px)", "--radius-m3-lg": "var(--md-sys-shape-corner-large, 16px)", "--radius-m3-lg-inc": "var(--md-sys-shape-corner-large-increased, 20px)", "--radius-m3-xl": "var(--md-sys-shape-corner-extra-large, 28px)", "--radius-m3-xl-inc": "var(--md-sys-shape-corner-extra-large-increased, 32px)", "--radius-m3-xxl": "var(--md-sys-shape-corner-extra-extra-large, 48px)", "--radius-m3-full": "var(--md-sys-shape-corner-full, 9999px)", "--md-sys-motion-duration-short1": "50ms", "--md-sys-motion-duration-short2": "100ms", "--md-sys-motion-duration-short3": "150ms", "--md-sys-motion-duration-short4": "200ms", "--md-sys-motion-duration-medium1": "250ms", "--md-sys-motion-duration-medium2": "300ms", "--md-sys-motion-duration-medium3": "350ms", "--md-sys-motion-duration-medium4": "400ms", "--md-sys-motion-duration-long1": "450ms", "--md-sys-motion-duration-long2": "500ms", "--md-sys-motion-duration-long3": "550ms", "--md-sys-motion-duration-long4": "600ms", "--md-sys-motion-duration-extra-long1": "700ms", "--md-sys-motion-duration-extra-long2": "800ms", "--md-sys-motion-duration-extra-long3": "900ms", "--md-sys-motion-duration-extra-long4": "1000ms", "--md-sys-motion-easing-emphasized": "cubic-bezier(0.2, 0, 0, 1)", "--md-sys-motion-easing-emphasized-accelerate": "cubic-bezier(0.3, 0, 0.8, 0.15)", "--md-sys-motion-easing-emphasized-decelerate": "cubic-bezier(0.05, 0.7, 0.1, 1.0)", "--md-sys-motion-easing-standard": "cubic-bezier(0.2, 0, 0, 1)", "--md-sys-motion-easing-standard-accelerate": "cubic-bezier(0.3, 0, 1, 1)", "--md-sys-motion-easing-standard-decelerate": "cubic-bezier(0, 0, 0, 1)", "--md-sys-motion-easing-linear": "cubic-bezier(0, 0, 1, 1)", "--md-sys-motion-spring-exp-fast-spatial-curve": "cubic-bezier(0.42, 1.67, 0.21, 0.90)", "--md-sys-motion-spring-exp-fast-spatial-duration": "350ms", "--md-sys-motion-spring-exp-default-spatial-curve": "cubic-bezier(0.38, 1.21, 0.22, 1.00)", "--md-sys-motion-spring-exp-default-spatial-duration": "500ms", "--md-sys-motion-spring-exp-slow-spatial-curve": "cubic-bezier(0.39, 1.29, 0.35, 0.98)", "--md-sys-motion-spring-exp-slow-spatial-duration": "650ms", "--md-sys-motion-spring-exp-fast-effects-curve": "cubic-bezier(0.31, 0.94, 0.34, 1.00)", "--md-sys-motion-spring-exp-fast-effects-duration": "150ms", "--md-sys-motion-spring-exp-default-effects-curve": "cubic-bezier(0.34, 0.80, 0.34, 1.00)", "--md-sys-motion-spring-exp-default-effects-duration": "200ms", "--md-sys-motion-spring-exp-slow-effects-curve": "cubic-bezier(0.34, 0.88, 0.34, 1.00)", "--md-sys-motion-spring-exp-slow-effects-duration": "300ms", "--md-sys-motion-spring-std-fast-spatial-curve": "cubic-bezier(0.27, 1.06, 0.18, 1.00)", "--md-sys-motion-spring-std-fast-spatial-duration": "350ms", "--md-sys-motion-spring-std-default-spatial-curve": "cubic-bezier(0.27, 1.06, 0.18, 1.00)", "--md-sys-motion-spring-std-default-spatial-duration": "500ms", "--md-sys-motion-spring-std-slow-spatial-curve": "cubic-bezier(0.27, 1.06, 0.18, 1.00)", "--md-sys-motion-spring-std-slow-spatial-duration": "750ms", "--md-sys-motion-spring-std-fast-effects-curve": "cubic-bezier(0.31, 0.94, 0.34, 1.00)", "--md-sys-motion-spring-std-fast-effects-duration": "150ms", "--md-sys-motion-spring-std-default-effects-curve": "cubic-bezier(0.34, 0.80, 0.34, 1.00)", "--md-sys-motion-spring-std-default-effects-duration": "200ms", "--md-sys-motion-spring-std-slow-effects-curve": "cubic-bezier(0.34, 0.88, 0.34, 1.00)", "--md-sys-motion-spring-std-slow-effects-duration": "300ms", }, }); // CSS variables drive font-variation-settings so utility classes and // inline style props can all influence the same axes without specificity wars. addComponents({ ".md-icon": { fontFamily: "var(--md-icon-font, 'Material Symbols Rounded')", fontWeight: "normal", fontStyle: "normal", fontSize: "var(--md-icon-size, 24px)", lineHeight: "1", display: "inline-block", whiteSpace: "nowrap", wordWrap: "normal", direction: "ltr", textRendering: "optimizeLegibility", "-webkit-font-smoothing": "antialiased", fontVariationSettings: "'FILL' var(--md-icon-fill, 0), 'wght' var(--md-icon-weight, 400), 'GRAD' var(--md-icon-grade, 0), 'opsz' var(--md-icon-opsz, 24)", }, }); addUtilities({ ".elevation-0": { boxShadow: "none" }, ".elevation-1": { boxShadow: "0px 1px 2px 0px rgba(0,0,0,.3), 0px 1px 3px 1px rgba(0,0,0,.15)", }, ".elevation-2": { boxShadow: "0px 1px 2px 0px rgba(0,0,0,.3), 0px 2px 6px 2px rgba(0,0,0,.15)", }, ".elevation-3": { boxShadow: "0px 1px 3px 0px rgba(0,0,0,.3), 0px 4px 8px 3px rgba(0,0,0,.15)", }, ".elevation-4": { boxShadow: "0px 2px 3px 0px rgba(0,0,0,.3), 0px 6px 10px 4px rgba(0,0,0,.15)", }, ".elevation-5": { boxShadow: "0px 4px 4px 0px rgba(0,0,0,.3), 0px 8px 12px 6px rgba(0,0,0,.15)", }, ".icon-outlined": { "--md-icon-font": "'Material Symbols Outlined'", fontFamily: "'Material Symbols Outlined'", }, ".icon-rounded": { "--md-icon-font": "'Material Symbols Rounded'", fontFamily: "'Material Symbols Rounded'", }, ".icon-sharp": { "--md-icon-font": "'Material Symbols Sharp'", fontFamily: "'Material Symbols Sharp'", }, ".icon-fill-0": { "--md-icon-fill": "0" }, ".icon-fill-1": { "--md-icon-fill": "1" }, ".icon-weight-100": { "--md-icon-weight": "100" }, ".icon-weight-200": { "--md-icon-weight": "200" }, ".icon-weight-300": { "--md-icon-weight": "300" }, ".icon-weight-400": { "--md-icon-weight": "400" }, ".icon-weight-500": { "--md-icon-weight": "500" }, ".icon-weight-600": { "--md-icon-weight": "600" }, ".icon-weight-700": { "--md-icon-weight": "700" }, ".icon-grade-low": { "--md-icon-grade": "-25" }, ".icon-grade-default": { "--md-icon-grade": "0" }, ".icon-grade-high": { "--md-icon-grade": "200" }, // opsz axis must match rendered size for optical quality ".icon-size-20": { "--md-icon-size": "20px", "--md-icon-opsz": "20", fontSize: "20px", }, ".icon-size-24": { "--md-icon-size": "24px", "--md-icon-opsz": "24", fontSize: "24px", }, ".icon-size-40": { "--md-icon-size": "40px", "--md-icon-opsz": "40", fontSize: "40px", }, ".icon-size-48": { "--md-icon-size": "48px", "--md-icon-opsz": "48", fontSize: "48px", }, // MD3 Expressive spring curves as CSS transitions ".transition-m3-fast-spatial": { transitionTimingFunction: "var(--md-sys-motion-spring-exp-fast-spatial-curve)", transitionDuration: "var(--md-sys-motion-spring-exp-fast-spatial-duration)", }, ".transition-m3-default-spatial": { transitionTimingFunction: "var(--md-sys-motion-spring-exp-default-spatial-curve)", transitionDuration: "var(--md-sys-motion-spring-exp-default-spatial-duration)", }, ".transition-m3-slow-spatial": { transitionTimingFunction: "var(--md-sys-motion-spring-exp-slow-spatial-curve)", transitionDuration: "var(--md-sys-motion-spring-exp-slow-spatial-duration)", }, ".transition-m3-fast-effects": { transitionTimingFunction: "var(--md-sys-motion-spring-exp-fast-effects-curve)", transitionDuration: "var(--md-sys-motion-spring-exp-fast-effects-duration)", }, ".transition-m3-default-effects": { transitionTimingFunction: "var(--md-sys-motion-spring-exp-default-effects-curve)", transitionDuration: "var(--md-sys-motion-spring-exp-default-effects-duration)", }, ".transition-m3-slow-effects": { transitionTimingFunction: "var(--md-sys-motion-spring-exp-slow-effects-curve)", transitionDuration: "var(--md-sys-motion-spring-exp-slow-effects-duration)", }, ".transition-m3-std-fast-spatial": { transitionTimingFunction: "var(--md-sys-motion-spring-std-fast-spatial-curve)", transitionDuration: "var(--md-sys-motion-spring-std-fast-spatial-duration)", }, ".transition-m3-std-default-spatial": { transitionTimingFunction: "var(--md-sys-motion-spring-std-default-spatial-curve)", transitionDuration: "var(--md-sys-motion-spring-std-default-spatial-duration)", }, ".transition-m3-std-slow-spatial": { transitionTimingFunction: "var(--md-sys-motion-spring-std-slow-spatial-curve)", transitionDuration: "var(--md-sys-motion-spring-std-slow-spatial-duration)", }, }); }); export interface TailwindPlugin { handler: (api: unknown) => void; config?: unknown; } export default md3Plugin as TailwindPlugin;