# MosaicGlow

> Canvas mosaic of small tiles on a dark surface where a soft halo follows the cursor with a lag, lighting tiles to random gold intensities that decay into a comet trail, with an additive bloom over the gaps, a glassy per-tile highlight, ambient flicker and an autonomous drift when idle.

- Package: `fancy-ui-svelte` (Svelte 5 + Tailwind CSS v4)
- Category: Backgrounds
- Tags: canvas, grid, mosaic, glow, cursor, halo, trail, background, interactive
- Types: `MosaicGlowProps`, `MosaicGlowIdle`
- Docs: https://fancy-ui.rama.app/docs/components/mosaic-glow
- Source: https://github.com/RamaHerbin/fancy-ui/tree/main/src/lib/fancy-ui/mosaic-glow

## Import

```svelte
<script lang="ts">
  import { MosaicGlow } from 'fancy-ui-svelte';
</script>
```

Setup (once per project): `npm install fancy-ui-svelte`, then add `@import "fancy-ui-svelte/tailwind.css";` after `@import "tailwindcss";` in your main CSS file. Full guide: https://fancy-ui.rama.app/llms.txt

React: `import { MosaicGlow } from 'fancy-ui-react';` (`class` becomes `className`, snippets become `ReactNode`, DOM callbacks are camel-cased; exact names on https://fancy-ui.rama.app/docs/components/react/mosaic-glow.md).

## Props

| Prop | Type | Default | Description |
| --- | --- | --- | --- |
| `hdr` | `boolean` | `true` | On a display that reports HDR, adds the light above SDR white in a WebGPU layer with extended tone mapping: the hottest tiles peak around 1000 nits and the halo gets a hot core. Elsewhere nothing starts and the mosaic is unchanged |
| `tileSize` | `number` | `18` | Tile edge in CSS px |
| `gap` | `number` | `2` | Gap between tiles in CSS px |
| `color` | `string` | `"#f2c318"` | Halo and tile colour, hex or rgb() |
| `background` | `string` | `"#0a0a0a"` | Surface colour behind the tiles, hex or rgb() |
| `radius` | `number` | `170` | Halo radius in CSS px |
| `intensity` | `number` | `1` | Overall brightness of lit tiles, 0 to 1 |
| `trail` | `number` | `0.6` | How long lit tiles linger after the halo moves on, 0 to 1 |
| `smoothing` | `number` | `0.15` | Pointer lag, 0 (instant) to 1 (very laggy) |
| `noise` | `number` | `0.7` | Spread of per-tile random brightness inside the halo, 0 to 1 |
| `ambient` | `number` | `0.35` | Visibility of the random faint tiles outside the halo, 0 to 1 |
| `flicker` | `boolean` | `true` | Slowly re-roll the faint tiles over time |
| `idle` | `"drift" \| "none"` | `"drift"` | With no pointer for 1.5s: drift wanders the halo on a slow path, none switches it off |
| `interactive` | `boolean` | `true` | Follow the pointer. Off leaves only the idle behaviour |
| `seed` | `number` | `1` | Seed for the per-tile randomness; same seed, same mosaic |
| `ref` | `HTMLDivElement \| null` | `null` | Bindable host element |
| `class` | `string` | — | Additional classes on the host |

## Snippets

| Snippet | Description |
| --- | --- |
| `children` | Content rendered above the canvas; give the host a height |

## Examples

### Basic Usage

```svelte
<script lang="ts">
	import { MosaicGlow } from "fancy-ui-svelte";
</script>

<MosaicGlow class="h-80 w-full rounded-2xl border border-white/10">
	<div class="flex h-full flex-col items-center justify-center gap-2 text-center">
		<h3 class="text-2xl font-semibold tracking-tight text-white">Something is glowing</h3>
		<p class="text-sm text-white/60">Move your cursor across the tiles</p>
	</div>
</MosaicGlow>
```

### Colors

Any hex or rgb() colour for the halo and the surface.

```svelte
<script lang="ts">
	import { MosaicGlow } from "fancy-ui-svelte";
</script>

<div class="grid w-full gap-4 sm:grid-cols-3">
	<MosaicGlow class="h-48 rounded-xl" seed={2} />
	<MosaicGlow class="h-48 rounded-xl" color="#22d3ee" background="#04101a" seed={3} />
	<MosaicGlow class="h-48 rounded-xl" color="#f472b6" background="#120812" seed={4} />
</div>
```

### Dense Grid

Smaller tiles for a finer mosaic.

```svelte
<script lang="ts">
	import { MosaicGlow } from "fancy-ui-svelte";
</script>

<MosaicGlow class="h-72 w-full rounded-2xl" tileSize={8} gap={1} radius={120} noise={0.85} />
```

### Trail and Idle

A short, cursor-only trail versus a long comet that keeps drifting.

```svelte
<script lang="ts">
	import { MosaicGlow } from "fancy-ui-svelte";
</script>

<div class="grid w-full gap-4 sm:grid-cols-2">
	<MosaicGlow class="h-64 rounded-xl" trail={0.15} smoothing={0} idle="none">
		<p class="p-4 text-xs text-white/50">trail 0.15 · idle none</p>
	</MosaicGlow>
	<MosaicGlow class="h-64 rounded-xl" trail={0.95} smoothing={0.4} seed={7}>
		<p class="p-4 text-xs text-white/50">trail 0.95 · smoothing 0.4 · drifts when idle</p>
	</MosaicGlow>
</div>
```

### Interactive Playground

```svelte
<script lang="ts">
	import { MosaicGlow, type MosaicGlowIdle } from "fancy-ui-svelte";
	import PropsPlayground from "$lib/components/PropsPlayground.svelte";
</script>

<PropsPlayground
	controls={[
		{ key: "color", type: "color", label: "Color" },
		{ key: "background", type: "color", label: "Background" },
		{ key: "tileSize", type: "range", label: "Tile Size", min: 4, max: 32, step: 1 },
		{ key: "gap", type: "range", label: "Gap", min: 0, max: 6, step: 1 },
		{ key: "radius", type: "range", label: "Radius", min: 60, max: 320, step: 10 },
		{ key: "intensity", type: "range", label: "Intensity", min: 0, max: 1, step: 0.05 },
		{ key: "trail", type: "range", label: "Trail", min: 0, max: 1, step: 0.05 },
		{ key: "smoothing", type: "range", label: "Smoothing", min: 0, max: 1, step: 0.05 },
		{ key: "noise", type: "range", label: "Noise", min: 0, max: 1, step: 0.05 },
		{ key: "ambient", type: "range", label: "Ambient", min: 0, max: 1, step: 0.05 },
		{ key: "flicker", type: "boolean", label: "Flicker" },
		{
			key: "idle",
			type: "select",
			label: "Idle",
			options: [
				{ value: "drift", label: "Drift" },
				{ value: "none", label: "None" },
			],
		},
	]}
	initialValues={{
		color: "#f2c318",
		background: "#0a0a0a",
		tileSize: 18,
		gap: 2,
		radius: 170,
		intensity: 1,
		trail: 0.6,
		smoothing: 0.15,
		noise: 0.7,
		ambient: 0.35,
		flicker: true,
		idle: "drift",
	}}
>
	{#snippet preview(values)}
		<MosaicGlow
			class="h-72 w-full rounded-xl"
			color={values.color as string}
			background={values.background as string}
			tileSize={values.tileSize as number}
			gap={values.gap as number}
			radius={values.radius as number}
			intensity={values.intensity as number}
			trail={values.trail as number}
			smoothing={values.smoothing as number}
			noise={values.noise as number}
			ambient={values.ambient as number}
			flicker={values.flicker as boolean}
			idle={values.idle as MosaicGlowIdle}
		/>
	{/snippet}
</PropsPlayground>
```
