Back to buttons
'use client';

import { GemSmoke } from '@paper-design/shaders-react';
import * as React from 'react';

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

import styles from './gem-smoke-button.module.css';

const defaultColors = ['#d8a7ff', '#ffb49a', '#87d9bc'];

export type GemSmokeButtonProps =
  React.ButtonHTMLAttributes<HTMLButtonElement> & {
    colors?: string[];
    speed?: number;
    smokeSize?: number;
  };

function subscribeToReducedMotion(callback: () => void) {
  const media = window.matchMedia('(prefers-reduced-motion: reduce)');
  media.addEventListener('change', callback);
  return () => media.removeEventListener('change', callback);
}

function getReducedMotion() {
  return window.matchMedia('(prefers-reduced-motion: reduce)').matches;
}

const GemSmokeButton = React.forwardRef<HTMLButtonElement, GemSmokeButtonProps>(
  function GemSmokeButton(
    {
      children = 'Reveal collection',
      className,
      colors = defaultColors,
      smokeSize = 0.82,
      speed = 0.4,
      type = 'button',
      ...props
    },
    ref,
  ) {
    const reduceMotion = React.useSyncExternalStore(
      subscribeToReducedMotion,
      getReducedMotion,
      () => false,
    );

    return (
      <button
        ref={ref}
        data-slot="gem-smoke-button"
        type={type}
        className={cn(styles.root, className)}
        {...props}
      >
        <span className={styles.material} aria-hidden="true">
          <GemSmoke
            width="100%"
            height="100%"
            colors={colors.slice(0, 6)}
            colorBack="#121114"
            colorInner="#f5f1eb"
            shape="metaballs"
            innerDistortion={0.78}
            outerDistortion={0.68}
            outerGlow={0.72}
            innerGlow={0.92}
            offset={-0.08}
            angle={18}
            size={Math.min(Math.max(smokeSize, 0.45), 1)}
            speed={reduceMotion ? 0 : Math.min(Math.max(speed, 0), 1.2)}
            scale={1.38}
            fit="cover"
            minPixelRatio={1}
            maxPixelCount={180_000}
          />
        </span>
        <span className={styles.scrim} aria-hidden="true" />
        <span className={styles.content}>
          <span>{children}</span>
          <span className={styles.gem} aria-hidden="true">
            <svg viewBox="0 0 18 18" fill="none">
              <path d="m9 2.5 5.5 4.2L12.4 15H5.6L3.5 6.7 9 2.5Z" />
              <path d="m3.8 6.8 5.2 2 5.2-2M9 8.8V15" />
            </svg>
          </span>
        </span>
      </button>
    );
  },
);

GemSmokeButton.displayName = 'GemSmokeButton';

export { GemSmokeButton };

Gem Smoke Button

By John Mamanao

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

About Gem Smoke Button

Gem Smoke 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/gem-smoke-button.tsx

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

components/ui/gem-smoke-button.tsx

'use client';

import { GemSmoke } from '@paper-design/shaders-react';
import * as React from 'react';

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

import styles from './gem-smoke-button.module.css';

const defaultColors = ['#d8a7ff', '#ffb49a', '#87d9bc'];

export type GemSmokeButtonProps =
  React.ButtonHTMLAttributes<HTMLButtonElement> & {
    colors?: string[];
    speed?: number;
    smokeSize?: number;
  };

function subscribeToReducedMotion(callback: () => void) {
  const media = window.matchMedia('(prefers-reduced-motion: reduce)');
  media.addEventListener('change', callback);
  return () => media.removeEventListener('change', callback);
}

function getReducedMotion() {
  return window.matchMedia('(prefers-reduced-motion: reduce)').matches;
}

const GemSmokeButton = React.forwardRef<HTMLButtonElement, GemSmokeButtonProps>(
  function GemSmokeButton(
    {
      children = 'Reveal collection',
      className,
      colors = defaultColors,
      smokeSize = 0.82,
      speed = 0.4,
      type = 'button',
      ...props
    },
    ref,
  ) {
    const reduceMotion = React.useSyncExternalStore(
      subscribeToReducedMotion,
      getReducedMotion,
      () => false,
    );

    return (
      <button
        ref={ref}
        data-slot="gem-smoke-button"
        type={type}
        className={cn(styles.root, className)}
        {...props}
      >
        <span className={styles.material} aria-hidden="true">
          <GemSmoke
            width="100%"
            height="100%"
            colors={colors.slice(0, 6)}
            colorBack="#121114"
            colorInner="#f5f1eb"
            shape="metaballs"
            innerDistortion={0.78}
            outerDistortion={0.68}
            outerGlow={0.72}
            innerGlow={0.92}
            offset={-0.08}
            angle={18}
            size={Math.min(Math.max(smokeSize, 0.45), 1)}
            speed={reduceMotion ? 0 : Math.min(Math.max(speed, 0), 1.2)}
            scale={1.38}
            fit="cover"
            minPixelRatio={1}
            maxPixelCount={180_000}
          />
        </span>
        <span className={styles.scrim} aria-hidden="true" />
        <span className={styles.content}>
          <span>{children}</span>
          <span className={styles.gem} aria-hidden="true">
            <svg viewBox="0 0 18 18" fill="none">
              <path d="m9 2.5 5.5 4.2L12.4 15H5.6L3.5 6.7 9 2.5Z" />
              <path d="m3.8 6.8 5.2 2 5.2-2M9 8.8V15" />
            </svg>
          </span>
        </span>
      </button>
    );
  },
);

