{
  "$schema": "https://ui.shadcn.com/schema/registry-item.json",
  "name": "elevated",
  "title": "elevated",
  "description": "A utility function for elevated.",
  "files": [
    {
      "path": "registry/default/lib/elevated.tsx",
      "content": "import type * as React from \"react\";\r\n\r\nimport { cn } from \"@/lib/utils\";\r\n\r\nexport type SurfaceLevel = 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8;\r\n\r\nexport const SURFACE_BG: Record<SurfaceLevel, string> = {\r\n  1: \"bg-surface-1\",\r\n  2: \"bg-surface-2\",\r\n  3: \"bg-surface-3\",\r\n  4: \"bg-surface-4\",\r\n  5: \"bg-surface-5\",\r\n  6: \"bg-surface-6\",\r\n  7: \"bg-surface-7\",\r\n  8: \"bg-surface-8\",\r\n};\r\n\r\nexport const SURFACE_SHADOW: Record<SurfaceLevel, string> = {\r\n  1: \"shadow-surface-1\",\r\n  2: \"shadow-surface-2\",\r\n  3: \"shadow-surface-3\",\r\n  4: \"shadow-surface-4\",\r\n  5: \"shadow-surface-5\",\r\n  6: \"shadow-surface-6\",\r\n  7: \"shadow-surface-7\",\r\n  8: \"shadow-surface-8\",\r\n};\r\n\r\nexport const SURFACE_RIM: Record<SurfaceLevel, string> = {\r\n  1: \"after:shadow-surface-rim-1\",\r\n  2: \"after:shadow-surface-rim-2\",\r\n  3: \"after:shadow-surface-rim-3\",\r\n  4: \"after:shadow-surface-rim-4\",\r\n  5: \"after:shadow-surface-rim-5\",\r\n  6: \"after:shadow-surface-rim-6\",\r\n  7: \"after:shadow-surface-rim-7\",\r\n  8: \"after:shadow-surface-rim-8\",\r\n};\r\n\r\n/**\r\n * Exposes the surface level to descendants as `--popup-surface` so children\r\n * (arrow fills, sticky labels, fade gradients) can track the popup's level\r\n * via `bg-(--popup-surface,var(--popover))`.\r\n */\r\nexport const SURFACE_VAR: Record<SurfaceLevel, string> = {\r\n  1: \"[--popup-surface:var(--surface-1)]\",\r\n  2: \"[--popup-surface:var(--surface-2)]\",\r\n  3: \"[--popup-surface:var(--surface-3)]\",\r\n  4: \"[--popup-surface:var(--surface-4)]\",\r\n  5: \"[--popup-surface:var(--surface-5)]\",\r\n  6: \"[--popup-surface:var(--surface-6)]\",\r\n  7: \"[--popup-surface:var(--surface-7)]\",\r\n  8: \"[--popup-surface:var(--surface-8)]\",\r\n};\r\n\r\n/**\r\n * Drops + rim insets in a single `box-shadow` (no `::after`). Used by `solidSurface()`.\r\n * Literal Tailwind classes so the scanner picks them up.\r\n */\r\nexport const SURFACE_SHADOW_COMBINED: Record<SurfaceLevel, string> = {\r\n  1: \"shadow-[var(--surface-shadow-1),var(--surface-rim-1)]\",\r\n  2: \"shadow-[var(--surface-shadow-2),var(--surface-rim-2)]\",\r\n  3: \"shadow-[var(--surface-shadow-3),var(--surface-rim-3)]\",\r\n  4: \"shadow-[var(--surface-shadow-4),var(--surface-rim-4)]\",\r\n  5: \"shadow-[var(--surface-shadow-5),var(--surface-rim-5)]\",\r\n  6: \"shadow-[var(--surface-shadow-6),var(--surface-rim-6)]\",\r\n  7: \"shadow-[var(--surface-shadow-7),var(--surface-rim-7)]\",\r\n  8: \"shadow-[var(--surface-shadow-8),var(--surface-rim-8)]\",\r\n};\r\n\r\nexport function surfaceClasses(\r\n  level: SurfaceLevel,\r\n  shadowLevel: SurfaceLevel = level,\r\n): string {\r\n  return `${SURFACE_BG[level]} ${SURFACE_SHADOW[shadowLevel]} ${SURFACE_VAR[level]}`;\r\n}\r\n\r\n/**\r\n * Like `surfaceClasses`, but adds a `::after` overlay that re-paints the rim\r\n * above the container's children. Use on elevated containers with opaque\r\n * children near their edges (sticky labels, pinned inputs, dialog headers).\r\n *\r\n * Host requirements: positioned, `border-radius` class, clipped overflow.\r\n * Overlay is `z-index: 2` — bump if children exceed that.\r\n */\r\nexport function elevatedSurface(\r\n  level: SurfaceLevel,\r\n  shadowLevel: SurfaceLevel = level,\r\n): string {\r\n  return `${SURFACE_BG[level]} ${SURFACE_SHADOW[shadowLevel]} ${SURFACE_RIM[level]} ${SURFACE_VAR[level]} after:pointer-events-none after:absolute after:inset-0 after:rounded-[inherit] after:z-[2]`;\r\n}\r\n\r\n/**\r\n * Like `elevatedSurface`, but paints the rim in the popup's own `box-shadow`\r\n * (no `::after`) — leaves `::after` free for other purposes. Use for elevated\r\n * containers with no opaque children near their edges; switch to\r\n * `elevatedSurface()` if you add a sticky/opaque child.\r\n *\r\n * When `level !== shadowLevel` the rim color tracks `shadowLevel`; for\r\n * independent rim/drop control use `elevatedSurface` instead.\r\n */\r\nexport function solidSurface(\r\n  level: SurfaceLevel,\r\n  shadowLevel: SurfaceLevel = level,\r\n): string {\r\n  return `${SURFACE_BG[level]} ${SURFACE_SHADOW_COMBINED[shadowLevel]} ${SURFACE_VAR[level]}`;\r\n}\r\n\r\n/**\r\n * `::after` classes for a 1px inset rim on a single edge — for viewport-flush\r\n * containers (Sheet/Drawer) so the rim only shows on the inner-facing edge.\r\n * Color is `--surface-rim-color` (transparent in light, ~4% white in dark).\r\n */\r\nexport const SURFACE_RIM_EDGE: Record<\r\n  \"top\" | \"bottom\" | \"left\" | \"right\",\r\n  string\r\n> = {\r\n  top: \"after:shadow-[inset_0_1px_0_0_var(--surface-rim-color)]\",\r\n  bottom: \"after:shadow-[inset_0_-1px_0_0_var(--surface-rim-color)]\",\r\n  left: \"after:shadow-[inset_1px_0_0_0_var(--surface-rim-color)]\",\r\n  right: \"after:shadow-[inset_-1px_0_0_0_var(--surface-rim-color)]\",\r\n};\r\n\r\n/**\r\n * `::after` overlay with a 1px rim on the specified inner-facing edge.\r\n * Pair with `surfaceClasses()` (NOT `elevatedSurface()`) for flush variants.\r\n */\r\nexport function innerEdgeRim(\r\n  innerEdge: \"top\" | \"bottom\" | \"left\" | \"right\",\r\n): string {\r\n  return `after:pointer-events-none after:absolute after:inset-0 after:rounded-[inherit] after:z-[2] ${SURFACE_RIM_EDGE[innerEdge]}`;\r\n}\r\n\r\n/** Maps attach-side → inner-facing edge for `innerEdgeRim`. */\r\nexport const INNER_EDGE_FROM_ATTACH_SIDE: Record<\r\n  \"top\" | \"bottom\" | \"left\" | \"right\",\r\n  \"top\" | \"bottom\" | \"left\" | \"right\"\r\n> = {\r\n  top: \"bottom\",\r\n  bottom: \"top\",\r\n  left: \"right\",\r\n  right: \"left\",\r\n};\r\n\r\n/**\r\n * Directional drop shadow for a viewport-flush surface: casts toward the\r\n * inner-facing edge (into the content) rather than always straight down. A\r\n * flush surface only sheds shadow on the one edge that isn't pinned to the\r\n * viewport, so the radial `--surface-shadow-N` recipe (which casts down on\r\n * every surface) points the wrong way for top/bottom/left attach sides.\r\n *\r\n * This is the level-5 recipe, rotated per edge. It matches the floating\r\n * variant's edge ring EXACTLY by mirroring how that recipe handles the ring\r\n * per mode: the base shadow uses --surface-shadow-ring (light: 6%) and the\r\n * `dark:` shadow inlines oklch(0 0 0 / 0.16) (the level-5 dark ring). The drop\r\n * layers reference --surface-shadow-near/mid/far, which already redefine per\r\n * mode, so they're identical between the two and don't need splitting.\r\n * The ring casts on all four edges — the three viewport-pinned ones fall\r\n * off-screen.\r\n */\r\nexport const INNER_EDGE_SHADOW: Record<\r\n  \"top\" | \"bottom\" | \"left\" | \"right\",\r\n  string\r\n> = {\r\n  left: \"shadow-[0_0_0_1px_var(--surface-shadow-ring),-1px_0_1px_-0.5px_var(--surface-shadow-near),-3px_0_3px_-1.5px_var(--surface-shadow-mid),-6px_0_6px_-3px_var(--surface-shadow-mid),-12px_0_12px_-6px_var(--surface-shadow-far)] dark:shadow-[0_0_0_1px_oklch(0_0_0/0.16),-1px_0_1px_-0.5px_var(--surface-shadow-near),-3px_0_3px_-1.5px_var(--surface-shadow-mid),-6px_0_6px_-3px_var(--surface-shadow-mid),-12px_0_12px_-6px_var(--surface-shadow-far)]\",\r\n  right:\r\n    \"shadow-[0_0_0_1px_var(--surface-shadow-ring),1px_0_1px_-0.5px_var(--surface-shadow-near),3px_0_3px_-1.5px_var(--surface-shadow-mid),6px_0_6px_-3px_var(--surface-shadow-mid),12px_0_12px_-6px_var(--surface-shadow-far)] dark:shadow-[0_0_0_1px_oklch(0_0_0/0.16),1px_0_1px_-0.5px_var(--surface-shadow-near),3px_0_3px_-1.5px_var(--surface-shadow-mid),6px_0_6px_-3px_var(--surface-shadow-mid),12px_0_12px_-6px_var(--surface-shadow-far)]\",\r\n  top: \"shadow-[0_0_0_1px_var(--surface-shadow-ring),0_-1px_1px_-0.5px_var(--surface-shadow-near),0_-3px_3px_-1.5px_var(--surface-shadow-mid),0_-6px_6px_-3px_var(--surface-shadow-mid),0_-12px_12px_-6px_var(--surface-shadow-far)] dark:shadow-[0_0_0_1px_oklch(0_0_0/0.16),0_-1px_1px_-0.5px_var(--surface-shadow-near),0_-3px_3px_-1.5px_var(--surface-shadow-mid),0_-6px_6px_-3px_var(--surface-shadow-mid),0_-12px_12px_-6px_var(--surface-shadow-far)]\",\r\n  bottom:\r\n    \"shadow-[0_0_0_1px_var(--surface-shadow-ring),0_1px_1px_-0.5px_var(--surface-shadow-near),0_3px_3px_-1.5px_var(--surface-shadow-mid),0_6px_6px_-3px_var(--surface-shadow-mid),0_12px_12px_-6px_var(--surface-shadow-far)] dark:shadow-[0_0_0_1px_oklch(0_0_0/0.16),0_1px_1px_-0.5px_var(--surface-shadow-near),0_3px_3px_-1.5px_var(--surface-shadow-mid),0_6px_6px_-3px_var(--surface-shadow-mid),0_12px_12px_-6px_var(--surface-shadow-far)]\",\r\n};\r\n\r\n/**\r\n * Flush-surface elevation: bg + a directional drop shadow cast toward the\r\n * inner edge + the single-edge inset rim on that edge. Use for viewport-flush\r\n * containers (Sheet/Drawer `default` variant) instead of `solidSurface` (whose\r\n * all-around, downward shadow only suits a free-floating surface). `innerEdge`\r\n * is the content-facing edge — derive it from the attach side via\r\n * `INNER_EDGE_FROM_ATTACH_SIDE`.\r\n */\r\nexport function flushSurface(\r\n  level: SurfaceLevel,\r\n  innerEdge: \"top\" | \"bottom\" | \"left\" | \"right\",\r\n): string {\r\n  return `${SURFACE_BG[level]} ${SURFACE_VAR[level]} ${INNER_EDGE_SHADOW[innerEdge]} ${innerEdgeRim(innerEdge)}`;\r\n}\r\n\r\nexport interface ElevatedProps extends React.ComponentProps<\"div\"> {\r\n  level: SurfaceLevel;\r\n  shadowLevel?: SurfaceLevel;\r\n}\r\n\r\nfunction Elevated({\r\n  level,\r\n  shadowLevel,\r\n  className,\r\n  ...props\r\n}: ElevatedProps) {\r\n  return (\r\n    <div\r\n      data-slot=\"elevated\"\r\n      data-level={level}\r\n      className={cn(surfaceClasses(level, shadowLevel ?? level), className)}\r\n      {...props}\r\n    />\r\n  );\r\n}\r\n\r\nexport { Elevated };\r\n",
      "type": "registry:lib",
      "target": "lib/cubby-ui/elevated.tsx"
    }
  ],
  "type": "registry:lib"
}