"use client";
import * as React from "react";
import { motion, type HTMLMotionProps } from "motion/react";
import { cn } from "@/lib/utils";
type ThreeDButtonProps = HTMLMotionProps<"button"> & {
children?: React.ReactNode;
};
const pressTransition = {
type: "spring",
stiffness: 620,
damping: 32,
mass: 0.5,
} as const;
export function ThreeDButton({
className,
children = "Continue",
...props
}: ThreeDButtonProps) {
return (
<motion.button
initial="rest"
whileHover="hover"
whileTap="tap"
className={cn(
"group relative isolate inline-flex min-w-38 cursor-pointer rounded-full pb-1.5 outline-none",
"focus-visible:ring-2 focus-visible:ring-zinc-500 focus-visible:ring-offset-2",
"dark:focus-visible:ring-white",
"disabled:pointer-events-none disabled:opacity-50",
className,
)}
{...props}
>
{/* Deck (bottom layer / shadow block) */}
<motion.span
aria-hidden
variants={{
rest: { y: 0 },
hover: { y: 1 },
tap: { y: -1 },
}}
transition={pressTransition}
className="absolute inset-x-0 bottom-0 top-1.5 -z-10 rounded-full bg-zinc-950 shadow-[0_10px_18px_rgba(24,24,27,0.2)] dark:bg-white dark:shadow-[0_10px_18px_rgba(255,255,255,0.15)]"
/>
{/* Face (top layer / button surface) */}
<motion.span
variants={{
// Whole-pixel moves only: tilting or fractionally scaling the face makes
// Chrome drop anti-aliasing on its edge, which shows up as a dashed rim.
rest: { y: 0 },
hover: { y: -2 },
tap: { y: 6 },
}}
transition={pressTransition}
className={cn(
"relative z-10 inline-flex w-full items-center justify-center overflow-hidden rounded-full px-7 py-3",
"bg-zinc-50 text-sm font-semibold text-zinc-950 dark:bg-zinc-900 dark:text-white",
// The rim is an inset ring rather than a border so it stays smooth while the face moves.
"shadow-[inset_0_0_0_1px_rgb(212_212_216),inset_0_2px_0_rgba(255,255,255,0.9),inset_0_-2px_0_rgba(24,24,27,0.06)]",
"dark:shadow-[inset_0_0_0_1px_rgb(255_255_255),inset_0_2px_0_rgba(255,255,255,0.15),inset_0_-2px_0_rgba(0,0,0,0.3)]",
"backface-hidden will-change-transform",
)}
>
{/* Press spot (darkens on press) */}
<motion.span
aria-hidden
variants={{
rest: { opacity: 0, scaleX: 0.25 },
hover: { opacity: 0.3, scaleX: 0.45 },
tap: { opacity: 1, scaleX: 1 },
}}
transition={pressTransition}
className="pointer-events-none absolute inset-y-1 left-1/2 w-10 -translate-x-1/2 rounded-full bg-zinc-950/10 dark:bg-white/20 blur-sm"
/>
{/* Sheen / gloss stripe */}
<motion.span
aria-hidden
variants={{
// Parked fully off the left edge so no sliver of it shows at rest.
rest: { opacity: 0, x: "-100%" },
hover: { opacity: 0.75, x: "-35%" },
tap: { opacity: 0.9, x: "82%" },
}}
transition={pressTransition}
className="pointer-events-none absolute inset-y-0 left-0 w-1/2 bg-linear-to-r from-transparent via-white to-transparent dark:via-white/20"
/>
{/* Label */}
<motion.span
variants={{
rest: { y: 0 },
hover: { y: -1 },
tap: { y: 1 },
}}
transition={pressTransition}
className="relative z-10"
>
{children}
</motion.span>
</motion.span>
</motion.button>
);
}
ThreeDButton
By jay sharma
Try the interaction, copy the React source files, or download the complete example.
About ThreeDButton
ThreeDButton is an animated React and Tailwind CSS button by jay sharma. 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/3d-button.tsx
import { ThreeDButton } from "@/components/evil-buttons/3d-button";
export function ButtonDemo() {
return (
<ThreeDButton>
Continue
</ThreeDButton>
);
}
components/evil-buttons/3d-button.tsx
"use client";
import * as React from "react";
import { motion, type HTMLMotionProps } from "motion/react";
import { cn } from "@/lib/utils";
type ThreeDButtonProps = HTMLMotionProps<"button"> & {
children?: React.ReactNode;
};
const pressTransition = {
type: "spring",
stiffness: 620,
damping: 32,
mass: 0.5,
} as const;
export function ThreeDButton({
className,
children = "Continue",
...props
}: ThreeDButtonProps) {
return (
<motion.button
initial="rest"
whileHover="hover"
whileTap="tap"
className={cn(
"group relative isolate inline-flex min-w-38 cursor-pointer rounded-full pb-1.5 outline-none",
"focus-visible:ring-2 focus-visible:ring-zinc-500 focus-visible:ring-offset-2",
"dark:focus-visible:ring-white",
"disabled:pointer-events-none disabled:opacity-50",
className,
)}
{...props}
>
{/* Deck (bottom layer / shadow block) */}
<motion.span
aria-hidden
variants={{
rest: { y: 0 },
hover: { y: 1 },
tap: { y: -1 },
}}
transition={pressTransition}
className="absolute inset-x-0 bottom-0 top-1.5 -z-10 rounded-full bg-zinc-950 shadow-[0_10px_18px_rgba(24,24,27,0.2)] dark:bg-white dark:shadow-[0_10px_18px_rgba(255,255,255,0.15)]"
/>
{/* Face (top layer / button surface) */}
<motion.span
variants={{
// Whole-pixel moves only: tilting or fractionally scaling the face makes
// Chrome drop anti-aliasing on its edge, which shows up as a dashed rim.
rest: { y: 0 },
hover: { y: -2 },
tap: { y: 6 },
}}
transition={pressTransition}
className={cn(
"relative z-10 inline-flex w-full items-center justify-center overflow-hidden rounded-full px-7 py-3",
"bg-zinc-50 text-sm font-semibold text-zinc-950 dark:bg-zinc-900 dark:text-white",
// The rim is an inset ring rather than a border so it stays smooth while the face moves.
"shadow-[inset_0_0_0_1px_rgb(212_212_216),inset_0_2px_0_rgba(255,255,255,0.9),inset_0_-2px_0_rgba(24,24,27,0.06)]",
"dark:shadow-[inset_0_0_0_1px_rgb(255_255_255),inset_0_2px_0_rgba(255,255,255,0.15),inset_0_-2px_0_rgba(0,0,0,0.3)]",
"backface-hidden will-change-transform",
)}
>
{/* Press spot (darkens on press) */}
<motion.span
aria-hidden
variants={{
rest: { opacity: 0, scaleX: 0.25 },
hover: { opacity: 0.3, scaleX: 0.45 },
tap: { opacity: 1, scaleX: 1 },
}}
transition={pressTransition}
className="pointer-events-none absolute inset-y-1 left-1/2 w-10 -translate-x-1/2 rounded-full bg-zinc-950/10 dark:bg-white/20 blur-sm"
/>
{/* Sheen / gloss stripe */}
<motion.span
aria-hidden
variants={{
// Parked fully off the left edge so no sliver of it shows at rest.
rest: { opacity: 0, x: "-100%" },
hover: { opacity: 0.75, x: "-35%" },
tap: { opacity: 0.9, x: "82%" },
}}
transition={pressTransition}
className="pointer-events-none absolute inset-y-0 left-0 w-1/2 bg-linear-to-r from-transparent via-white to-transparent dark:via-white/20"
/>
{/* Label */}
<motion.span
variants={{
rest: { y: 0 },
hover: { y: -1 },
tap: { y: 1 },
}}
transition={pressTransition}
className="relative z-10"
>
{children}
</motion.span>
</motion.span>
</motion.button>
);
}
lib/utils.ts
import { clsx, type ClassValue } from "clsx"
import { twMerge } from "tailwind-merge"
export function cn(...inputs: ClassValue[]) {
return twMerge(clsx(inputs))
}
demo.tsx
export { ButtonDemo as default } from "@/import-examples/3d-button";CSS
/*! tailwindcss v4.3.3 | MIT License | https://tailwindcss.com */
@layer properties;
@layer theme, base, components, utilities;
@layer theme {
:root, :host {
--color-zinc-50: oklch(98.5% 0 none);
--color-zinc-500: oklch(55.2% 0.016 285.938);
--color-zinc-900: oklch(21% 0.006 285.885);
--color-zinc-950: oklch(14.1% 0.005 285.823);
--color-white: #fff;
--spacing: 0.25rem;
--text-sm: 0.875rem;
--text-sm--line-height: calc(1.25 / 0.875);
--font-weight-semibold: 600;
--blur-sm: 8px;
--default-transition-duration: 150ms;
--default-transition-timing-function: cubic-bezier(0.4, 0, 0.2, 1);
--default-font-family: var(--font-geist-sans), ui-sans-serif, system-ui, sans-serif;
--default-mono-font-family: var(--font-geist-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;
}
.inset-x-0 {
inset-inline: 0px;
}
.inset-y-0 {
inset-block: 0px;
}
.inset-y-1 {
inset-block: var(--spacing);
}
.top-1\.5 {
top: calc(var(--spacing) * 1.5);
}
.bottom-0 {
bottom: 0px;
}
.left-0 {
left: 0px;
}
.left-1\/2 {
left: calc(1 / 2 * 100%);
}
.isolate {
isolation: isolate;
}
.-z-10 {
z-index: calc(10 * -1);
}
.z-10 {
z-index: 10;
}
.inline-flex {
display: inline-flex;
}
.w-1\/2 {
width: calc(1 / 2 * 100%);
}
.w-10 {
width: calc(var(--spacing) * 10);
}
.w-full {
width: 100%;
}
.min-w-38 {
min-width: calc(var(--spacing) * 38);
}
.-translate-x-1\/2 {
--tw-translate-x: calc(calc(1 / 2 * 100%) * -1);
translate: var(--tw-translate-x) var(--tw-translate-y);
}
.cursor-pointer {
cursor: pointer;
}
.items-center {
align-items: center;
}
.justify-center {
justify-content: center;
}
.overflow-hidden {
overflow: hidden;
}
.rounded-full {
border-radius: calc(infinity * 1px);
}
.border {
border-style: var(--tw-border-style);
border-width: 1px;
}
.bg-zinc-50 {
background-color: var(--color-zinc-50);
}
.bg-zinc-950 {
background-color: var(--color-zinc-950);
}
.bg-zinc-950\/10 {
background-color: color-mix(in srgb, oklch(14.1% 0.005 285.823) 10%, transparent);
@supports (color: color-mix(in lab, red, red)) {
background-color: color-mix(in oklab, var(--color-zinc-950) 10%, transparent);
}
}
.bg-linear-to-r {
--tw-gradient-position: to right;
@supports (background-image: linear-gradient(in lab, red, red)) {
--tw-gradient-position: to right in oklab;
}
background-image: linear-gradient(var(--tw-gradient-stops));
}
.from-transparent {
--tw-gradient-from: transparent;
--tw-gradient-stops: var(--tw-gradient-via-stops, var(--tw-gradient-position), var(--tw-gradient-from) var(--tw-gradient-from-position), var(--tw-gradient-to) var(--tw-gradient-to-position));
}
.via-white {
--tw-gradient-via: var(--color-white);
--tw-gradient-via-stops: var(--tw-gradient-position), var(--tw-gradient-from) var(--tw-gradient-from-position), var(--tw-gradient-via) var(--tw-gradient-via-position), var(--tw-gradient-to) var(--tw-gradient-to-position);
--tw-gradient-stops: var(--tw-gradient-via-stops);
}
.to-transparent {
--tw-gradient-to: transparent;
--tw-gradient-stops: var(--tw-gradient-via-stops, var(--tw-gradient-position), var(--tw-gradient-from) var(--tw-gradient-from-position), var(--tw-gradient-to) var(--tw-gradient-to-position));
}
.px-7 {
padding-inline: calc(var(--spacing) * 7);
}
.py-3 {
padding-block: calc(var(--spacing) * 3);
}
.pb-1\.5 {
padding-bottom: 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-zinc-950 {
color: var(--color-zinc-950);
}
.shadow {
--tw-shadow: 0 1px 3px 0 var(--tw-shadow-color, rgb(0 0 0 / 0.1)), 0 1px 2px -1px var(--tw-shadow-color, rgb(0 0 0 / 0.1));
box-shadow: var(--tw-inset-shadow), var(--tw-inset-ring-shadow), var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow);
}
.shadow-\[0_10px_18px_rgba\(24\,24\,27\,0\.2\)\] {
--tw-shadow: 0 10px 18px var(--tw-shadow-color, rgba(24,24,27,0.2));
box-shadow: var(--tw-inset-shadow), var(--tw-inset-ring-shadow), var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow);
}
.shadow-\[inset_0_0_0_1px_rgb\(212_212_216\)\,inset_0_2px_0_rgba\(255\,255\,255\,0\.9\)\,inset_0_-2px_0_rgba\(24\,24\,27\,0\.06\)\] {
--tw-shadow: inset 0 0 0 1px var(--tw-shadow-color, rgb(212 212 216)), inset 0 2px 0 var(--tw-shadow-color, rgba(255,255,255,0.9)), inset 0 -2px 0 var(--tw-shadow-color, rgba(24,24,27,0.06));
box-shadow: var(--tw-inset-shadow), var(--tw-inset-ring-shadow), var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow);
}
.ring {
--tw-ring-shadow: var(--tw-ring-inset,) 0 0 0 calc(1px + var(--tw-ring-offset-width)) var(--tw-ring-color, currentcolor);
box-shadow: var(--tw-inset-shadow), var(--tw-inset-ring-shadow), var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow);
}
.blur-sm {
--tw-blur: blur(var(--blur-sm));
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));
}
.will-change-transform {
will-change: transform;
}
.outline-none {
--tw-outline-style: none;
outline-style: none;
}
.backface-hidden {
backface-visibility: hidden;
}
.focus-visible\:ring-2:focus-visible {
--tw-ring-shadow: var(--tw-ring-inset,) 0 0 0 calc(2px + var(--tw-ring-offset-width)) var(--tw-ring-color, currentcolor);
box-shadow: var(--tw-inset-shadow), var(--tw-inset-ring-shadow), var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow);
}
.focus-visible\:ring-zinc-500:focus-visible {
--tw-ring-color: var(--color-zinc-500);
}
.focus-visible\:ring-offset-2:focus-visible {
--tw-ring-offset-width: 2px;
--tw-ring-offset-shadow: var(--tw-ring-inset,) 0 0 0 var(--tw-ring-offset-width) var(--tw-ring-offset-color);
}
.disabled\:pointer-events-none:disabled {
pointer-events: none;
}
.disabled\:opacity-50:disabled {
opacity: 50%;
}
.dark\:bg-white:where(.dark, .dark *) {
background-color: var(--color-white);
}
.dark\:bg-white\/20:where(.dark, .dark *) {
background-color: color-mix(in srgb, #fff 20%, transparent);
@supports (color: color-mix(in lab, red, red)) {
background-color: color-mix(in oklab, var(--color-white) 20%, transparent);
}
}
.dark\:bg-zinc-900:where(.dark, .dark *) {
background-color: var(--color-zinc-900);
}
.dark\:via-white\/20:where(.dark, .dark *) {
--tw-gradient-via: color-mix(in srgb, #fff 20%, transparent);
@supports (color: color-mix(in lab, red, red)) {
--tw-gradient-via: color-mix(in oklab, var(--color-white) 20%, transparent);
}
--tw-gradient-via-stops: var(--tw-gradient-position), var(--tw-gradient-from) var(--tw-gradient-from-position), var(--tw-gradient-via) var(--tw-gradient-via-position), var(--tw-gradient-to) var(--tw-gradient-to-position);
--tw-gradient-stops: var(--tw-gradient-via-stops);
}
.dark\:text-white:where(.dark, .dark *) {
color: var(--color-white);
}
.dark\:shadow-\[0_10px_18px_rgba\(255\,255\,255\,0\.15\)\]:where(.dark, .dark *) {
--tw-shadow: 0 10px 18px var(--tw-shadow-color, rgba(255,255,255,0.15));
box-shadow: var(--tw-inset-shadow), var(--tw-inset-ring-shadow), var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow);
}
.dark\:shadow-\[inset_0_0_0_1px_rgb\(255_255_255\)\,inset_0_2px_0_rgba\(255\,255\,255\,0\.15\)\,inset_0_-2px_0_rgba\(0\,0\,0\,0\.3\)\]:where(.dark, .dark *) {
--tw-shadow: inset 0 0 0 1px var(--tw-shadow-color, rgb(255 255 255)), inset 0 2px 0 var(--tw-shadow-color, rgba(255,255,255,0.15)), inset 0 -2px 0 var(--tw-shadow-color, rgba(0,0,0,0.3));
box-shadow: var(--tw-inset-shadow), var(--tw-inset-ring-shadow), var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow);
}
.dark\:focus-visible\:ring-white:where(.dark, .dark *):focus-visible {
--tw-ring-color: var(--color-white);
}
}
: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 {
--card: oklch(1 0 0);
--muted: oklch(0.97 0 0);
--muted-foreground: oklch(0.556 0 0);
--border: oklch(0.922 0 0);
--primary: oklch(0.205 0 0);
--card-foreground: oklch(0.145 0 0);
--popover: oklch(1 0 0);
--popover-foreground: oklch(0.145 0 0);
--primary-foreground: oklch(0.985 0 0);
--secondary: oklch(0.97 0 0);
--secondary-foreground: oklch(0.205 0 0);
--accent: oklch(0.97 0 0);
--accent-foreground: oklch(0.205 0 0);
--destructive: oklch(0.577 0.245 27.325);
--input: oklch(0.922 0 0);
--ring: oklch(0.708 0 0);
--chart-1: oklch(0.87 0 0);
--chart-2: oklch(0.556 0 0);
--chart-3: oklch(0.439 0 0);
--chart-4: oklch(0.371 0 0);
--chart-5: oklch(0.269 0 0);
--radius: 0.625rem;
--sidebar: oklch(0.985 0 0);
--sidebar-foreground: oklch(0.145 0 0);
--sidebar-primary: oklch(0.205 0 0);
--sidebar-primary-foreground: oklch(0.985 0 0);
--sidebar-accent: oklch(0.97 0 0);
--sidebar-accent-foreground: oklch(0.205 0 0);
--sidebar-border: oklch(0.922 0 0);
--sidebar-ring: oklch(0.708 0 0);
--background: oklch(1 0 0);
--foreground: oklch(0.145 0 0);
--chrome: oklch(0.967 0 0);
--brand: oklch(0.6 0.23 29);
--chart-background: oklch(1 0 0);
--chart-foreground: oklch(0.145 0.004 285);
--chart-foreground-muted: oklch(0.55 0.014 260);
--chart-line-primary: var(--chart-1);
--chart-line-secondary: var(--chart-2);
--chart-crosshair: oklch(0.4 0.1828 274.34);
--chart-grid: oklch(0.9 0 0);
--chart-brush-border: var(--chart-grid);
--chart-tooltip-background: oklch(0.21 0.006 285 / 0.8);
--chart-tooltip-foreground: oklch(0.985 0 0);
--chart-tooltip-muted: oklch(0.65 0.01 260);
--chart-marker-background: oklch(0.97 0.005 260);
--chart-marker-border: oklch(0.85 0.01 260);
--chart-marker-foreground: oklch(0.3 0.01 260);
--chart-label: oklch(0.45 0.01 260);
--chart-scale-01: oklch(0.98 0.003 106);
--chart-scale-02: oklch(0.92 0.008 106);
--chart-scale-03: oklch(0.82 0.015 106);
--chart-scale-04: oklch(0.68 0.02 106);
--chart-scale-05: oklch(0.55 0.025 106);
--chart-scale-pattern-color: oklch(0.96 0.005 106);
}
.dark {
--background: oklch(0.145 0 0);
--foreground: oklch(0.985 0 0);
--chrome: oklch(0.18 0 0);
--card: oklch(0.205 0 0);
--muted: oklch(0.269 0 0);
--muted-foreground: oklch(0.708 0 0);
--border: oklch(1 0 0 / 10%);
--primary: oklch(0.922 0 0);
--card-foreground: oklch(0.985 0 0);
--popover: oklch(0.205 0 0);
--popover-foreground: oklch(0.985 0 0);
--primary-foreground: oklch(0.205 0 0);
--secondary: oklch(0.269 0 0);
--secondary-foreground: oklch(0.985 0 0);
--accent: oklch(0.269 0 0);
--accent-foreground: oklch(0.985 0 0);
--destructive: oklch(0.704 0.191 22.216);
--input: oklch(1 0 0 / 15%);
--ring: oklch(0.556 0 0);
--chart-1: oklch(0.87 0 0);
--chart-2: oklch(0.556 0 0);
--chart-3: oklch(0.439 0 0);
--chart-4: oklch(0.371 0 0);
--chart-5: oklch(0.269 0 0);
--sidebar: oklch(0.205 0 0);
--sidebar-foreground: oklch(0.985 0 0);
--sidebar-primary: oklch(0.922 0 0);
--sidebar-primary-foreground: oklch(0.205 0 0);
--sidebar-accent: oklch(0.269 0 0);
--sidebar-accent-foreground: oklch(0.985 0 0);
--sidebar-border: oklch(1 0 0 / 10%);
--sidebar-ring: oklch(0.556 0 0);
--brand: oklch(0.66 0.23 32);
--chart-background: oklch(0.145 0 0);
--chart-foreground: oklch(0.45 0 0);
--chart-foreground-muted: oklch(0.65 0.01 260);
--chart-crosshair: oklch(0.45 0 0);
--chart-grid: oklch(0.25 0 0);
--chart-brush-border: var(--chart-grid);
--chart-marker-background: oklch(0.25 0.01 260);
--chart-marker-border: oklch(0.4 0.01 260);
--chart-marker-foreground: oklch(0.9 0 0);
--chart-label: oklch(0.75 0.01 260);
--chart-scale-01: oklch(0.28 0.03 270);
--chart-scale-02: oklch(0.38 0.04 270);
--chart-scale-03: oklch(0.48 0.05 270);
--chart-scale-04: oklch(0.58 0.06 270);
--chart-scale-05: oklch(0.68 0.07 270);
--chart-scale-pattern-color: oklch(0.145 0 0);
}
@keyframes docs-dot-swing {
0%, 100% {
transform: translateX(0) scale(1);
}
45% {
transform: translateX(-6px) scale(0.7);
}
}
@keyframes hell-flicker {
0%, 100% {
opacity: 1;
}
41% {
opacity: 0.7;
}
43% {
opacity: 1;
}
77% {
opacity: 0.85;
}
78% {
opacity: 1;
}
}
@keyframes lights-off {
0% {
opacity: 0;
}
15% {
opacity: 1;
}
30% {
opacity: 0.2;
}
45% {
opacity: 1;
}
60% {
opacity: 0.5;
}
70%, 100% {
opacity: 1;
}
}
@keyframes lights-on {
0% {
opacity: 1;
}
20% {
opacity: 0;
}
32% {
opacity: 1;
}
50% {
opacity: 0.1;
}
60% {
opacity: 0.9;
}
75%, 100% {
opacity: 0;
}
}
@keyframes lights-fade {
to {
opacity: 0;
}
}
@keyframes eyes-dim {
from {
opacity: 0;
}
}
@keyframes eyes-open {
from {
opacity: 0;
transform: scaleY(0.05);
}
}
@keyframes eyes-blink {
0%, 92%, 100% {
transform: none;
}
95% {
transform: scaleY(0.08);
}
}
@keyframes crack-life {
0% {
opacity: 0;
transform: scale(0.92);
}
4% {
opacity: 1;
transform: none;
}
80% {
opacity: 1;
}
100% {
opacity: 0;
}
}
@keyframes egg-wobble {
0%, 84%, 100% {
transform: none;
}
87% {
transform: rotate(-14deg);
}
90% {
transform: rotate(10deg);
}
93% {
transform: rotate(-6deg);
}
96% {
transform: rotate(3deg);
}
}
@keyframes page-glitch {
0% {
transform: none;
filter: none;
clip-path: none;
}
12% {
transform: translate(-6px, 2px) skewX(-2deg);
filter: hue-rotate(90deg) saturate(3);
}
24% {
transform: translate(5px, -1px);
filter: invert(1) hue-rotate(180deg);
clip-path: inset(18% 0 52% 0);
}
36% {
transform: none;
filter: contrast(2.2) saturate(0);
clip-path: none;
}
48% {
transform: translate(9px, 0) skewX(4deg);
filter: hue-rotate(-60deg);
clip-path: inset(0 0 70% 0);
}
60% {
transform: translate(-3px, 3px);
filter: none;
clip-path: inset(40% 0 20% 0);
}
72% {
transform: translate(2px, -4px) scaleY(1.02);
filter: saturate(4) contrast(1.4);
clip-path: none;
}
86% {
transform: translate(-8px, 0);
filter: invert(1);
clip-path: inset(62% 0 8% 0);
}
}
@keyframes glitch-label {
0% {
transform: translate(0, 0);
opacity: 1;
}
33% {
transform: translate(-4px, 2px);
opacity: 0.6;
}
66% {
transform: translate(5px, -2px);
opacity: 1;
}
}
@keyframes deleted-progress {
from {
width: 0;
}
to {
width: 100%;
}
}
@keyframes deleted-restore {
0%, 70% {
opacity: 1;
}
100% {
opacity: 0;
}
}
@keyframes creeper-swell {
0% {
transform: scale(0.3) translateY(40px);
opacity: 0;
filter: none;
}
20% {
transform: scale(1);
opacity: 1;
}
45%, 65%, 85% {
filter: brightness(3) saturate(0);
}
55%, 75% {
filter: none;
}
100% {
transform: scale(1.35);
filter: brightness(4) saturate(0);
}
}
@keyframes creeper-flash {
from {
opacity: 0.85;
}
to {
opacity: 0;
}
}
@property --tw-translate-x {
syntax: "*";
inherits: false;
initial-value: 0;
}
@property --tw-translate-y {
syntax: "*";
inherits: false;
initial-value: 0;
}
@property --tw-translate-z {
syntax: "*";
inherits: false;
initial-value: 0;
}
@property --tw-border-style {
syntax: "*";
inherits: false;
initial-value: solid;
}
@property --tw-gradient-position {
syntax: "*";
inherits: false;
}
@property --tw-gradient-from {
syntax: "<color>";
inherits: false;
initial-value: #0000;
}
@property --tw-gradient-via {
syntax: "<color>";
inherits: false;
initial-value: #0000;
}
@property --tw-gradient-to {
syntax: "<color>";
inherits: false;
initial-value: #0000;
}
@property --tw-gradient-stops {
syntax: "*";
inherits: false;
}
@property --tw-gradient-via-stops {
syntax: "*";
inherits: false;
}
@property --tw-gradient-from-position {
syntax: "<length-percentage>";
inherits: false;
initial-value: 0%;
}
@property --tw-gradient-via-position {
syntax: "<length-percentage>";
inherits: false;
initial-value: 50%;
}
@property --tw-gradient-to-position {
syntax: "<length-percentage>";
inherits: false;
initial-value: 100%;
}
@property --tw-font-weight {
syntax: "*";
inherits: false;
}
@property --tw-shadow {
syntax: "*";
inherits: false;
initial-value: 0 0 #0000;
}
@property --tw-shadow-color {
syntax: "*";
inherits: false;
}
@property --tw-shadow-alpha {
syntax: "<percentage>";
inherits: false;
initial-value: 100%;
}
@property --tw-inset-shadow {
syntax: "*";
inherits: false;
initial-value: 0 0 #0000;
}
@property --tw-inset-shadow-color {
syntax: "*";
inherits: false;
}
@property --tw-inset-shadow-alpha {
syntax: "<percentage>";
inherits: false;
initial-value: 100%;
}
@property --tw-ring-color {
syntax: "*";
inherits: false;
}
@property --tw-ring-shadow {
syntax: "*";
inherits: false;
initial-value: 0 0 #0000;
}
@property --tw-inset-ring-color {
syntax: "*";
inherits: false;
}
@property --tw-inset-ring-shadow {
syntax: "*";
inherits: false;
initial-value: 0 0 #0000;
}
@property --tw-ring-inset {
syntax: "*";
inherits: false;
}
@property --tw-ring-offset-width {
syntax: "<length>";
inherits: false;
initial-value: 0px;
}
@property --tw-ring-offset-color {
syntax: "*";
inherits: false;
initial-value: #fff;
}
@property --tw-ring-offset-shadow {
syntax: "*";
inherits: false;
initial-value: 0 0 #0000;
}
@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-translate-x: 0;
--tw-translate-y: 0;
--tw-translate-z: 0;
--tw-border-style: solid;
--tw-gradient-position: initial;
--tw-gradient-from: #0000;
--tw-gradient-via: #0000;
--tw-gradient-to: #0000;
--tw-gradient-stops: initial;
--tw-gradient-via-stops: initial;
--tw-gradient-from-position: 0%;
--tw-gradient-via-position: 50%;
--tw-gradient-to-position: 100%;
--tw-font-weight: initial;
--tw-shadow: 0 0 #0000;
--tw-shadow-color: initial;
--tw-shadow-alpha: 100%;
--tw-inset-shadow: 0 0 #0000;
--tw-inset-shadow-color: initial;
--tw-inset-shadow-alpha: 100%;
--tw-ring-color: initial;
--tw-ring-shadow: 0 0 #0000;
--tw-inset-ring-color: initial;
--tw-inset-ring-shadow: 0 0 #0000;
--tw-ring-inset: initial;
--tw-ring-offset-width: 0px;
--tw-ring-offset-color: #fff;
--tw-ring-offset-shadow: 0 0 #0000;
--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;
}
}
}