Back to buttons
'use client';

import * as React from 'react';

import { cn } from '@/lib/utils';

import styles from './lustre-button.module.css';

type LustreStyle = React.CSSProperties & {
  '--lustre-color': string;
  '--lustre-duration': string;
};

export type LustreButtonProps =
  React.ButtonHTMLAttributes<HTMLButtonElement> & {
    lustreColor?: string;
    duration?: number;
    motion?: 'loop' | 'hover';
  };

const LustreButton = React.forwardRef<HTMLButtonElement, LustreButtonProps>(
  function LustreButton(
    {
      children = 'Explore components',
      className,
      duration = 3200,
      lustreColor = '#ffffff',
      motion = 'loop',
      style,
      type = 'button',
      ...props
    },
    ref,
  ) {
    const lustreStyle = {
      ...style,
      '--lustre-color': lustreColor,
      '--lustre-duration': `${Math.min(Math.max(duration, 1800), 6000)}ms`,
    } as LustreStyle;

    return (
      <button
        ref={ref}
        data-slot="lustre-button"
        data-motion={motion}
        type={type}
        className={cn(styles.root, className)}
        style={lustreStyle}
        {...props}
      >
        <span className={styles.lustre} aria-hidden="true" />
        <span className={styles.edge} aria-hidden="true" />
        <span className={styles.content}>
          <span>{children}</span>
          <svg
            className={styles.arrow}
            viewBox="0 0 16 16"
            fill="none"
            aria-hidden="true"
          >
            <path d="M3 8h9M8.5 4.5 12 8l-3.5 3.5" />
          </svg>
        </span>
      </button>
    );
  },
);

LustreButton.displayName = 'LustreButton';

export { LustreButton };

Lustre Button

By John Mamanao

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

About Lustre Button

Lustre Button is an animated React and CSS button by John Mamanao. 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

import-examples/lustre-button.tsx

import {LustreButton} from "@/components/ui/lustre-button";export default function Demo(){return <LustreButton/>}

components/ui/lustre-button.tsx

'use client';

import * as React from 'react';

import { cn } from '@/lib/utils';

import styles from './lustre-button.module.css';

type LustreStyle = React.CSSProperties & {
  '--lustre-color': string;
  '--lustre-duration': string;
};

export type LustreButtonProps =
  React.ButtonHTMLAttributes<HTMLButtonElement> & {
    lustreColor?: string;
    duration?: number;
    motion?: 'loop' | 'hover';
  };

const LustreButton = React.forwardRef<HTMLButtonElement, LustreButtonProps>(
  function LustreButton(
    {
      children = 'Explore components',
      className,
      duration = 3200,
      lustreColor = '#ffffff',
      motion = 'loop',
      style,
      type = 'button',
      ...props
    },
    ref,
  ) {
    const lustreStyle = {
      ...style,
      '--lustre-color': lustreColor,
      '--lustre-duration': `${Math.min(Math.max(duration, 1800), 6000)}ms`,
    } as LustreStyle;

    return (
      <button
        ref={ref}
        data-slot="lustre-button"
        data-motion={motion}
        type={type}
        className={cn(styles.root, className)}
        style={lustreStyle}
        {...props}
      >
        <span className={styles.lustre} aria-hidden="true" />
        <span className={styles.edge} aria-hidden="true" />
        <span className={styles.content}>
          <span>{children}</span>
          <svg
            className={styles.arrow}
            viewBox="0 0 16 16"
            fill="none"
            aria-hidden="true"
          >
            <path d="M3 8h9M8.5 4.5 12 8l-3.5 3.5" />
          </svg>
        </span>
      </button>
    );
  },
);

LustreButton.displayName = 'LustreButton';

export { LustreButton };

lib/utils.ts

import { clsx, type ClassValue } from 'clsx';
import { twMerge } from 'tailwind-merge';

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

components/ui/lustre-button.module.css

.root {
  --lustre-color: #ffffff;
  --lustre-duration: 3200ms;

  position: relative;
  display: inline-grid;
  min-width: 190px;
  height: 50px;
  padding: 0 19px;
  place-items: center;
  overflow: hidden;
  border: 1px solid rgb(255 255 255 / 11%);
  border-radius: 13px;
  color: #f4f3ee;
  background: #151613;
  box-shadow:
    inset 0 1px rgb(255 255 255 / 7%),
    inset 0 -1px rgb(0 0 0 / 28%),
    0 12px 30px rgb(0 0 0 / 22%);
  cursor: pointer;
  isolation: isolate;
  transition:
    border-color 90ms ease-out,
    background 90ms ease-out,
    box-shadow 180ms ease-out,
    transform 80ms cubic-bezier(0.2, 0, 0, 1);
}

