# Shadows

Six shadow levels, a hairline ring, and a fade for scrolling edges.

Package: @reuse-sh/shadows

## Principles

These are the rules to keep when you adapt this library. The code is one way to keep them. An adaptation on any framework must keep every one.

- Build each level from two layers. Every level is a close shadow and a wide one, drawn from one color and one strength.

- Set color and strength once. --reuse-shadow-color and --reuse-shadow-strength drive all six levels, and a dark ancestor raises the strength and lightens the ring.

- Use a ring, not a border. The ring variants add a hairline in the shadow itself, so the element's size never changes.

- Work without JavaScript. The levels and cards are plain classes in one stylesheet.

- Fade only where there is more. The fade edge masks a side only while there is content left to scroll toward it, and it follows right-to-left layouts.

- Put the inline style back. Destroy restores the scroller's original inline style exactly.

## Install

```bash
npm install @reuse-sh/shadows
```

## Integration notes

- Import the stylesheet. The classes need no JavaScript and no Tailwind.

- Use the ring variant instead of adding a border on top of the shadow.

- A data-reuse-theme="dark" ancestor switches to stronger shadows and a light ring.

- createFadeEdge writes a mask to the scroller's inline style and puts the old style back on destroy. It follows right-to-left layouts.

## API

- `reuse-shadow-xs … reuse-shadow-2xl`: Six shadow levels.

- `reuse-shadow-ring-xs … reuse-shadow-ring-2xl`: The same levels with a hairline ring instead of a border.

- `reuse-card, reuse-card-frame`: A card surface and its outer frame.

- `reuse-card-code, reuse-card-action`: Cards for code samples and for actions.

- `shadowLevels`: The level names in order, from "xs" to "2xl".

- `createFadeEdge(scroller, { size, curve, mode })`: Masks the edges of a horizontal scroller. Returns update(options) and destroy().

- `size`: The width of each fade in pixels. 64 by default.

- `curve, FADE_CURVES`: "smooth" eases the fade in and out, "linear" is a straight ramp. "smooth" by default.

- `mode, FADE_MODES`: "scroll" grows each fade with the distance left to scroll. "fixed" keeps it at full size until that edge is reached. "scroll" by default.

## Browser JavaScript

```js
import "@reuse-sh/shadows/styles.css";
import { createFadeEdge } from "@reuse-sh/shadows";

// <div class="reuse-card reuse-shadow-ring-md">
//   <div class="strip">Your content</div>
// </div>

// Fade the sides of the scroller inside the card, so the ring stays.
const strip = document.querySelector(".strip");
const fade = createFadeEdge(strip, { size: 64, curve: "smooth", mode: "scroll" });

// Later, when the strip leaves the page
fade.destroy();
```

## React

```tsx
import "@reuse-sh/shadows/styles.css";
import { createFadeEdge } from "@reuse-sh/shadows";
import { useEffect, useRef } from "react";

export function Strip({ children }) {
  const ref = useRef(null);
  useEffect(() => {
    const fade = createFadeEdge(ref.current, { mode: "fixed" });
    return () => fade.destroy();
  }, []);
  return (
    <div className="reuse-card reuse-shadow-ring-md">
      <div ref={ref} className="strip">
        {children}
      </div>
    </div>
  );
}
```

## Agent workflow

1. Inspect the project and read the installed package's types and stylesheet.

2. Reuse the native controller. Use the React adapter only in a React surface.

3. Adapt styles and data connections to the project. Keep every principle above. Do not recreate the gesture or state engine.

4. Connect destroy and unsubscribe callbacks to the owner lifecycle.

5. Verify keyboard access, pointer/touch behavior, resize, empty/one-item states, errors, reduced motion, and teardown where applicable.

6. Report the actual checks and remaining browser/device limits.

## Source

https://github.com/reuse-sh/reuse/tree/main/packages/shadows/src

License: MIT for original library code. Preserve dependency and asset license notices.
