Back to buttons
"use client"

import { useState } from "react"
import { motion, AnimatePresence } from "motion/react"
import { ArrowBigUp } from "lucide-react"
import { cn } from "@/lib/utils"

const COLORS = ["bg-orange-500", "bg-amber-400", "bg-yellow-400", "bg-orange-400"]

const COUNT = 6
const PARTICLES = Array.from({ length: COUNT }, (_, i) => {
  const angle = -150 + (i / (COUNT - 1)) * 120   // -150° → -30° (upward arc)
  const rad   = (angle * Math.PI) / 180
  const dist  = 30 + (i % 2) * 15
  return {
    id:    i,
    x:     Math.cos(rad) * dist,
    y:     Math.sin(rad) * dist,
    color: COLORS[i % COLORS.length],
    size:  4 + (i % 2),
    dur:   0.5 + (i % 3) * 0.07,
  }
})

export default function UpVoteButton() {
  const [voted, setVoted]       = useState(false)
  const [count, setCount]       = useState(165)
  const [clickKey, setClickKey] = useState(0)

  const handleClick = () => {
    const next = !voted
    setVoted(next)
    setCount((c) => (next ? c + 1 : c - 1))
    if (next) setClickKey((k) => k + 1)
  }

  return (
    <div className="relative inline-flex items-center justify-center">
      {/* Particles */}
      <AnimatePresence>
        {voted && PARTICLES.map((p) => (
          <motion.span
            key={`${p.id}-${clickKey}`}
            className={cn("absolute rounded-full pointer-events-none", p.color)}
            style={{ width: p.size, height: p.size, left: "50%", top: "50%", marginLeft: -(p.size / 2), marginTop: -(p.size / 2) }}
            initial={{ x: 0, y: 0, opacity: 1, scale: 1 }}
            animate={{ x: p.x, y: [0, p.y * 0.6, p.y], opacity: [1, 1, 0], scale: 0.5 }}
            exit={{}}
            transition={{ duration: p.dur, ease: [0.22, 1, 0.36, 1] }}
          />
        ))}
      </AnimatePresence>

      {/* Pill */}
      <motion.button
        onClick={handleClick}
        whileHover={{ scale: 1.04 }}
        whileTap={{ scale: 0.88 }}
        transition={{ type: "spring", stiffness: 380, damping: 22 }}
        className="relative overflow-hidden inline-flex items-center gap-2 px-3 py-1.5 rounded-full bg-neutral-800 cursor-pointer select-none"
      >
        {/* Ripple */}
        <AnimatePresence initial={false}>
          <motion.span
            key={clickKey}
            className="absolute w-5 h-5 rounded-full bg-orange-500/25 pointer-events-none"
            style={{ top: "50%", left: "50%", marginLeft: -10, marginTop: -10 }}
            initial={{ scale: 0, opacity: 1 }}
            animate={{ scale: 15, opacity: 0 }}
            exit={{}}
            transition={{
              scale:   { duration: 1.1, ease: "easeOut" },
              opacity: { duration: 1.0, ease: "easeIn", delay: 0.1 },
            }}
          />
        </AnimatePresence>

        {/* Arrow */}
        <motion.div
          key={`icon-${clickKey}`}
          animate={voted ? { y: [0, -4, 1, -2, 0] } : { y: [0, 3, 0] }}
          transition={{ duration: 0.4, ease: "easeOut" }}
        >
          <ArrowBigUp
            className={cn("size-5 transition-colors duration-300", voted ? "text-orange-500" : "text-neutral-400")}
            fill={voted ? "currentColor" : "none"}
            strokeWidth={1.75}
          />
        </motion.div>

        {/* Count */}
        <div className="overflow-hidden h-5 flex items-center tabular-nums min-w-[2ch]">
          <AnimatePresence mode="wait" initial={false}>
            <motion.span
              key={count}
              initial={{ y: voted ? 12 : -12, opacity: 0 }}
              animate={{ y: 0, opacity: 1 }}
              exit={{ y: voted ? -12 : 12, opacity: 0 }}
              transition={{ duration: 0.18, ease: [0.2, 0, 0.2, 1] }}
              className="block text-sm font-semibold text-white"
            >
              {count.toLocaleString()}
            </motion.span>
          </AnimatePresence>
        </div>
      </motion.button>
    </div>
  )
}

Button 21 - Animated Upvote Button

By ShadcnSpace