.root:hover,
.root:focus-visible {
  border-color: rgb(255 255 255 / 19%);
  background: #1a1b17;
  box-shadow:
    inset 0 1px rgb(255 255 255 / 9%),
    inset 0 -1px rgb(0 0 0 / 28%),
    0 16px 36px rgb(0 0 0 / 28%);
}

.root:active {
  box-shadow:
    inset 0 1px rgb(255 255 255 / 5%),
    inset 0 2px 5px rgb(0 0 0 / 30%),
    0 6px 14px rgb(0 0 0 / 18%);
  transform: scale(0.97);
}

.root:focus-visible {
  outline: 2px solid currentColor;
  outline-offset: 3px;
}

.root:disabled {
  cursor: not-allowed;
  opacity: 0.46;
  transform: none;
}

.lustre {
  position: absolute;
  z-index: -1;
  top: -60%;
  left: -42%;
  width: 34%;
  height: 220%;
  background: linear-gradient(
    90deg,
    transparent,
    color-mix(in srgb, var(--lustre-color) 9%, transparent) 34%,
    color-mix(in srgb, var(--lustre-color) 24%, transparent) 50%,
    color-mix(in srgb, var(--lustre-color) 9%, transparent) 66%,
    transparent
  );
  filter: blur(0.5px);
  opacity: 0.78;
  pointer-events: none;
  transform: skewX(-18deg) translateX(0);
}

.root[data-motion='loop'] .lustre {
  animation: lustre-pass var(--lustre-duration) cubic-bezier(0.4, 0, 0.2, 1)
    infinite;
}

.root[data-motion='hover'] .lustre {
  opacity: 0;
  transform: skewX(-18deg) translateX(0);
}

.root[data-motion='hover']:hover .lustre,
.root[data-motion='hover']:focus-visible .lustre {
  animation: lustre-hover 680ms cubic-bezier(0.2, 0, 0, 1) both;
}

.edge {
  position: absolute;
  z-index: -1;
  inset: 1px;
  border-radius: 11px;
  background: linear-gradient(
    110deg,
    rgb(255 255 255 / 4%),
    transparent 28%,
    transparent 72%,
    rgb(255 255 255 / 3%)
  );
  pointer-events: none;
}

.content {
  position: relative;
  display: inline-flex;
  align-items: center;
  gap: 11px;
  font-size: 13px;
  font-weight: 650;
  letter-spacing: -0.013em;
  white-space: nowrap;
}

.arrow {
  width: 16px;
  height: 16px;
  stroke: currentColor;
  stroke-linecap: round;
  stroke-linejoin: round;
  stroke-width: 1.4;
  transition: transform 180ms cubic-bezier(0.2, 0, 0, 1);
}

.root:hover .arrow,
.root:focus-visible .arrow {
  transform: translateX(2px);
}

.root:disabled .lustre {
  animation: none;
}

.root:disabled .arrow {
  transform: none;
}

@keyframes lustre-pass {
  0%,
  54% {
    opacity: 0;
    transform: skewX(-18deg) translateX(0);
  }

  60% {
    opacity: 0.78;
  }

  82% {
    opacity: 0.78;
  }

  88%,
  100% {
    opacity: 0;
    transform: skewX(-18deg) translateX(560%);
  }
}

@keyframes lustre-hover {
  from {
    opacity: 0;
    transform: skewX(-18deg) translateX(0);
  }

  16% {
    opacity: 0.78;
  }

  84% {
    opacity: 0.78;
  }

  to {
    opacity: 0;
    transform: skewX(-18deg) translateX(560%);
  }
}

@media (prefers-reduced-motion: reduce) {
  .root,
  .arrow {
    transition: none;
  }

  .lustre,
  .root[data-motion='loop'] .lustre,
  .root[data-motion='hover']:hover .lustre,
  .root[data-motion='hover']:focus-visible .lustre {
    display: none;
    animation: none;
  }

  .root:active,
  .root:hover .arrow,
  .root:focus-visible .arrow {
    transform: none;
  }
}

@media (forced-colors: active) {
  .root {
    color: ButtonText;
    border-color: ButtonText;
    background: ButtonFace;
    box-shadow: none;
  }

  .lustre,
  .edge {
    display: none;
  }
}

demo.tsx


export { default as default } from "@/import-examples/lustre-button";

CSS