GemSmokeButton.displayName = 'GemSmokeButton';

export { GemSmokeButton };

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/gem-smoke-button.module.css

.root {
  position: relative;
  display: inline-grid;
  min-width: 200px;
  height: 50px;
  padding: 0 10px 0 18px;
  place-items: center;
  overflow: hidden;
  border: 1px solid rgb(255 255 255 / 14%);
  border-radius: 13px;
  color: #f7f5f0;
  background: #121114;
  box-shadow:
    inset 0 1px rgb(255 255 255 / 8%),
    0 14px 32px rgb(0 0 0 / 26%);
  cursor: pointer;
  isolation: isolate;
  transition:
    border-color 90ms ease-out,
    box-shadow 180ms ease-out,
    transform 90ms cubic-bezier(0.2, 0, 0, 1);
}

.root:hover,
.root:focus-visible {
  border-color: rgb(255 255 255 / 28%);
  box-shadow:
    inset 0 1px rgb(255 255 255 / 12%),
    0 18px 40px rgb(0 0 0 / 34%);
  transform: translateY(-1px);
}

.root:active {
  box-shadow:
    inset 0 2px 7px rgb(0 0 0 / 30%),
    0 7px 16px rgb(0 0 0 / 22%);
  transform: translateY(0) scale(0.98);
}

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

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

.material,
.scrim {
  position: absolute;
  z-index: -2;
  inset: 0;
  pointer-events: none;
}

.material {
  transform: scale(1.08);
  transition: transform 500ms cubic-bezier(0.4, 0, 0.2, 1);
}

.material canvas {
  display: block;
  width: 100% !important;
  height: 100% !important;
}

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

.scrim {
  z-index: -1;
  background: linear-gradient(90deg, rgb(9 8 10 / 64%), rgb(9 8 10 / 16%));
  transition: opacity 220ms ease-out;
}

.root:hover .scrim,
.root:focus-visible .scrim {
  opacity: 0.68;
}

.content {
  position: relative;
  display: flex;
  width: 100%;
  align-items: center;
  justify-content: space-between;
  gap: 16px;
  text-shadow: 0 1px 6px rgb(0 0 0 / 56%);
  font-size: 13px;
  font-weight: 660;
  letter-spacing: -0.013em;
  white-space: nowrap;
}

.gem {
  display: grid;
  width: 31px;
  height: 31px;
  flex: 0 0 31px;
  place-items: center;
  border: 1px solid rgb(255 255 255 / 14%);
  border-radius: 9px;
  background: rgb(10 9 11 / 34%);
  backdrop-filter: blur(5px);
  transition: transform 220ms cubic-bezier(0.2, 0, 0, 1);
}

.gem svg {
  width: 17px;
  height: 17px;
  stroke: currentColor;
  stroke-linecap: round;
  stroke-linejoin: round;
  stroke-width: 1.15;
}

.root:hover .gem,
.root:focus-visible .gem {
  transform: rotate(6deg) scale(1.04);
}

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

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

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

  .material,
  .scrim {
    display: none;
  }

  .content {
    text-shadow: none;
  }

  .gem {
    border-color: ButtonText;
    background: ButtonFace;
    backdrop-filter: none;
  }
}

demo.tsx


