Skip to content

Shine Button

Gradient pill button with a glossy top highlight and a bright light sweep crossing it on hover or keyboard focus (CSS only); renders an anchor when href is set. Two sizes.

glass/ui/shine-button
Open ↗

Source

import type { AnchorHTMLAttributes, ButtonHTMLAttributes, ReactNode } from "react";
import { cn } from "@/lib/utils";

type Common = { children?: ReactNode; size?: "md" | "lg"; className?: string };
export type ShineButtonProps = Common &
  (({ href?: undefined } & ButtonHTMLAttributes<HTMLButtonElement>) | ({ href: string } & AnchorHTMLAttributes<HTMLAnchorElement>));

/** Gradient pill with a glossy highlight and a light sweep that crosses it on hover/focus (CSS only). Renders a link when href is set. */
export function ShineButton({ children = "Start free", size = "md", className, ...rest }: ShineButtonProps) {
  const cls = cn(
    "glass-shine da-focus da-transition group relative inline-flex items-center justify-center gap-2 overflow-hidden rounded-da-pill bg-gradient-to-r from-da-primary to-da-accent font-semibold text-da-primary-fg shadow-da-md hover:-translate-y-0.5 hover:shadow-da-lg active:translate-y-0",
    size === "lg" ? "h-13 px-7 text-base" : "h-11 px-5 text-sm",
    className,
  );
  const inner = (
    <>
      <span aria-hidden className="absolute inset-x-3 top-0 h-1/2 rounded-b-full bg-gradient-to-b from-white/35 to-transparent" />
      <span
        aria-hidden
        className="glass-shine-sweep absolute inset-y-0 -left-1/2 w-1/3 skew-x-[-20deg] bg-gradient-to-r from-transparent via-white/55 to-transparent"
      />
      <span className="relative inline-flex items-center gap-2">{children}</span>
      <style href="glass-shine" precedence="default">{`
        .glass-shine-sweep { translate: -100% 0; transition: translate 0s }
        .glass-shine:hover .glass-shine-sweep, .glass-shine:focus-visible .glass-shine-sweep { translate: 450% 0; transition: translate .8s cubic-bezier(.2,.8,.2,1) }
        @media (prefers-reduced-motion: reduce) { .glass-shine-sweep { display: none } }
      `}</style>
    </>
  );
  if ("href" in rest && rest.href !== undefined) {
    return (
      <a {...(rest as AnchorHTMLAttributes<HTMLAnchorElement>)} className={cls}>
        {inner}
      </a>
    );
  }
  return (
    <button type="button" {...(rest as ButtonHTMLAttributes<HTMLButtonElement>)} className={cls}>
      {inner}
    </button>
  );
}

export default ShineButton;

modules/glass/ui/shine-button/index.tsx

Props

PropTypeDefaultDescription
childrenReactNode—Label and icons.
size"md" | "lg""md"Size.
hrefstring—Render as link.
...restbutton / anchor attributes—Forwarded.

Other button variants in Glass

Button in other art directions

Button

Pressable button with 6 variants (primary, secondary, ink, outline, ghost, danger), 4 sizes, icons, loading state and link mode (href). Hard shadow collapses on hover/press.

BrutalistButton

Copy Button

Code field with an attached yellow copy button that flips to green 'Copied' with a check; optional secret masking for API keys and custom display text for commands.

BrutalistButton

Segmented Control

Ruled segmented control for mutually exclusive options: mono uppercase segments split by strokes, ink selected segment, yellow hover. Controlled or uncontrolled, typed values.

BrutalistButton

Split Button

Yellow primary action glued to a chevron trigger that opens a ruled dropdown of secondary actions with descriptions (Radix DropdownMenu). Both halves flip to ink on hover.

BrutalistButton

Button

Compact button with 6 variants (indigo primary with inner highlight, ink secondary, outline, ghost, danger, link), 4 sizes, icons, keyboard-shortcut hint, loading state and link mode.

MinimalButton

Loading Button

Async action button that morphs through pending (spinner), success (green check) and error (red cross) states, then resets; all labels share one grid cell so the width never jumps.

MinimalButton

Shortcut Button

Button displaying its keyboard shortcut as keycaps; pressing the shortcut anywhere on the page clicks it (ignored while typing in a field). Primary, secondary and ghost styles.

MinimalButton

Toggle Group

Single-choice segmented toolbar on a muted track with a raised active segment (Radix ToggleGroup): text, icon-only or mixed options, two sizes, controlled or uncontrolled.

MinimalButton

Arrow Link

Text link with an ↗ that nudges up-right on hover and an ink underline that wipes in from the left; optional mono index prefix; scales from inline to display size.

Mono CleanButton

Button

Square monochrome button: ink primary, outlined (inverts on hover), ghost and underline (signal-colored underline) variants; three sizes and an optional trailing glyph.

Mono CleanButton

Icon Button

Square icon-only button with a hairline border (darkens on hover), ghost or solid ink variant; required label for aria-label and title.

Mono CleanButton

Text Toggle

Typographic toggle: options are plain mono words separated by slashes; the active one is ink with a signal underline, others muted — radio semantics with arrow keys.

Mono CleanButton

Button

Corporate button: 6px radius, five variants (blue primary, bordered white secondary, ghost, danger, link), three sizes, leading/trailing icons.

Neo CorporateButton

Button Group

Attached segmented button group with shared borders (radio semantics) — for period pickers and view switchers. Selected segment gets a surface-2 fill and bold label.

Neo CorporateButton

Icon Button

Square icon-only button (secondary, ghost, primary, danger) with required aria-label, title tooltip and optional count/dot badge.

Neo CorporateButton

Loading Button

Async action button: idle → spinner + “Processing…” (aria-busy, width locked) → green check “Sent” for 2s → idle. Default simulates a 1.4s payment run.

Neo CorporateButton

Arrow Button

Link-button with a round arrow badge at its end: on hover the badge grows and the arrow turns from ↗ to →, a signature call-to-action for the DA.

Organic SoftButton

Button

Soft pill button: sage primary, sage-tint soft, terracotta clay, outlined ink and ghost variants; three sizes, icons, gentle hover.

Organic SoftButton

Icon Button

Round icon-only button in soft sage, sage, cream (with shadow) or ghost; required label used for aria-label and title.

Organic SoftButton

Segmented

Pill segmented control on a sand track: the selected pill is cream with a soft shadow and slides with a sliding indicator; radio semantics with arrow keys.

Organic SoftButton

Button

Friendly pill button: six variants (periwinkle primary, soft lavender, outline, ghost, danger, ink), three sizes, left/right icons, loading spinner and link mode, with a tiny bounce on hover.

Soft FlatButton

Fab

Floating action button: a big round periwinkle “+” that rotates into “×” and fans out labelled pastel speed-dial actions with a staggered bounce; closes on Escape or outside click.

Soft FlatButton

Icon Button

Round pastel icon button in six tones (neutral, peach, mint, lavender, butter, primary) and three sizes, with optional red counter bubble and a springy press.

Soft FlatButton

Toggle Chips

Row of pill toggle chips with emoji; selected chips fill periwinkle and show a popping check. Multiple or single selection, controlled or not.

Soft FlatButton