{
  "$schema": "https://ui.shadcn.com/schema/registry-item.json",
  "name": "aurora-background",
  "title": "Aurora Background",
  "description": "Light with height and direction: curtains from the top, a glow from the bottom edge, a ring behind the centre or one diagonal ribbon, with an optional slow drift.",
  "dependencies": [
    "motion"
  ],
  "registryDependencies": [
    "utils",
    "https://miseui.junsu4621.workers.dev/r/mesh-background.json"
  ],
  "files": [
    {
      "path": "registry/miseui/ui/aurora-background.tsx",
      "content": "import type * as React from \"react\"\nimport { driftStyle, useDrift } from \"@/registry/miseui/ui/mesh-background-drift\"\nimport { cn } from \"@/registry/miseui/lib/utils\"\n\ntype AuroraBackgroundVariant = \"curtain\" | \"horizon\" | \"halo\" | \"ribbon\"\ntype AuroraBackgroundEffect = \"drift\"\ntype AuroraTone = 1 | 2 | 3\n\ninterface AuroraBand {\n  /** Percent of the background. */\n  left: number\n  width: number\n  height: number\n  tone: AuroraTone\n  opacity: number\n}\n\n/** Lives with the component. Curtains sway and stretch along their own height, the halo turns, the ribbon slides along its length. */\nconst KEYFRAMES =\n  \"@keyframes mise-aurora-sway-a{from{transform:translateX(-8%) scaleY(.94)}to{transform:translateX(8%) scaleY(1.05)}}\" +\n  \"@keyframes mise-aurora-sway-b{from{transform:translateX(7%) scaleY(1.05)}to{transform:translateX(-7%) scaleY(.95)}}\" +\n  \"@keyframes mise-aurora-turn{to{transform:rotate(360deg)}}\" +\n  \"@keyframes mise-aurora-slide{from{transform:translateX(-6%)}to{transform:translateX(6%)}}\"\n\n/** Same reasoning as mesh: hue walks away from 100, lightness clamped per theme so a near-black accent becomes silver and a near-white one fog. */\nconst TONES_CLASS =\n  \"[--mise-aurora-1:var(--mise)] [--mise-aurora-2:var(--mise)] [--mise-aurora-3:var(--mise)] supports-[color:oklch(from_red_l_c_h)]:[--mise-aurora-1:oklch(from_var(--mise)_clamp(0.62,l,0.78)_c_h)] supports-[color:oklch(from_red_l_c_h)]:[--mise-aurora-2:oklch(from_var(--mise)_clamp(0.62,l,0.78)_c_calc(h_+_40_*_sin((h_-_100)_*_1deg)))] supports-[color:oklch(from_red_l_c_h)]:[--mise-aurora-3:oklch(from_var(--mise)_clamp(0.62,l,0.78)_c_calc(h_+_80_*_sin((h_-_100)_*_1deg)))] dark:supports-[color:oklch(from_red_l_c_h)]:[--mise-aurora-1:oklch(from_var(--mise)_clamp(0.5,l,0.68)_c_h)] dark:supports-[color:oklch(from_red_l_c_h)]:[--mise-aurora-2:oklch(from_var(--mise)_clamp(0.5,l,0.68)_c_calc(h_+_40_*_sin((h_-_100)_*_1deg)))] dark:supports-[color:oklch(from_red_l_c_h)]:[--mise-aurora-3:oklch(from_var(--mise)_clamp(0.5,l,0.68)_c_calc(h_+_80_*_sin((h_-_100)_*_1deg)))]\"\n\n/**\n * Ellipses hanging from the top edge: this height and direction is what separates aurora from mesh. No filter, so swaying costs one transform each.\n * They overlap into one sheet of light. Narrow separate ones read as icicles.\n */\nconst CURTAINS: readonly AuroraBand[] = [\n  { left: -8, width: 42, height: 78, tone: 1, opacity: 0.3 },\n  { left: 12, width: 34, height: 100, tone: 2, opacity: 0.28 },\n  { left: 34, width: 38, height: 70, tone: 1, opacity: 0.24 },\n  { left: 54, width: 30, height: 92, tone: 3, opacity: 0.28 },\n  { left: 70, width: 40, height: 100, tone: 2, opacity: 0.26 },\n]\n\n/** The same ellipses from the bottom edge, nested wide to narrow like light behind a hill. */\nconst HORIZONS: readonly AuroraBand[] = [\n  { left: -20, width: 140, height: 78, tone: 1, opacity: 0.36 },\n  { left: 12, width: 76, height: 50, tone: 2, opacity: 0.4 },\n  { left: 34, width: 32, height: 28, tone: 3, opacity: 0.4 },\n]\n\nconst HALO_MASK = \"radial-gradient(closest-side,transparent 44%,#000 72%,transparent 100%)\"\nconst HALO_STYLE: React.CSSProperties = {\n  inset: 0,\n  borderRadius: \"50%\",\n  backgroundImage: \"conic-gradient(from 20deg in oklab,var(--mise-aurora-1),var(--mise-aurora-2),var(--mise-aurora-3),var(--mise-aurora-2),var(--mise-aurora-1))\",\n  maskImage: HALO_MASK,\n  WebkitMaskImage: HALO_MASK,\n}\nconst RIBBON_MASK = \"linear-gradient(to bottom,transparent,#000 50%,transparent)\"\nconst RIBBON_STYLE: React.CSSProperties = {\n  inset: 0,\n  backgroundImage: \"linear-gradient(90deg in oklab,var(--mise-aurora-1),var(--mise-aurora-2) 50%,var(--mise-aurora-3))\",\n  maskImage: RIBBON_MASK,\n  WebkitMaskImage: RIBBON_MASK,\n}\n\ntype MotionFor = (name: string, seconds: number, steady?: boolean) => React.CSSProperties | undefined\n\nfunction Bands({ bands, edge, motionFor }: { bands: readonly AuroraBand[]; edge: \"top\" | \"bottom\"; motionFor: MotionFor }) {\n  const anchor = edge === \"top\" ? \"0%\" : \"100%\"\n  return bands.map((band, index) => (\n    <div\n      key={`${band.left}-${band.width}`}\n      data-slot=\"aurora-background-band\"\n      className=\"absolute\"\n      style={{\n        left: `${band.left}%`,\n        width: `${band.width}%`,\n        height: `${band.height}%`,\n        top: edge === \"top\" ? 0 : undefined,\n        bottom: edge === \"bottom\" ? 0 : undefined,\n        backgroundImage: `radial-gradient(50% 100% at 50% ${anchor},var(--mise-aurora-${band.tone}),transparent)`,\n        opacity: band.opacity,\n        transformOrigin: `50% ${anchor}`,\n        ...motionFor(index % 2 ? \"mise-aurora-sway-b\" : \"mise-aurora-sway-a\", 26 + index * 7),\n      }}\n    />\n  ))\n}\n\nfunction Drawing({ variant, motionFor }: { variant: AuroraBackgroundVariant; motionFor: MotionFor }) {\n  if (variant === \"curtain\") {\n    return (\n      // Leaning wider than the box, so the slant never shows a bare top corner.\n      <div className=\"absolute inset-y-0 -inset-x-[8%] -skew-x-6\">\n        <Bands bands={CURTAINS} edge=\"top\" motionFor={motionFor} />\n      </div>\n    )\n  }\n  if (variant === \"horizon\") return <Bands bands={HORIZONS} edge=\"bottom\" motionFor={motionFor} />\n  if (variant === \"halo\") {\n    return (\n      // Sized from the shorter side, and the ring ends inside its own box, so it always fades before the edge.\n      <div className=\"absolute inset-0 [container-type:size]\">\n        <div className=\"absolute top-1/2 left-1/2 size-[96cqmin] -translate-x-1/2 -translate-y-1/2 opacity-35\">\n          <div data-slot=\"aurora-background-halo\" className=\"absolute\" style={{ ...HALO_STYLE, ...motionFor(\"mise-aurora-turn\", 90, true) }} />\n        </div>\n      </div>\n    )\n  }\n  return (\n    // Longer than any box at this angle, so its ends are never seen.\n    <div className=\"absolute top-1/2 -left-[40%] h-[46%] w-[180%] -translate-y-1/2 -rotate-[16deg] opacity-40\">\n      <div data-slot=\"aurora-background-ribbon\" className=\"absolute\" style={{ ...RIBBON_STYLE, ...motionFor(\"mise-aurora-slide\", 34) }} />\n    </div>\n  )\n}\n\ntype AuroraBackgroundProps = React.ComponentProps<\"div\"> & {\n  /** `curtain` vertical bands from the top, `horizon` glow rising from the bottom edge, `halo` a soft ring behind the centre, `ribbon` one long diagonal band. */\n  variant?: AuroraBackgroundVariant\n  /** `drift` sways the light very slowly. It stops off screen and in a hidden tab. */\n  effect?: AuroraBackgroundEffect\n  /** Holds the drift. Tie it to a pause control: motion past five seconds needs a way to stop it. */\n  paused?: boolean\n}\n\nfunction AuroraBackground({ variant = \"curtain\", effect, paused = false, className, children, ...props }: AuroraBackgroundProps) {\n  const { ref, moving, playing } = useDrift(effect === \"drift\", paused)\n  const motionFor: MotionFor = (name, seconds, steady) => (moving ? driftStyle(name, seconds, playing, steady) : undefined)\n  return (\n    <div\n      {...props}\n      data-slot=\"aurora-background\"\n      data-variant={variant}\n      data-effect={effect}\n      data-playing={moving ? (playing ? \"true\" : \"false\") : undefined}\n      className={cn(\"relative isolate overflow-clip\", className)}\n    >\n      {moving ? <style href=\"mise-aurora-background\" precedence=\"default\">{KEYFRAMES}</style> : null}\n      <div ref={ref} aria-hidden=\"true\" data-slot=\"aurora-background-layer\" className={cn(\"pointer-events-none absolute inset-0 rounded-[inherit] contrast-more:hidden forced-colors:hidden\", TONES_CLASS)}>\n        <Drawing variant={variant} motionFor={motionFor} />\n      </div>\n      <div data-slot=\"aurora-background-content\" className=\"relative h-full min-h-[inherit]\">\n        {children}\n      </div>\n    </div>\n  )\n}\n\nexport { AuroraBackground, type AuroraBackgroundProps, type AuroraBackgroundVariant, type AuroraBackgroundEffect }\n",
      "type": "registry:ui"
    }
  ],
  "categories": [
    "backgrounds"
  ],
  "type": "registry:ui"
}