Buttons

Lift Shadow Button

A button that lifts off the surface: three shadow layers grow and blur along with the rise, and a press puts it back on the table.

  • button
  • shadow
  • hover
  • elevation

Preview

1440pxHost theme

Use it with AI

  1. 1. Copy the link.
  2. 2. Write to your agent in your own words and drop the link into the sentence.
  3. 3. The agent opens the link and installs the component from the registry.

put this in the header: https://vibeui.ru/c/button-043?lang=en

Show the full instructions

What the link says, spelled out. Use it when your agent cannot open links — paste this text instead.

# Install and place "button-043" (Lift Shadow Button) from VibeUI

## 1. Install first — do not skip, do not recreate
Run this exact command before writing any code:
npx shadcn@latest add https://vibeui.ru/r/button-043.json

Registry item: https://vibeui.ru/r/button-043.json
Installs to: components/vibeui/button-043.tsx (the exact path follows this project's components.json aliases).
npm dependencies: none.
Registry dependencies: none.

Install it from the registry. Do not recreate it from the description,
do not substitute a similar component from another library, and do not
rewrite it to match the project's existing style.

## 2. What it is
A button that lifts off the surface: three shadow layers grow and blur along with the rise, and a press puts it back on the table.

A light button with the physics of a lift. At rest a three-layer shadow sits beneath it: a hard contact, a middle halo and a distant blur. On hover the button rises while the far layers grow and soften — the object has left the table. On press only the contact layer remains. Zero dependencies, one file.

## 3. How to use it
import { Button043 } from "@/components/vibeui/button-043"

<Button043 lift={6} onClick={openCard}>Open card</Button043>

Read the installed file for the full prop list.

## 4. Where to place it
This is a small inline component. Put it exactly where the user asked,
inside the existing markup. Do not create a new page, section or
wrapper for it. If a similar control already sits in that spot,
replace it instead of adding a second one.

Placement: ___
(The user fills this line in. If it is still blank, ask where to put it
instead of guessing.)

## 5. Keep exactly as installed
- the three shadow layers: a single blurred layer reads as a halo, not as height
- the unblurred contact layer — it keeps the object tied to the surface at any height
- the offset and the blur growing together: a shadow that merely shifts looks painted on
- the return on :active down to a single contact shadow — that is the press
- cubic-bezier(0.16,1,0.3,1): on linear easing the lift reads as a jerk
- the light surface of the button — the shadow is built on contrast with it, and the dark label stays readable

## 6. You may change
- the label
- the lift height through the lift prop, in pixels
- the mark's accent colour through the accent prop
- the onClick handler and the rest of the native button props
- the shadow colour through the --vibeui-button-043-shadow variable in the style block

## 7. Rules
- Do not line these buttons up densely: neighbouring elements lifting at once create visual noise.
- Do not set lift above 12px — any higher and the shadow detaches from the button and looks borrowed.
- Do not collapse the three-layer shadow into one box-shadow for brevity: the sense of height goes with it.
- Do not lift the CSS variables into globals.css: the component has to stay a single file.

## 8. Verify
- it renders with no console errors;
- it looks like the preview on the VibeUI page you copied this from;
- if it does not, you changed something listed in section 5 — put it back.

For developers

npx shadcn@latest add https://vibeui.ru/r/button-043.json
https://vibeui.ru/r/button-043.json

Компонент самодостаточен: один файл, без зависимостей, собственная палитра в локальных переменных --vibeui-button-043-*. Серверный компонент, корень — сам <button>. Тень собрана из трёх слоёв: контактного без размытия, среднего и дальнего; на наведении меняются смещение и размытие двух дальних, контактный остаётся. Высота подъёма вынесена в переменную --vibeui-button-043-lift и задаётся пропом lift в пикселях. Переходы идут на cubic-bezier(0.16,1,0.3,1).

Component source

The same file your agent installs. Here in case you would rather copy it by hand.

import type { ComponentPropsWithoutRef, CSSProperties } from "react"

export type Button043Props = ComponentPropsWithoutRef<"button"> & {
  /** Высота подъёма на наведении в пикселях. */
  lift?: number
  accent?: string
}

// Идея компонента: физика подъёма. Тень собрана из трёх слоёв — контактной,
// средней и дальней; на наведении кнопка уезжает вверх, а тени одновременно
// растут и размываются, как у предмета, оторвавшегося от стола. На :active
// подъём обнуляется и остаётся только контактная тень — предмет прижали.
const STYLES = `
:where([data-vibeui-block="button-043"]){
--vibeui-button-043-lift:6px;
--vibeui-button-043-surface:oklch(1 0 0);
--vibeui-button-043-border:oklch(0.9 0.006 265);
--vibeui-button-043-fg:oklch(0.24 0.02 265);
--vibeui-button-043-accent:oklch(0.58 0.16 45);
--vibeui-button-043-shadow:oklch(0.3 0.03 265 / 22%);
--vibeui-button-043-font:ui-sans-serif,system-ui,-apple-system,"Segoe UI",Roboto,"Helvetica Neue",Arial,sans-serif;
}
[data-vibeui-block="button-043"]{
appearance:none;cursor:pointer;box-sizing:border-box;
display:inline-flex;align-items:center;gap:0.5rem;
height:2.75rem;padding:0 1.125rem;border-radius:0.75rem;
border:1px solid var(--vibeui-button-043-border);
background:var(--vibeui-button-043-surface);color:var(--vibeui-button-043-fg);
font-family:var(--vibeui-button-043-font);font-size:0.875rem;font-weight:650;line-height:1;
box-shadow:
0 1px 1px var(--vibeui-button-043-shadow),
0 2px 4px -2px var(--vibeui-button-043-shadow),
0 4px 10px -6px var(--vibeui-button-043-shadow);
transition:transform .2s cubic-bezier(0.16,1,0.3,1),box-shadow .2s cubic-bezier(0.16,1,0.3,1);
}
[data-vibeui-block="button-043"]:hover:not(:disabled){
transform:translateY(calc(-1 * var(--vibeui-button-043-lift)));
box-shadow:
0 1px 1px var(--vibeui-button-043-shadow),
0 8px 14px -8px var(--vibeui-button-043-shadow),
0 20px 34px -18px var(--vibeui-button-043-shadow);
}
/* Нажатие возвращает предмет на стол: остаётся только контактная тень. */
[data-vibeui-block="button-043"]:active:not(:disabled){
transform:translateY(1px);
box-shadow:0 1px 1px var(--vibeui-button-043-shadow);
}
[data-vibeui-block="button-043"]:focus-visible{outline:2px solid var(--vibeui-button-043-accent);outline-offset:3px}
[data-vibeui-block="button-043"]:disabled{cursor:not-allowed;opacity:.55;box-shadow:none}
[data-vibeui-block="button-043"] [data-part="chip"]{
flex:none;width:1.375rem;height:1.375rem;border-radius:0.4375rem;
background:color-mix(in oklab,var(--vibeui-button-043-accent) 18%,transparent);
position:relative;
}
[data-vibeui-block="button-043"] [data-part="chip"]::after{
content:"";position:absolute;left:50%;top:50%;width:0.5rem;height:0.5rem;
margin:-0.25rem 0 0 -0.25rem;border-radius:2px;
background:var(--vibeui-button-043-accent);
}
@media (prefers-reduced-motion:reduce){[data-vibeui-block="button-043"]{transition:none!important}}
`

/**
 * Кнопка с тенью-подъёмом: на наведении отрывается от поверхности.
 * Один файл, ноль зависимостей, собственная палитра.
 */
export function Button043({
  lift = 6,
  accent,
  type = "button",
  className,
  style,
  children = "Открыть карточку",
  ...props
}: Button043Props) {
  const palette = {
    "--vibeui-button-043-lift": `${lift}px`,
    ...(accent ? { "--vibeui-button-043-accent": accent } : null),
    ...style,
  } as CSSProperties

  return (
    <>
      <style href="vibeui-button-043" precedence="medium">
        {STYLES}
      </style>
      <button
        {...props}
        type={type}
        data-vibeui-block="button-043"
        className={className}
        style={palette}
      >
        <span data-part="chip" aria-hidden="true" />
        {children}
      </button>
    </>
  )
}