Files
2026-07-13 12:12:04 +08:00

107 lines
3.2 KiB
CSS

/**
* ================================================================================================
* HeroUI Custom Tailwind CSS Variants
* ================================================================================================
*
* Custom variants with intelligent fallback: explicit controls override system preferences.
*
* Usage:
* motion-reduce:opacity-0 - Reduced motion accessibility
* motion-safe:animate-spin - Full motion effects
* dark:bg-gray-900 - Dark mode styles
*
* Priority: Explicit data attributes/classes → System preferences (fallback)
* ================================================================================================
*/
/* -------------------------------------------------------------------------------------------------
* motion-reduce — Minimize animations for accessibility
* Priority: data-reduce-motion="true" → prefers-reduced-motion: reduce
* ------------------------------------------------------------------------------------------------- */
@custom-variant motion-reduce {
/* Explicit: data-reduce-motion="true" on element or ancestor */
&:is([data-reduce-motion="true"], [data-reduce-motion="true"] *) {
@slot;
&::before,
&::after {
@slot;
}
}
/* Fallback: system prefers-reduced-motion setting */
@media (prefers-reduced-motion: reduce) {
&:not(:is([data-reduce-motion="true"], [data-reduce-motion="true"] *)) {
@slot;
&::before,
&::after {
@slot;
}
}
}
}
/* -------------------------------------------------------------------------------------------------
* motion-safe — Enable full animations and transitions
* Priority: data-reduce-motion="false" → prefers-reduced-motion: no-preference
* ------------------------------------------------------------------------------------------------- */
@custom-variant motion-safe {
/* Explicit: data-reduce-motion="false" on element or ancestor */
&:is([data-reduce-motion="false"], [data-reduce-motion="false"] *) {
@slot;
&::before,
&::after {
@slot;
}
}
/* Fallback: system has no motion preference set */
@media (prefers-reduced-motion: no-preference) {
&:not(
:is(
[data-reduce-motion="true"],
[data-reduce-motion="true"] *,
[data-reduce-motion="false"],
[data-reduce-motion="false"] *
)
) {
@slot;
&::before,
&::after {
@slot;
}
}
}
}
/* -------------------------------------------------------------------------------------------------
* dark — Dark mode styles
* Priority: .dark class / data-theme="dark" → prefers-color-scheme: dark
* ------------------------------------------------------------------------------------------------- */
@custom-variant dark {
/* Explicit: .dark class or data-theme="dark" on element or ancestor */
&:is(.dark, .dark *, [data-theme="dark"], [data-theme="dark"] *) {
@slot;
&::before,
&::after {
@slot;
}
}
/* Fallback: system prefers dark color scheme */
@media (prefers-color-scheme: dark) {
&:not(:is(.dark, .dark *, [data-theme="dark"], [data-theme="dark"] *)) & {
@slot;
&::before,
&::after {
@slot;
}
}
}
}