Try the interaction, copy the React source files, or download the complete example.

About Button 21 - Animated Upvote Button

Button 21 - Animated Upvote Button is an animated React and Tailwind CSS button by ShadcnSpace. Try the interaction, copy the React source, or download the example with creator credit.

Effects and categories
Hover effects, Animated
Using this example
Copy a TSX file or download the original source and standalone demo. Test keyboard focus, motion and contrast in your own project.

Usage, Tailwind and licensing questions

Read the source files

components/shadcn-space/button/button-21.tsx

"use client"

import { useState } from "react"
import { motion, AnimatePresence } from "motion/react"
import { ArrowBigUp } from "lucide-react"
import { cn } from "@/lib/utils"

const COLORS = ["bg-orange-500", "bg-amber-400", "bg-yellow-400", "bg-orange-400"]

const COUNT = 6
const PARTICLES = Array.from({ length: COUNT }, (_, i) => {
  const angle = -150 + (i / (COUNT - 1)) * 120   // -150° → -30° (upward arc)
  const rad   = (angle * Math.PI) / 180
  const dist  = 30 + (i % 2) * 15
  return {
    id:    i,
    x:     Math.cos(rad) * dist,
    y:     Math.sin(rad) * dist,
    color: COLORS[i % COLORS.length],
    size:  4 + (i % 2),
    dur:   0.5 + (i % 3) * 0.07,
  }
})

export default function UpVoteButton() {
  const [voted, setVoted]       = useState(false)
  const [count, setCount]       = useState(165)
  const [clickKey, setClickKey] = useState(0)

  const handleClick = () => {
    const next = !voted
    setVoted(next)
    setCount((c) => (next ? c + 1 : c - 1))
    if (next) setClickKey((k) => k + 1)
  }

  return (
    <div className="relative inline-flex items-center justify-center">
      {/* Particles */}
      <AnimatePresence>
        {voted && PARTICLES.map((p) => (
          <motion.span
            key={`${p.id}-${clickKey}`}
            className={cn("absolute rounded-full pointer-events-none", p.color)}
            style={{ width: p.size, height: p.size, left: "50%", top: "50%", marginLeft: -(p.size / 2), marginTop: -(p.size / 2) }}
            initial={{ x: 0, y: 0, opacity: 1, scale: 1 }}
            animate={{ x: p.x, y: [0, p.y * 0.6, p.y], opacity: [1, 1, 0], scale: 0.5 }}
            exit={{}}
            transition={{ duration: p.dur, ease: [0.22, 1, 0.36, 1] }}
          />
        ))}
      </AnimatePresence>

      {/* Pill */}
      <motion.button
        onClick={handleClick}
        whileHover={{ scale: 1.04 }}
        whileTap={{ scale: 0.88 }}
        transition={{ type: "spring", stiffness: 380, damping: 22 }}
        className="relative overflow-hidden inline-flex items-center gap-2 px-3 py-1.5 rounded-full bg-neutral-800 cursor-pointer select-none"
      >
        {/* Ripple */}
        <AnimatePresence initial={false}>
          <motion.span
            key={clickKey}
            className="absolute w-5 h-5 rounded-full bg-orange-500/25 pointer-events-none"
            style={{ top: "50%", left: "50%", marginLeft: -10, marginTop: -10 }}
            initial={{ scale: 0, opacity: 1 }}
            animate={{ scale: 15, opacity: 0 }}
            exit={{}}
            transition={{
              scale:   { duration: 1.1, ease: "easeOut" },
              opacity: { duration: 1.0, ease: "easeIn", delay: 0.1 },
            }}
          />
        </AnimatePresence>

        {/* Arrow */}
        <motion.div
          key={`icon-${clickKey}`}
          animate={voted ? { y: [0, -4, 1, -2, 0] } : { y: [0, 3, 0] }}
          transition={{ duration: 0.4, ease: "easeOut" }}
        >
          <ArrowBigUp
            className={cn("size-5 transition-colors duration-300", voted ? "text-orange-500" : "text-neutral-400")}
            fill={voted ? "currentColor" : "none"}
            strokeWidth={1.75}
          />
        </motion.div>

        {/* Count */}
        <div className="overflow-hidden h-5 flex items-center tabular-nums min-w-[2ch]">
          <AnimatePresence mode="wait" initial={false}>
            <motion.span
              key={count}
              initial={{ y: voted ? 12 : -12, opacity: 0 }}
              animate={{ y: 0, opacity: 1 }}
              exit={{ y: voted ? -12 : 12, opacity: 0 }}
              transition={{ duration: 0.18, ease: [0.2, 0, 0.2, 1] }}
              className="block text-sm font-semibold text-white"
            >
              {count.toLocaleString()}
            </motion.span>
          </AnimatePresence>
        </div>
      </motion.button>
    </div>
  )
}

