# Hero design guidelines

Every hero in this repo follows the same structural contract. This document is the rule sheet, a PR that breaks one of these is going to ask for changes.

## What a hero is

A hero is the visual in the **first viewport** of a buzzvil.com page. It loads with the page, runs continuously, and tells the page's story in motion before the user has read a single word.

A hero is **not** the section heading, the title, the sub-line, or the CTA. Those are typography. The hero is the animated thing above / behind / beside them that makes the page feel alive.

When you isolate a hero (as this repo does), the copy disappears. The hero must still read what page you're on. That's the identity test.

## The anchor: Buzzvil mark with a pattern inside

Every hero anchors on the same primitive: **the Buzzvil mark, masked with a `comp-*` pattern**.

```html
<svg viewBox="80 165 330 220" preserveAspectRatio="xMidYMid meet">
  <g mask="url(#m-logo)">
    <use href="#comp-stripes" x="80" y="165" width="330" height="220"
         style="--c-bg: #03c75a; --c-mid: #4d8b31; --c-acc: #000000;"/>
  </g>
</svg>
```

This is non-negotiable. It's how a visitor knows they're on a Buzzvil page within 200ms of arriving, the wordmark is the bedrock and the pattern inside it is the page's accent. The exception is the homepage hero, which may use the mark masked through an even more atmospheric layer (e.g. the morphing blob from the patterns gallery) when the page wants to read as "Buzzvil itself," not as a specific solution.

The pattern is one of the canonical `comp-*` symbols from [`patterns/`](../patterns/) (currently `comp-squares`, `comp-stripes`, `comp-hex`, `comp-circles`, `comp-triangles`, `comp-diamonds`). For v1 the symbols are inlined in `index.html`'s defs; you don't redefine them, you just `<use>` them.

## The motion layer

On top of the mark-with-pattern anchor, every hero adds **one focal motion** that tells the page's story:

| Story type | Motion family | Examples |
|---|---|---|
| **Journey / breadth** | Orbit, traveler-on-path, tour | `hero-landing-orbit`, single dot traces the 5-step product story around the mark |
| **Outcome demo** | Card-state loop with cursor | `hero-solution-drive-sales-cursor-demo`, cursor clicks through ad → form → reward |
| **People / culture** | Cursors, swarms, gestures | `hero-how-we-work-swarm`, 1 → 2 → 14 cursors converge on the mark |
| **Mechanism** | Sequence, pulse, beat-driven | _planned_, how-it-works pillar pages |
| **Identity / mood** | Float, breathe, slow drift | The default fallback when there's no specific story |

**One focal motion per hero.** If you have two competing motion ideas, the hero hasn't been edited yet.

## The three palette tokens (chameleon rule)