export { default as default } from "@/import-examples/gem-smoke-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 {
  .flex {
    display: flex;
  }
  .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;
  }
  .backdrop-filter {
    -webkit-backdrop-filter: var(--tw-backdrop-blur,) var(--tw-backdrop-brightness,) var(--tw-backdrop-contrast,) var(--tw-backdrop-grayscale,) var(--tw-backdrop-hue-rotate,) var(--tw-backdrop-invert,) var(--tw-backdrop-opacity,) var(--tw-backdrop-saturate,) var(--tw-backdrop-sepia,);
    backdrop-filter: var(--tw-backdrop-blur,) var(--tw-backdrop-brightness,) var(--tw-backdrop-contrast,) var(--tw-backdrop-grayscale,) var(--tw-backdrop-hue-rotate,) var(--tw-backdrop-invert,) var(--tw-backdrop-opacity,) var(--tw-backdrop-saturate,) var(--tw-backdrop-sepia,);
  }
  .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);
  }
}
.e {
  position: relative;
  display: inline-grid;
  min-width: 200px;
  height: 50px;
  padding: 0 10px 0 18px;
  place-items: center;
  overflow: hidden;
  border: 1px solid rgb(255 255 255 / 14%);
  border-radius: 13px;
  color: #f7f5f0;
  background: #121114;
  box-shadow: inset 0 1px #ffffff14,0 14px 32px #00000042;
  cursor: pointer;
  isolation: isolate;
  transition: border-color 90ms ease-out,box-shadow .18s ease-out,transform 90ms cubic-bezier(.2,0,0,1);
}
.e:hover,.e:focus-visible {
  border-color: #ffffff47;
  box-shadow: inset 0 1px #ffffff1f,0 18px 40px #00000057;
  transform: translateY(-1px);
}
.e:active {
  box-shadow: inset 0 2px 7px #0000004d,0 7px 16px #00000038;
  transform: translateY(0) scale(.98);
}
.e:focus-visible {
  outline: 2px solid #f7f5f0;
  outline-offset: 3px;
}
.e:disabled {
  cursor: not-allowed;
  opacity: .46;
  transform: none;
}
.o,.t {
  position: absolute;
  z-index: -2;
  inset: 0;
  pointer-events: none;
}
.o {
  transform: scale(1.08);
  transition: transform .5s cubic-bezier(.4,0,.2,1);
}
.o canvas {
  display: block;
  width: 100% !important;
  height: 100% !important;
}
.e:hover .o,.e:focus-visible .o {
  transform: scale(1.18) translate(2px);
}
.t {
  z-index: -1;
  background: linear-gradient(90deg,#09080aa3,#09080a29);
  transition: opacity .22s ease-out;
}
.e:hover .t,.e:focus-visible .t {
  opacity: .68;
}
.i {
  position: relative;
  display: flex;
  width: 100%;
  align-items: center;
  justify-content: space-between;
  gap: 16px;
  text-shadow: 0 1px 6px rgb(0 0 0 / 56%);
  font-size: 13px;
  font-weight: 660;
  letter-spacing: -.013em;
  white-space: nowrap;
}
.r {
  display: grid;
  width: 31px;
  height: 31px;
  flex: 0 0 31px;
  place-items: center;
  border: 1px solid rgb(255 255 255 / 14%);
  border-radius: 9px;
  background: #0a090b57;
  backdrop-filter: blur(5px);
  transition: transform .22s cubic-bezier(.2,0,0,1);
}
.r svg {
  width: 17px;
  height: 17px;
  stroke: currentColor;
  stroke-linecap: round;
  stroke-linejoin: round;
  stroke-width: 1.15;
}
.e:hover .r,.e:focus-visible .r {
  transform: rotate(6deg) scale(1.04);
}
@media (prefers-reduced-motion:reduce) {
  .e,.o,.t,.r {
    transition: none;
  }
  .e:hover,.e:active,.e:hover .o,.e:focus-visible .o,.e:hover .r,.e:focus-visible .r {
    transform: none;
  }
}
@media (forced-colors:active) {
  .e {
    color: ButtonText;
    border-color: ButtonText;
    background: ButtonFace;
    box-shadow: none;
  }
  .o,.t {
    display: none;
  }
  .i {
    text-shadow: none;
  }
  .r {
    border-color: ButtonText;
    background: ButtonFace;
    backdrop-filter: 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-backdrop-blur {
  syntax: "*";
  inherits: false;
}
@property --tw-backdrop-brightness {
  syntax: "*";
  inherits: false;
}
@property --tw-backdrop-contrast {
  syntax: "*";
  inherits: false;
}
@property --tw-backdrop-grayscale {
  syntax: "*";
  inherits: false;
}
@property --tw-backdrop-hue-rotate {
  syntax: "*";
  inherits: false;
}
@property --tw-backdrop-invert {
  syntax: "*";
  inherits: false;
}
@property --tw-backdrop-opacity {
  syntax: "*";
  inherits: false;
}
@property --tw-backdrop-saturate {
  syntax: "*";
  inherits: false;
}
@property --tw-backdrop-sepia {
  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-backdrop-blur: initial;
      --tw-backdrop-brightness: initial;
      --tw-backdrop-contrast: initial;
      --tw-backdrop-grayscale: initial;
      --tw-backdrop-hue-rotate: initial;
      --tw-backdrop-invert: initial;
      --tw-backdrop-opacity: initial;
      --tw-backdrop-saturate: initial;
      --tw-backdrop-sepia: initial;
    }
  }
}