# Agency — Page Template for React

> A one-page site for a creative / development studio: a sticky Lodestar pill header, an oversized editorial hero with a word-by-word blur reveal and a pulsing availability chip, a staggered selected-work grid of tilting Facet tiles with seeded procedural cover art and hover reveals, numbered services that expand to deliverables, Casebook client results, a pinned Drawbench process, the Guild team, a routed Parley contact form and a Tailstock wordmark footer — every string a prop, any section droppable, one vermilion accent flowing through every block.

- Page: https://crucibleui.com/components/templates/agency
- Category: [templates](https://crucibleui.com/components/templates)
- Tier: pro (one-time purchase, see https://crucibleui.com/pricing)
- Engine: motion
- npm dependencies: motion

## Install

```bash
npx shadcn@latest add @crucible/agency
```

Pro install requires adding the token-bearing `@crucible` registry to components.json (issued at https://crucibleui.com/account after purchase).

Import from `@/components/crucible/agency`.

## Props (`AgencyTemplateProps`)

| Prop | Type | Default | Description |
| --- | --- | --- | --- |
| `brand?` | `string` | `"Marrow"` | Studio name: nav wordmark, footer wordmark, copyright. |
| `accentColor?` | `string` | `"#ff6b4a"` | Signature accent hex shared by every section, so the page reads as one brand. |
| `header?` | `AgencyHeaderConfig \| false` | — | Sticky pill header (composes `lodestar`). `false` hides it. |
| `hero?` | `AgencyHeroConfig \| false` | — | Editorial hero. `false` hides it. |
| `work?` | `AgencyWorkConfig \| false` | — | Selected-work grid (tiles compose `facet`). `false` hides it. |
| `services?` | `AgencyServicesConfig \| false` | — | Numbered, expandable services list. `false` hides it. |
| `results?` | `BlockConfig<CasebookProps>` | — | Client results (composes `casebook`). `false` hides it. |
| `process?` | `BlockConfig<DrawbenchProps>` | — | Process (composes `drawbench`). `false` hides it. |
| `team?` | `BlockConfig<GuildProps>` | — | Team / studio (composes `guild`). `false` hides it. |
| `contact?` | `BlockConfig<ParleyProps>` | — | Closing contact section (composes `parley`). `false` hides it. |
| `footer?` | `BlockConfig<TailstockProps>` | — | Footer (composes `tailstock`). `false` hides it. |
| `scroller?` | `React.RefObject<HTMLElement \| null>` | `the window` | Scroll container the page lives in (e.g. a boxed preview). The header sticks inside it, the process section pins inside it and nav links scroll it. |
| `ref?` | `React.Ref<AgencyTemplateHandle>` | — | Imperative handle (`replay()`, `scrollToSection()`). React 19 ref-as-prop. |
| `className?` | `string` | — | Extra classes for the root. |

Also accepts: `Omit<React.ComponentPropsWithoutRef<"div">, "children" | "results">`.

## Usage example

```tsx
"use client";

import * as React from "react";

import { AgencyTemplate } from "@/components/crucible/agency";

export default function AgencyTemplateDemo() {
  const scrollerRef = React.useRef<HTMLDivElement>(null);
  const [scrolled, setScrolled] = React.useState(false);

  return (
    <div className="relative isolate h-[640px] w-full overflow-hidden rounded-xl bg-neutral-950">
      <div
        ref={scrollerRef}
        onScroll={(e) => {
          if (!scrolled && e.currentTarget.scrollTop > 40) setScrolled(true);
        }}
        className="absolute inset-0 overflow-y-auto overflow-x-hidden overscroll-contain"
      >
        <AgencyTemplate scroller={scrollerRef} />
      </div>
      <p
        aria-hidden
        className="pointer-events-none absolute inset-x-0 bottom-3 z-10 flex justify-center transition-opacity duration-500"
        style={{ opacity: scrolled ? 0 : 1 }}
      >
        <span className="rounded-full border border-white/10 bg-neutral-950/80 px-3 py-1 text-[11px] font-medium text-neutral-400 backdrop-blur">
          Scroll the page — hover the work, open a service.
        </span>
      </p>
    </div>
  );
}
```

## Accessibility & performance

Honors `prefers-reduced-motion` with a designed static frame or fade (never a blank box) and passes `className` through.