The `comp-*` pattern paints with exactly three tokens: `--c-bg`, `--c-mid`, `--c-acc`. **Where the colours come from** is dictated by the page, following the same chameleon logic as [`patterns/GUIDELINES.md`](../patterns/GUIDELINES.md#where-the-colours-come-from-the-chameleon-rule):

- **Solution page** → top 3 partners' brand colours in that solution.
  - Drive Sales → Naver Shopping green, Olive Young olive, Musinsa black.
  - Acquire Users → NetMarble purple, Krafton gold, NCSoft red.
  - Build Brand → Samsung blue, Hyundai navy, LG red.
  - Boost Engagement → Toss blue, KakaoBank dark, Kakao yellow.
  - Monetize → Buzzvil red palette (publisher-anchor).
- **How-it-works pillar pages** → atmospheric, single-anchor hue.
  - Reach → deep blue.
  - Interaction → amber/orange.
  - Reward → green.
- **Homepage / culture / brand-anchor surfaces** → Buzzvil brand palette (cherry / warm orange / hot pink).

Hard-coded colour values are **not allowed inside `comp-*` symbols**. Motion-layer decoration (cursors, card frames, confetti, traveler dots) may use literal colours, but **they must come from the same three-token palette** the pattern is using, no introducing a fourth colour.

What this means in practice: design the motion layer with **structure first**. If your cursor pip needs to be electric blue to "pop," but the page's palette is Naver green + olive + black, you're fighting the page's brand story rather than serving it. The brand wins; the cursor finds a different way to read.

## Anatomy of a hero card (what we showcase)

In this gallery, each hero is rendered **without** its hero-section copy. You see:

- **The mark with its pattern**, at hero scale, in the page's actual palette.
- **The motion layer**, running continuously, in the page's actual palette.
- **Nothing else.** No eyebrow, no title, no sub-line, no CTA.

If the hero needs the copy to read, it's not a hero, it's a header. Refine.

The framing is a 16:9 box (480×270 default) on a background that approximates the page's hero background colour (dark on landing/how-we-work, white on solutions / how-it-works).

## Animation rules

- **One focal loop.** The "main thing" that animates. Multiple supporting micro-motions (the pattern's own breathing, a gentle float on the mark) are fine, but there should be exactly one focal motion that carries the page's story.
- **Loop length: 6-60s for the focal motion.** Long enough to feel deliberate, short enough that a returning visitor doesn't wait. The pattern beneath may run longer (24-120s per the patterns rules), that's a different layer.
- **Continuous, not staged.** Heroes loop forever from the moment the page loads. No "play once on entry", assume the visitor scrolls past and back.
- **`prefers-reduced-motion`.** The pattern stays (it's structural). The focal motion freezes on a representative still frame, pick the frame that best reads the page's story without motion (e.g. orbit shows all 5 step dots; cursor-demo holds on the reward state).
- **No filters, no blends, no parallax on scroll.** The hero is a self-contained animation; it does not depend on viewport position to read.

## Performance budget

- Renders smoothly on a 2018 phone with the hero visible and the rest of the page mounted.
- No animated `<filter>`s. No `mix-blend-mode` driving the focal motion. No animated SVG masks unless the mask IS the focal motion.
- JS for animation only when SMIL / CSS keyframes cannot express the motion (e.g. `hero-landing-orbit` uses a single rAF loop to position one traveler along an arc-length parameterised path, that's the bar).

## Identity tests

A good hero passes these, in order:

1. **Copy-off test.** Remove the eyebrow + title + sub-line + CTA. Can you tell what page you're on from the visual alone? (Landing = product breadth. Drive Sales = ad-to-reward demo. How We Work = people converging on Buzzvil.) If no, the hero is leaning on the words.
2. **Palette-swap test.** Swap the three colour tokens to a completely different palette (Samsung blue + Hyundai navy + LG red). Does the visual logic still work, or does it depend on a specific hue to read? If only the original colours look good, the composition is colour-dependent, refine.
3. **Pause test.** Pause the animation in DevTools. Is the still frame interesting? Does it tell *some* part of the page's story? Heroes shouldn't lean entirely on motion to justify themselves.
4. **Loop-back test.** Watch the focal loop three times in a row. Does the seam show? Continuous loops that visibly snap back to the start break the spell.
5. **Scale test.** Render at 480×270 (gallery scale) AND at the actual hero size on the page (~1200×600). Does the motion still read at both? Some motions (cursor swarms) lose legibility when scaled down; some patterns (fine stripes) lose identity when scaled up.

## Naming

- `hero-` prefix on every id.
- Format: `hero-{route-slug}-{motion-variant}`.
  - Route slug matches the IA: `landing`, `solution-drive-sales`, `solution-acquire-users`, `solution-build-brand`, `solution-boost-engagement`, `solution-monetize`, `how-it-works`, `how-it-works-reach`, `how-it-works-interaction`, `how-it-works-reward`, `how-we-work`.
  - Motion variant is the one-word handle for the focal motion: `orbit`, `cursor-demo`, `swarm`, `pulse`, `tour`, etc.
- Examples: `hero-landing-orbit`, `hero-solution-drive-sales-cursor-demo`, `hero-how-we-work-swarm`.
- The **first** hero for a route doesn't strictly need a motion suffix, but include one anyway, it makes the second variant easier to name later. `hero-landing-orbit` is clearer than `hero-landing` if a `hero-landing-blob` variant ever ships.

## What counts as a new entry

**Page + visual concept together define an entry.** A new pattern on the same page is *not* a new entry (the pattern lives in `patterns/`); a new **motion layer** on the same page **is** a new entry.

- Drive Sales with `comp-stripes` cursor-demo → entry A.
- Drive Sales with `comp-circles` cursor-demo → still entry A (pattern swap, not a new entry, update the existing one).
- Drive Sales with the cursor-demo replaced by a "live-leaderboard" motion → **new entry** B (motion changed).

Two heroes sharing a motion family across two different pages are two entries (e.g. cursor-demo on Drive Sales and cursor-demo on Acquire Users, same family, different story, different palette, separate cards).

## Credit

Every hero card carries its author. When you add a gallery card, include yourself in the head section:

```html
<span class="hero-card-author">by <a href="https://github.com/your-handle" target="_blank" rel="noopener">@your-handle</a></span>
```

That's how credit shows up next to the hero id on the gallery. Use your GitHub handle so the link lands on your profile.

### Updates to an existing hero keep every contributor's name

If you refine someone else's hero (motion timing, palette, supporting micro-motion), **don't replace the original author**. Append yourself to the credit line so both names show:

```html
<span class="hero-card-author">
  by <a href="https://github.com/mmaxence">@mmaxence</a>,
  updated by <a href="https://github.com/your-handle">@your-handle</a>
</span>
```

If a third or fourth update lands, **list every author**, don't collapse to "and others" or use ellipses. Original creator first, then each updater in the order their changes landed.

If your change is so different, different motion family entirely, open a new entry instead.

## Do / don't

**Do:**
- Anchor on the mark-with-pattern primitive. Always.
- Pull palette from the page's partner / pillar / brand source.
- Pick one focal motion and let it carry the story.
- Test with copy removed.
- Honour `prefers-reduced-motion`.

**Don't:**
- Stack the focal motion on top of the typography. Heroes live behind / around / beside the copy, not on top.
- Use a fourth colour for "highlight." The three tokens are the contract.
- Lean on parallax, scroll-jacking, or pointer-tracking. The hero is self-contained.
- Replicate the same motion across multiple pages, the motion layer is the page's signature.
- Ship a hero that only reads at one scale.

## The PR

When you open a PR, the template will pre-fill a checklist. Before merging, the hero lives on a deploy preview. Reviewer (Max) walks it, gives notes if any, or merges. Once merged, the hero is available to use on its target page in `buzzvil-com-preview`.