lib/utils.ts

import { config } from "@/config";
import { clsx, type ClassValue } from "clsx";
import { twMerge } from "tailwind-merge";

export function cn(...inputs: ClassValue[]) {
  return twMerge(clsx(inputs));
}

export function capitalize(str: string) {
  return str.charAt(0).toUpperCase() + str.slice(1);
}

// eslint-disable-next-line @typescript-eslint/no-unused-vars
type GroupBy<T, K extends keyof T> = Record<string, T[]>;

export function groupBy<T, K extends keyof T>(
  array: T[],
  key: K
): GroupBy<T, K> {
  return array.reduce((acc, item) => {
    const keyValue = String(item[key]);
    if (!acc[keyValue]) {
      acc[keyValue] = [];
    }
    acc[keyValue].push(item);
    return acc;
  }, {} as GroupBy<T, K>);
}

export function absoluteUrl(path: string) {
  return process.env.NODE_ENV === "development"
    ? `http://localhost:3000/${path}`
    : `${config.appUrl}/${path}`;
}

config.ts

export const config = {
  appUrl:
    process.env.NODE_ENV === "production"
      ? process.env.VERCEL_PROJECT_PRODUCTION_URL ??
      process.env.NEXT_PUBLIC_APP_URL!
      : "http://localhost:3000",
  social: {
    github: "https://github.com/shadcnspace/shadcnspace",
    twitter: "https://twitter.com/",
  },
};

demo.tsx

export { default as default } from "@/components/shadcn-space/button/button-21";

CSS