/*! tailwindcss v4.3.3 | MIT License | https://tailwindcss.com */
@layer properties;
@layer theme, base, components, utilities;
@layer theme {
  :root, :host {
    --default-transition-duration: 150ms;
    --default-transition-timing-function: cubic-bezier(0.4, 0, 0.2, 1);
    --default-font-family: var(--sans);
    --default-mono-font-family: var(--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 {
  .transform {
    transform: var(--tw-rotate-x,) var(--tw-rotate-y,) var(--tw-rotate-z,) var(--tw-skew-x,) var(--tw-skew-y,);
  }
  .border {
    border-style: var(--tw-border-style);
    border-width: 1px;
  }
  .outline {
    outline-style: var(--tw-outline-style);
    outline-width: 1px;
  }
  .filter {
    filter: var(--tw-blur,) var(--tw-brightness,) var(--tw-contrast,) var(--tw-grayscale,) var(--tw-hue-rotate,) var(--tw-invert,) var(--tw-saturate,) var(--tw-sepia,) var(--tw-drop-shadow,);
  }
  .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));
  }
}
: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 {
  --page-max: 1180px;
  --page-gutter: clamp(20px, 4vw, 52px);
  --sans: -apple-system, BlinkMacSystemFont, 'SF Pro Text', 'Helvetica Neue',
    'Segoe UI', sans-serif;
  --mono: 'SFMono-Regular', 'SF Mono', 'Cascadia Code', Consolas, monospace;
  --bg: #f4f3ef;
  --text: #171716;
  --surface: #ffffff;
  --surface-2: #e9e8e3;
  --muted: #66645f;
  --line: rgb(23 23 22 / 9%);
  --line-strong: rgb(23 23 22 / 20%);
  --control-primary-bg: #1d1d1f;
  --control-primary-fg: #ffffff;
  --control-accent-subtle: #e8e8ea;
  --focus-ring: #1d1d1f;
  --red: #b23a31;
  --sidebar-active: #5d7300;
  --warm: #e4e0d7;
  --warm-text: #1a1917;
  --scrollbar-thumb: rgb(23 23 22 / 32%);
  --scrollbar-thumb-hover: rgb(23 23 22 / 48%);
  --landing-primary-bg: #1d1d1f;
  --landing-primary-text: #ffffff;
  --landing-secondary-bg: #e8e8ea;
  --landing-secondary-text: #1d1d1f;
  --hero-field: #e7e4dd;
  --hero-center: rgb(255 255 255 / 88%);
  --hero-cool-lustre: rgb(172 191 218 / 34%);
  --hero-warm-lustre: rgb(224 194 174 / 38%);
  --cta-text: #24231f;
  --cta-muted: #716f68;
  --cta-accent: #718a48;
  --cta-glow: rgb(126 157 82 / 10%);
  --cta-wash: rgb(255 255 255 / 46%);
  --cta-control-bg: rgb(23 23 22 / 4%);
  --cta-control-border: rgb(23 23 22 / 12%);
  --cta-control-highlight: rgb(255 255 255 / 68%);
  --cta-primary-bg: #1d1d1f;
  --cta-primary-text: #ffffff;
  --type-micro: 12px;
  --type-caption: 13px;
  --type-ui: 14px;
  --type-body: 16px;
  --type-lead: 18px;
}
.dark {
  --bg: #0b0b0a;
  --text: #f2f1ed;
  --surface: #171716;
  --surface-2: #222220;
  --muted: #9c9b95;
  --line: rgb(255 255 255 / 8%);
  --line-strong: rgb(255 255 255 / 17%);
  --control-primary-bg: #f5f5f7;
  --control-primary-fg: #111111;
  --control-accent-subtle: #242426;
  --focus-ring: #f5f5f7;
  --red: #ff9189;
  --sidebar-active: #d4ff00;
  --scrollbar-thumb: rgb(255 255 255 / 30%);
  --scrollbar-thumb-hover: rgb(255 255 255 / 46%);
  --landing-primary-bg: #f5f5f7;
  --landing-primary-text: #111111;
  --landing-secondary-bg: #242426;
  --landing-secondary-text: #f5f5f7;
  --hero-field: #11110f;
  --hero-center: rgb(255 255 255 / 7%);
  --hero-cool-lustre: rgb(88 105 132 / 23%);
  --hero-warm-lustre: rgb(105 73 58 / 22%);
  --cta-text: #f2f1ed;
  --cta-muted: #969691;
  --cta-accent: #a6bd7d;
  --cta-glow: rgb(183 216 135 / 7%);
  --cta-wash: rgb(255 255 255 / 3%);
  --cta-control-bg: rgb(255 255 255 / 4%);
  --cta-control-border: rgb(255 255 255 / 10%);
  --cta-control-highlight: rgb(255 255 255 / 4%);
  --cta-primary-bg: #f5f5f7;
  --cta-primary-text: #111111;
}
.dark .brand img {
  filter: invert(1);
  mix-blend-mode: screen;
}
.dark .theme-icon-light {
  display: none;
}
.dark .theme-icon-dark {
  display: block;
}
.dark .preview-theme-light {
  display: none;
}
.dark .preview-theme-dark {
  display: block;
}
@keyframes changelog-pulse {
  0%, 45% {
    opacity: 0.72;
    transform: scale(0.68);
  }
  80%, 100% {
    opacity: 0;
    transform: scale(1.35);
  }
}
.dark .changelog-rail-signature img {
  filter: invert(1);
  mix-blend-mode: screen;
}
@keyframes nacre-motion-sample {
  0%, 16% {
    left: 8%;
  }
  70%, 100% {
    left: calc(100% - 28px);
  }
}
.dark .home-cta-mark img {
  filter: invert(1);
}
.dark .docs-search-dialog::backdrop {
  background: rgb(0 0 0 / 52%);
}
.dark .docs-search-dialog {
  background: color-mix(in srgb, #0b0b0d 92%, transparent) !important;
  box-shadow: 0 40px 120px rgb(0 0 0 / 62%), inset 0 1px 0 rgb(255 255 255 / 5%);
}
@keyframes docs-search-enter {
  from {
    opacity: 0;
    transform: translate(-50%, -10px) scale(0.985);
  }
  to {
    opacity: 1;
    transform: translate(-50%, 0) scale(1);
  }
}
@keyframes docs-search-exit {
  from {
    opacity: 1;
    transform: translate(-50%, 0) scale(1);
  }
  to {
    opacity: 0;
    transform: translate(-50%, -6px) scale(0.99);
  }
}
.o {
  --lustre-color: #ffffff;
  --lustre-duration: 3.2s;
  position: relative;
  display: inline-grid;
  min-width: 190px;
  height: 50px;
  padding: 0 19px;
  place-items: center;
  overflow: hidden;
  border: 1px solid rgb(255 255 255 / 11%);
  border-radius: 13px;
  color: #f4f3ee;
  background: #151613;
  box-shadow: inset 0 1px #ffffff12,inset 0 -1px #00000047,0 12px 30px #00000038;
  cursor: pointer;
  isolation: isolate;
  transition: border-color 90ms ease-out,background 90ms ease-out,box-shadow .18s ease-out,transform 80ms cubic-bezier(.2,0,0,1);
}
.o:hover,.o:focus-visible {
  border-color: #ffffff30;
  background: #1a1b17;
  box-shadow: inset 0 1px #ffffff17,inset 0 -1px #00000047,0 16px 36px #00000047;
}
.o:active {
  box-shadow: inset 0 1px #ffffff0d,inset 0 2px 5px #0000004d,0 6px 14px #0000002e;
  transform: scale(.97);
}
.o:focus-visible {
  outline: 2px solid currentColor;
  outline-offset: 3px;
}
.o:disabled {
  cursor: not-allowed;
  opacity: .46;
  transform: none;
}
.e {
  position: absolute;
  z-index: -1;
  top: -60%;
  left: -42%;
  width: 34%;
  height: 220%;
  background: linear-gradient(90deg,transparent,var(--lustre-color) 34%,var(--lustre-color) 50%,var(--lustre-color) 66%,transparent);
  @supports (color: color-mix(in lab, red, red)) {
    background: linear-gradient(90deg,transparent,color-mix(in srgb,var(--lustre-color) 9%,transparent) 34%,color-mix(in srgb,var(--lustre-color) 24%,transparent) 50%,color-mix(in srgb,var(--lustre-color) 9%,transparent) 66%,transparent);
  }
  filter: blur(.5px);
  opacity: .78;
  pointer-events: none;
  transform: skew(-18deg) translate(0);
}
.o[data-motion=loop] .e {
  animation: t var(--lustre-duration) cubic-bezier(.4,0,.2,1) infinite;
}
.o[data-motion=hover] .e {
  opacity: 0;
  transform: skew(-18deg) translate(0);
}
.o[data-motion=hover]:hover .e,.o[data-motion=hover]:focus-visible .e {
  animation: n .68s cubic-bezier(.2,0,0,1) both;
}
.i {
  position: absolute;
  z-index: -1;
  inset: 1px;
  border-radius: 11px;
  background: linear-gradient(110deg,rgb(255 255 255 / 4%),transparent 28%,transparent 72%,rgb(255 255 255 / 3%));
  pointer-events: none;
}
.a {
  position: relative;
  display: inline-flex;
  align-items: center;
  gap: 11px;
  font-size: 13px;
  font-weight: 650;
  letter-spacing: -.013em;
  white-space: nowrap;
}
.r {
  width: 16px;
  height: 16px;
  stroke: currentColor;
  stroke-linecap: round;
  stroke-linejoin: round;
  stroke-width: 1.4;
  transition: transform .18s cubic-bezier(.2,0,0,1);
}
.o:hover .r,.o:focus-visible .r {
  transform: translate(2px);
}
.o:disabled .e {
  animation: none;
}
.o:disabled .r {
  transform: none;
}
@keyframes t {
  0%,54% {
    opacity: 0;
    transform: skew(-18deg) translate(0);
  }
  60% {
    opacity: .78;
  }
  82% {
    opacity: .78;
  }
  88%,to {
    opacity: 0;
    transform: skew(-18deg) translate(560%);
  }
}
@keyframes n {
  0% {
    opacity: 0;
    transform: skew(-18deg) translate(0);
  }
  16% {
    opacity: .78;
  }
  84% {
    opacity: .78;
  }
  to {
    opacity: 0;
    transform: skew(-18deg) translate(560%);
  }
}
@media (prefers-reduced-motion:reduce) {
  .o,.r {
    transition: none;
  }
  .e,.o[data-motion=loop] .e,.o[data-motion=hover]:hover .e,.o[data-motion=hover]:focus-visible .e {
    display: none;
    animation: none;
  }
  .o:active,.o:hover .r,.o:focus-visible .r {
    transform: none;
  }
}
@media (forced-colors:active) {
  .o {
    color: ButtonText;
    border-color: ButtonText;
    background: ButtonFace;
    box-shadow: none;
  }
  .e,.i {
    display: none;
  }
}
@property --tw-rotate-x {
  syntax: "*";
  inherits: false;
}
@property --tw-rotate-y {
  syntax: "*";
  inherits: false;
}
@property --tw-rotate-z {
  syntax: "*";
  inherits: false;
}
@property --tw-skew-x {
  syntax: "*";
  inherits: false;
}
@property --tw-skew-y {
  syntax: "*";
  inherits: false;
}
@property --tw-border-style {
  syntax: "*";
  inherits: false;
  initial-value: solid;
}
@property --tw-outline-style {
  syntax: "*";
  inherits: false;
  initial-value: solid;
}
@property --tw-blur {
  syntax: "*";
  inherits: false;
}
@property --tw-brightness {
  syntax: "*";
  inherits: false;
}
@property --tw-contrast {
  syntax: "*";
  inherits: false;
}
@property --tw-grayscale {
  syntax: "*";
  inherits: false;
}
@property --tw-hue-rotate {
  syntax: "*";
  inherits: false;
}
@property --tw-invert {
  syntax: "*";
  inherits: false;
}
@property --tw-opacity {
  syntax: "*";
  inherits: false;
}
@property --tw-saturate {
  syntax: "*";
  inherits: false;
}
@property --tw-sepia {
  syntax: "*";
  inherits: false;
}
@property --tw-drop-shadow {
  syntax: "*";
  inherits: false;
}
@property --tw-drop-shadow-color {
  syntax: "*";
  inherits: false;
}
@property --tw-drop-shadow-alpha {
  syntax: "<percentage>";
  inherits: false;
  initial-value: 100%;
}
@property --tw-drop-shadow-size {
  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-rotate-x: initial;
      --tw-rotate-y: initial;
      --tw-rotate-z: initial;
      --tw-skew-x: initial;
      --tw-skew-y: initial;
      --tw-border-style: solid;
      --tw-outline-style: solid;
      --tw-blur: initial;
      --tw-brightness: initial;
      --tw-contrast: initial;
      --tw-grayscale: initial;
      --tw-hue-rotate: initial;
      --tw-invert: initial;
      --tw-opacity: initial;
      --tw-saturate: initial;
      --tw-sepia: initial;
      --tw-drop-shadow: initial;
      --tw-drop-shadow-color: initial;
      --tw-drop-shadow-alpha: 100%;
      --tw-drop-shadow-size: initial;
    }
  }
}