# Fluted Glass (Moonarc)

Reeded glass over whatever is behind it: the box's backdrop blurred and lightly brightened, cut into vertical flutes (or flutes at an angle), each with a light edge and a shade, as a pane of fluted glass bends what is behind it into strips. Put it in a positioned box over a picture, a video or a gradient, and give it the flute's width and how far it blurs. Without backdrop-filter the flutes are drawn over the content as they are, unblurred. Decoration, hidden from a screen reader; it never takes a click. Zero JavaScript.

- Import: `import FlutedGlass from '@moonarc/core/FlutedGlass'`
- Install: `npx astro add moonarc` · copy-paste: `npx shadcn@latest add https://moonarc.dev/r/fluted-glass.json`
- Tier A · category background · trigger always
- Readout: `<FlutedGlass width="22px" blur="6px" />`
- Browser support: widely (Chrome 76 · Firefox 103 · Safari 18); elsewhere: without backdrop-filter the flutes are drawn unblurred
- Measured cost: 0 B JS (CSS 4.6 kB raw)
- Page: https://moonarc.dev/components/fluted-glass/

## Props

| Prop | Type | Default | Description |
|---|---|---|---|
| `width` | `string` | `'22px'` | The flutes' width. |
| `blur` | `string` | `'6px'` | How far the backdrop blurs. |
| `angle` | `number` | `0` | The flutes' angle in degrees; 0 is upright. |
| `strength` | `number` | `0.5` | How strong the light edges and the shades are, 0 to 1. |

## Usage

```astro
<figure style="position: relative">
  <img src="/studio.webp" alt="The studio at dusk" width="1600" height="1000" />
  <FlutedGlass width="28px" blur="8px" angle={8} />
</figure>
```

## Reduced motion

Nothing in it moves.

## With ClientRouter

No script: it works on any page however it was reached.

## Craft

- One element: backdrop-filter blurs what is behind it, and one repeating gradient draws each flute's light edge, clear middle and shade.
- The strength scales every stop of the gradient at once, so a flute keeps its shape at any strength.

## Replaces

- Fluted Glass (Cult UI)
- Fluted glass shader (shaderscn)

## Source

```astro
---
/**
 * FlutedGlass — reeded glass over whatever is behind it: the box's backdrop blurred and lightly brightened, cut into
 * vertical flutes (or flutes at an angle), each with a light edge and a shade, as a pane of fluted glass bends what is
 * behind it into strips. Put it in a positioned box over a picture, a video or a gradient; give it the flute's width and
 * how much it blurs. Without backdrop-filter the flutes are drawn over the content as they are, unblurred.
 * Decoration, hidden from a screen reader; it never takes a click. Zero JavaScript.
 */
import type { HTMLAttributes } from 'astro/types';

interface Props extends HTMLAttributes<'div'> {
  /** The flutes' width, a CSS length. */
  width?: string;
  /** How far the backdrop blurs, a CSS length. */
  blur?: string;
  /** The flutes' angle, in degrees: 0 for upright. */
  angle?: number;
  /** How strong the flutes' light and shade are, 0 to 1. */
  strength?: number;
}

const { width = '22px', blur = '6px', angle = 0, strength = 0.5, class: className, style, ...rest } = Astro.props;
const vars = [`--ma-flute-width:${width}`, `--ma-flute-blur:${blur}`, `--ma-flute-angle:${angle}deg`, `--ma-flute-strength:${strength}`, typeof style === 'string' ? style : ''].filter(Boolean).join(';');
---

<div class:list={['ma-flute', className]} aria-hidden="true" style={vars} {...rest}></div>

<style is:global>
  @layer components {
    :where(.ma-flute) {
      --ma-flute-width: 22px;
      --ma-flute-angle: 0deg;
      --ma-flute-strength: 0.5;
      position: absolute;
      inset: 0;
      z-index: 1;
      pointer-events: none;
      -webkit-backdrop-filter: blur(var(--ma-flute-blur, 6px)) brightness(1.04) saturate(1.1);
      backdrop-filter: blur(var(--ma-flute-blur, 6px)) brightness(1.04) saturate(1.1);
      /* each flute: a light edge, the clear middle, a shade before the next */
      background: repeating-linear-gradient(
        calc(90deg + var(--ma-flute-angle, 0deg)),
        rgb(255 255 255 / calc(0.32 * var(--ma-flute-strength))) 0,
        rgb(255 255 255 / calc(0.06 * var(--ma-flute-strength))) calc(var(--ma-flute-width) * 0.18),
        transparent calc(var(--ma-flute-width) * 0.45),
        rgb(0 0 0 / calc(0.1 * var(--ma-flute-strength))) calc(var(--ma-flute-width) * 0.82),
        rgb(0 0 0 / calc(0.22 * var(--ma-flute-strength))) var(--ma-flute-width)
      );
    }
    /* prefers-reduced-motion: nothing here moves */
  }
</style>

```
