Skip to content
goodtabs UI
BrowseBrowse components

Raised panel

A hero surface with a hairline, a top shine and a large shadow, lit from below on request.

npx shadcn@latest add https://ui.goodtabs.co/r/raised-panel.json

With the @goodtabs namespace in components.json: npx shadcn@latest add @goodtabs/raised-panel

$ npx shadcn@latest add @goodtabs/raised-panel

Checking registry.

Added components/ui/raised-panel.tsx

Done in 1.2s

A panel holding a few lines of mono output, like a terminal.

With glow

Launch week

Lit from below

The glow sits behind the panel and spills past its edges, so it reads as light, not as a border.

The glow prop adds a soft light behind the panel, lit from below.

No padding

Overview
Activity
Members
Billing
Usage
Settings

padding none with a placeholder app grid filling the panel edge to edge.

Usage

import { RaisedPanel } from "@/components/ui/raised-panel"

<RaisedPanel glow padding="none">
  <img src="/screenshot.png" alt="The dashboard" />
</RaisedPanel>

Props

PropTypeDefaultDescription
glowbooleanfalseAdds a soft light behind the panel, lit from below.
padding"none" | "sm" | "default" | "lg""default"Inner padding: none, 12px, 20px or 32px.
as"div" | "section""div"The element rendered for the panel.

Source

raised-panel/raised-panel.tsx
import * as React from "react";
import { cn } from "@/lib/utils";

type Padding = "none" | "sm" | "default" | "lg";

type RaisedPanelProps = React.ComponentProps<"div"> & {
  /** Adds a soft light behind the panel, lit from below. */
  glow?: boolean;
  /** Inner padding: none, 12px, 20px or 32px. */
  padding?: Padding;
  /** The element rendered for the panel. */
  as?: "div" | "section";
};

const PADDING: Record<Padding, string> = {
  none: "",
  sm: "p-3",
  default: "p-5",
  lg: "p-8",
};

/**
 * A raised surface for a hero visual: card fill, hairline border, a 1px top shine and the large shadow.
 * Pass glow to light it from below the way a hero frame is lit.
 */
export function RaisedPanel({
  glow = false,
  padding = "default",
  as: Tag = "div",
  className,
  children,
  ...props
}: RaisedPanelProps) {
  const panel = (
    <Tag
      data-slot="raised-panel"
      data-padding={padding}
      className={cn(
        "relative w-full overflow-hidden rounded-lg border bg-card text-card-foreground shadow-lg inset-shadow-highlight",
        PADDING[padding],
        className,
      )}
      {...props}
    >
      {children}
    </Tag>
  );

  if (!glow) return panel;

  return (
    <div data-slot="raised-panel-glow" className="relative isolate w-full">
      <div
        aria-hidden="true"
        className="glow-backdrop pointer-events-none absolute -inset-x-12 -top-8 -bottom-16 -z-10"
      />
      {panel}
    </div>
  );
}

For AI agents

Hand your agent this page, the markdown at /components/raised-panel/prompt.md, or the Copy AI prompt button above.

When to use

  • The visual under a hero: a screenshot, a live demo or a terminal
  • One raised surface on a page that should sit above the rest
  • Around a placeholder while the real visual is being made

When not to use

  • For ordinary cards in a grid, where the shadow and glow would pile up
  • Inside dialogs or popovers, which already carry a shadow
  • For a browser mockup, use browser-frame

Agent notes

  • Server component. The glow adds a wrapper div with an absolutely positioned backdrop; className still lands on the panel itself
  • The shine is the inset-shadow-highlight utility, so it composes with shadow-lg. A consumer theme needs --highlight and --glow for the shine and glow to show
  • The glow spills 48px to the sides and 64px below the panel; give it room or clip it with overflow-hidden on a parent
  • padding none is for images and grids that should run edge to edge; the panel clips to its radius