/*! tailwindcss v4.3.3 | MIT License | https://tailwindcss.com */
@layer properties;
@layer theme, base, components, utilities;
@layer theme {
  :root, :host {
    --font-sans: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue",
      "Noto Sans", Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji",
      "Segoe UI Symbol", "Noto Color Emoji";
    --font-mono: ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, "Liberation Mono",
      "Courier New", monospace;
    --color-orange-400: oklch(75% 0.183 55.934);
    --color-orange-500: oklch(70.5% 0.213 47.604);
    --color-amber-400: oklch(82.8% 0.189 84.429);
    --color-yellow-400: oklch(85.2% 0.199 91.936);
    --color-neutral-400: oklch(70.8% 0 none);
    --color-neutral-800: oklch(26.9% 0 none);
    --color-white: #fff;
    --spacing: 0.25rem;
    --text-sm: 0.875rem;
    --text-sm--line-height: calc(1.25 / 0.875);
    --font-weight-semibold: 600;
    --default-transition-duration: 150ms;
    --default-transition-timing-function: cubic-bezier(0.4, 0, 0.2, 1);
    --default-font-family: var(--font-sans);
    --default-font-feature-settings: "cv02", "cv03", "cv04", "cv11";
    --default-mono-font-family: var(--font-mono);
  }
}
@layer base {
  *, ::after, ::before, ::backdrop, ::file-selector-button {
    box-sizing: border-box;
    margin: 0;
    padding: 0;
    border: 0 solid;
  }
  html, :host {
    line-height: 1.5;
    -webkit-text-size-adjust: 100%;
    tab-size: 4;
    font-family: var(--default-font-family, -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", "Noto Sans", Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol", "Noto Color Emoji");
    font-feature-settings: var(--default-font-feature-settings, normal);
    font-variation-settings: var(--default-font-variation-settings, normal);
    -webkit-tap-highlight-color: transparent;
  }
  hr {
    height: 0;
    color: inherit;
    border-top-width: 1px;
  }
  abbr:where([title]) {
    -webkit-text-decoration: underline dotted;
    text-decoration: underline dotted;
  }
  h1, h2, h3, h4, h5, h6 {
    font-size: inherit;
    font-weight: inherit;
  }
  a {
    color: inherit;
    -webkit-text-decoration: inherit;
    text-decoration: inherit;
  }
  b, strong {
    font-weight: bolder;
  }
  code, kbd, samp, pre {
    font-family: var(--default-mono-font-family, ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, "Liberation Mono", "Courier New", monospace);
    font-feature-settings: var(--default-mono-font-feature-settings, normal);
    font-variation-settings: var(--default-mono-font-variation-settings, normal);
    font-size: 1em;
  }
  small {
    font-size: 80%;
  }
  sub, sup {
    font-size: 75%;
    line-height: 0;
    position: relative;
    vertical-align: baseline;
  }
  sub {
    bottom: -0.25em;
  }
  sup {
    top: -0.5em;
  }
  table {
    text-indent: 0;
    border-color: inherit;
    border-collapse: collapse;
  }
  :-moz-focusring:where(:not(iframe)) {
    outline: auto;
  }
  progress {
    vertical-align: baseline;
  }
  summary {
    display: list-item;
  }
  ol, ul, menu {
    list-style: none;
  }
  img, svg, video, canvas, audio, iframe, embed, object {
    display: block;
    vertical-align: middle;
  }
  img, video {
    max-width: 100%;
    height: auto;
  }
  button, input, select, optgroup, textarea, ::file-selector-button {
    font: inherit;
    font-feature-settings: inherit;
    font-variation-settings: inherit;
    letter-spacing: inherit;
    color: inherit;
    border-radius: 0;
    background-color: transparent;
    opacity: 1;
  }
  :where(select:is([multiple], [size])) optgroup {
    font-weight: bolder;
  }
  :where(select:is([multiple], [size])) optgroup option {
    padding-inline-start: 20px;
  }
  ::file-selector-button {
    margin-inline-end: 4px;
  }
  ::placeholder {
    opacity: 1;
  }
  @supports (not (-webkit-appearance: -apple-pay-button))  or (contain-intrinsic-size: 1px) {
    ::placeholder {
      color: currentcolor;
      @supports (color: color-mix(in lab, red, red)) {
        color: color-mix(in oklab, currentcolor 50%, transparent);
      }
    }
  }
  textarea {
    resize: vertical;
  }
  ::-webkit-search-decoration {
    -webkit-appearance: none;
  }
  ::-webkit-date-and-time-value {
    min-height: 1lh;
    text-align: inherit;
  }
  ::-webkit-datetime-edit {
    display: inline-flex;
  }
  ::-webkit-datetime-edit-fields-wrapper {
    padding: 0;
  }
  ::-webkit-datetime-edit, ::-webkit-datetime-edit-year-field, ::-webkit-datetime-edit-month-field, ::-webkit-datetime-edit-day-field, ::-webkit-datetime-edit-hour-field, ::-webkit-datetime-edit-minute-field, ::-webkit-datetime-edit-second-field, ::-webkit-datetime-edit-millisecond-field, ::-webkit-datetime-edit-meridiem-field {
    padding-block: 0;
  }
  ::-webkit-calendar-picker-indicator {
    line-height: 1;
  }
  :-moz-ui-invalid {
    box-shadow: none;
  }
  button, input:where([type="button"], [type="reset"], [type="submit"]), ::file-selector-button {
    appearance: button;
  }
  ::-webkit-inner-spin-button, ::-webkit-outer-spin-button {
    height: auto;
  }
  [hidden]:where(:not([hidden="until-found"])) {
    display: none !important;
  }
}
@layer utilities {
  .pointer-events-none {
    pointer-events: none;
  }
  .absolute {
    position: absolute;
  }
  .relative {
    position: relative;
  }
  .block {
    display: block;
  }
  .flex {
    display: flex;
  }
  .inline-flex {
    display: inline-flex;
  }
  .size-5 {
    width: calc(var(--spacing) * 5);
    height: calc(var(--spacing) * 5);
  }
  .h-5 {
    height: calc(var(--spacing) * 5);
  }
  .w-5 {
    width: calc(var(--spacing) * 5);
  }
  .min-w-\[2ch\] {
    min-width: 2ch;
  }
  .cursor-pointer {
    cursor: pointer;
  }
  .items-center {
    align-items: center;
  }
  .justify-center {
    justify-content: center;
  }
  .gap-2 {
    gap: calc(var(--spacing) * 2);
  }
  .overflow-hidden {
    overflow: hidden;
  }
  .rounded-full {
    border-radius: calc(infinity * 1px);
  }
  .bg-amber-400 {
    background-color: var(--color-amber-400);
  }
  .bg-neutral-800 {
    background-color: var(--color-neutral-800);
  }
  .bg-orange-400 {
    background-color: var(--color-orange-400);
  }
  .bg-orange-500 {
    background-color: var(--color-orange-500);
  }
  .bg-orange-500\/25 {
    background-color: color-mix(in srgb, oklch(70.5% 0.213 47.604) 25%, transparent);
    @supports (color: color-mix(in lab, red, red)) {
      background-color: color-mix(in oklab, var(--color-orange-500) 25%, transparent);
    }
  }
  .bg-yellow-400 {
    background-color: var(--color-yellow-400);
  }
  .px-3 {
    padding-inline: calc(var(--spacing) * 3);
  }
  .py-1\.5 {
    padding-block: calc(var(--spacing) * 1.5);
  }
  .text-sm {
    font-size: var(--text-sm);
    line-height: var(--tw-leading, var(--text-sm--line-height));
  }
  .font-semibold {
    --tw-font-weight: var(--font-weight-semibold);
    font-weight: var(--font-weight-semibold);
  }
  .text-neutral-400 {
    color: var(--color-neutral-400);
  }
  .text-orange-500 {
    color: var(--color-orange-500);
  }
  .text-white {
    color: var(--color-white);
  }
  .tabular-nums {
    --tw-numeric-spacing: tabular-nums;
    font-variant-numeric: var(--tw-ordinal,) var(--tw-slashed-zero,) var(--tw-numeric-figure,) var(--tw-numeric-spacing,) var(--tw-numeric-fraction,);
  }
  .transition {
    transition-property: color, background-color, border-color, outline-color, text-decoration-color, fill, stroke, --tw-gradient-from, --tw-gradient-via, --tw-gradient-to, opacity, box-shadow, transform, translate, scale, rotate, filter, -webkit-backdrop-filter, backdrop-filter, display, content-visibility, overlay, pointer-events;
    transition-timing-function: var(--tw-ease, var(--default-transition-timing-function));
    transition-duration: var(--tw-duration, var(--default-transition-duration));
  }
  .transition-colors {
    transition-property: color, background-color, border-color, outline-color, text-decoration-color, fill, stroke, --tw-gradient-from, --tw-gradient-via, --tw-gradient-to;
    transition-timing-function: var(--tw-ease, var(--default-transition-timing-function));
    transition-duration: var(--tw-duration, var(--default-transition-duration));
  }
  .duration-300 {
    --tw-duration: 300ms;
    transition-duration: 300ms;
  }
  .select-none {
    -webkit-user-select: none;
    user-select: none;
  }
}
:root {
  --background: #fff;
  --foreground: #111;
  --primary: #171717;
  --primary-foreground: #fff;
  --secondary: #eee;
  --secondary-foreground: #171717;
  --muted: #eee;
  --muted-foreground: #666;
  --accent: #eee;
  --accent-foreground: #171717;
  --border: #ddd;
  --input: #ddd;
  --ring: #777;
  --destructive: #dc2626;
  --destructive-foreground: #fff;
  --popover: #fff;
  --popover-foreground: #111;
  --success: #15803d;
  --success-foreground: #fff;
  --radius: .625rem;
  --hairline: 1px;
}
.dark {
  --background: #090909;
  --foreground: #fafafa;
  --primary: #fafafa;
  --primary-foreground: #171717;
  --secondary: #262626;
  --secondary-foreground: #fafafa;
  --muted: #262626;
  --muted-foreground: #a3a3a3;
  --accent: #262626;
  --accent-foreground: #fafafa;
  --border: #333;
  --input: #333;
  --popover: #171717;
  --popover-foreground: #fafafa;
}
:root {
  --radius: 0.5rem;
  --background: oklch(1 0 0);
  --foreground: oklch(0.1296 0.0274 261.69);
  --card: oklch(1 0 0);
  --card-foreground: oklch(0.1296 0.0274 261.69);
  --popover: oklch(1 0 0);
  --popover-foreground: oklch(0.1296 0.0274 261.69);
  --primary: oklch(0.1296 0.0274 261.69);
  --primary-foreground: oklch(0.9276 0.0058 264.53);
  --secondary: oklch(0.967 0.0029 264.54);
  --secondary-foreground: oklch(0.1296 0.0274 261.69);
  --muted: oklch(0.967 0.0029 264.54);
  --muted-foreground: oklch(0.4461 0.0263 256.8);
  --accent: oklch(0.967 0.0029 264.54);
  --accent-foreground: oklch(0.1296 0.0274 261.69);
  --destructive: oklch(0.6368 0.2078 25.33);
  --border: oklch(0.9276 0.0058 264.53);
  --input: oklch(0.922 0 0);
  --ring: oklch(0.7137 0.0192 261.32);
  --chart-1: oklch(63.681% 0.20784 25.315);
  --chart-2: oklch(78.453% 0.13254 181.95);
  --chart-3: oklch(62.31% 0.1881 259.83);
  --chart-4: oklch(87.896% 0.15335 91.611);
  --chart-5: oklch(75.763% 0.15899 55.922);
  --sidebar: oklch(0.985 0 0);
  --sidebar-foreground: oklch(0.1296 0.0274 261.69);
  --sidebar-primary: oklch(0.1296 0.0274 261.69);
  --sidebar-primary-foreground: oklch(0.9276 0.0058 264.53);
  --sidebar-accent: oklch(0.967 0.0029 264.54);
  --sidebar-accent-foreground: oklch(0.1296 0.0274 261.69);
  --sidebar-border: oklch(0.9276 0.0058 264.53);
  --sidebar-ring: oklch(0.7137 0.0192 261.32);
}
.dark {
  --background: oklch(0.1296 0.0274 261.69);
  --foreground: oklch(0.9276 0.0058 264.53);
  --card: oklch(0.1296 0.0274 261.69);
  --card-foreground: oklch(0.9276 0.0058 264.53);
  --popover: oklch(0.1296 0.0274 261.69);
  --popover-foreground: oklch(0.9276 0.0058 264.53);
  --primary: oklch(0.9276 0.0058 264.53);
  --primary-foreground: oklch(0.1296 0.0274 261.69);
  --secondary: oklch(0.3729 0.0306 259.73);
  --secondary-foreground: oklch(0.9276 0.0058 264.53);
  --muted: oklch(0.2781 0.0296 256.85);
  --muted-foreground: oklch(0.8717 0.0093 258.34);
  --accent: oklch(0.2781 0.0296 256.85);
  --accent-foreground: oklch(0.9276 0.0058 264.53);
  --destructive: oklch(0.6368 0.2078 25.33);
  --border: oklch(27.808% 0.02963 256.871 / 70%);
  --input: oklch(1 0 0 / 15%);
  --ring: oklch(0.4461 0.0263 256.8);
  --chart-1: oklch(63.681% 0.20784 25.315);
  --chart-2: oklch(78.453% 0.13254 181.95);
  --chart-3: oklch(62.31% 0.1881 259.83);
  --chart-4: oklch(87.896% 0.15335 91.611);
  --chart-5: oklch(75.763% 0.15899 55.922);
  --sidebar: oklch(0.205 0 0);
  --sidebar-foreground: oklch(0.9276 0.0058 264.53);
  --sidebar-primary: oklch(0.9276 0.0058 264.53);
  --sidebar-primary-foreground: oklch(0.1296 0.0274 261.69);
  --sidebar-accent: oklch(0.2781 0.0296 256.85);
  --sidebar-accent-foreground: oklch(0.9276 0.0058 264.53);
  --sidebar-border: var(--border);
  --sidebar-ring: oklch(0.4461 0.0263 256.8);
}
@property --tw-font-weight {
  syntax: "*";
  inherits: false;
}
@property --tw-ordinal {
  syntax: "*";
  inherits: false;
}
@property --tw-slashed-zero {
  syntax: "*";
  inherits: false;
}
@property --tw-numeric-figure {
  syntax: "*";
  inherits: false;
}
@property --tw-numeric-spacing {
  syntax: "*";
  inherits: false;
}
@property --tw-numeric-fraction {
  syntax: "*";
  inherits: false;
}
@property --tw-duration {
  syntax: "*";
  inherits: false;
}
@layer properties {
  @supports ((-webkit-hyphens: none) and (not (margin-trim: inline))) or ((-moz-orient: inline) and (not (color:rgb(from red r g b)))) {
    *, ::before, ::after, ::backdrop {
      --tw-font-weight: initial;
      --tw-ordinal: initial;
      --tw-slashed-zero: initial;
      --tw-numeric-figure: initial;
      --tw-numeric-spacing: initial;
      --tw-numeric-fraction: initial;
      --tw-duration: initial;
    }
  }
}