# Web Module Taxonomy & Design Vocabulary

A working lexicon of page modules, from structural primitives to high-craft scroll cinema.
Purpose: shared naming so a module can be specified, priced, and reused without describing it in prose every time.

---

## How to read this

**Difficulty (D1–D5)** — build cost, not visual impact.

| Tier | Meaning | Typical implementation |
|---|---|---|
| D1 | Static markup + CSS | Flex/grid, no JS |
| D2 | CSS state or trivial JS | `:hover`, `position: sticky`, small toggle |
| D3 | Real JS / library | IntersectionObserver, Embla, Radix, Framer Motion |
| D4 | Scroll-driven choreography | GSAP ScrollTrigger, Lenis, timeline sequencing |
| D5 | Custom render layer | WebGL/Three.js, shaders, physics, canvas sequences |

**Rarity** — `[std]` on nearly every site · `[com]` common · `[unc]` uncommon · `[rare]` signature-tier, memorable when done well.

**Fragility flag** — ⚠ marks patterns that commonly break on mobile, hurt LCP/CLS, or fight accessibility.

---

## 1. Structural primitives

The container grammar everything else sits inside. Name these first — most "modules" are just a primitive plus a fill.

| Name | Aliases | D | Rarity | What it is |
|---|---|---|---|---|
| **Full-bleed section** | edge-to-edge, breakout | D1 | std | Section spanning 100vw, ignoring the content container. Baseline for photo panels. |
| **Contained section** | boxed, gutter section | D1 | std | Max-width column with symmetric gutters. Default reading measure. |
| **Split panel** | 50/50, half-and-half | D1 | std | Two vertical halves, usually media + copy. The workhorse of B2B pages. |
| **Asymmetric split** | 60/40, offset split | D1 | com | Deliberately unequal halves. Reads more designed than 50/50 for the same effort. |
| **Bento grid** | modular grid, tile grid | D2 | com | Mixed-span cards in a fixed grid. Apple-derived. Fast way to make a features section look considered. |
| **Editorial grid** | magazine grid, broken grid | D2 | unc | Explicit column grid where elements deliberately break alignment. High craft-signal, low tech cost. |
| **Stacked band layout** | ribbon stack | D1 | std | Alternating background bands down the page. Basic but readable rhythm. |
| **Overlap / negative-margin block** | bleed-over, tuck | D1 | com | Element pulled up over the preceding section boundary. Cheapest way to break the band monotony. |
| **Rail + content** | sidebar layout | D2 | com | Persistent side column (nav, TOC, filters) beside a scrolling body. |
| **Aspect-locked media frame** | ratio box | D1 | std | Fixed-ratio container preventing layout shift on image load. Non-negotiable for CLS. |
| **Viewport-unit panel** | 100vh / 100svh block | D1 | std | Section sized to the viewport. Use `svh`/`dvh`, not `vh`. ⚠ mobile browser chrome. |

---

## 2. Hero patterns

| Name | Aliases | D | Rarity | What it is |
|---|---|---|---|---|
| **Static hero** | classic hero | D1 | std | Headline, sub, CTA, optional image. Fastest LCP. Still correct for most conversion pages. |
| **Full-bleed image hero** | photo hero | D1 | std | Edge-to-edge photo with overlaid type and scrim gradient. |
| **Video hero** | background video, loop hero | D2 | com | Muted autoplay loop behind type. ⚠ heavy; needs poster frame + mobile still fallback. |
| **Split hero** | product hero | D1 | std | Copy one side, product shot or form the other. |
| **Kinetic type hero** | animated headline | D3 | com | Per-word or per-character staggered entrance (SplitText / Framer stagger). |
| **Marquee hero** | ticker hero | D2 | com | Oversized looping horizontal text strip. Instant editorial energy, near-zero cost. |
| **Rotating word hero** | word swapper, headline cycler | D2 | com | One noun in the headline cycles ("marketing for **attorneys / builders / clinics**"). |
| **Generative hero** | WebGL hero, shader hero | D5 | rare | Live-rendered noise field, particle mesh, fluid, or point cloud. Signature-tier. ⚠ battery, LCP, fallback path required. |
| **Scroll-reactive hero** | hero-to-nav morph | D4 | unc | Hero elements scale, fade, and hand off into the sticky header as you leave. |
| **Zoom-out hero** | dolly reveal | D4 | unc | Media begins cropped/scaled and eases to full frame on first scroll input. |
| **Interactive hero** | cursor-reactive hero | D4 | rare | Media distorts, parallaxes, or reveals along the pointer. |
| **Search / input-first hero** | utility hero | D2 | com | The primary element is a field. Correct for directories, tools, marketplaces. |

---

## 3. Scroll-driven modules

This is the tier you were describing. The pattern you built is **#3.4 — Pinned Full-Bleed Scene**.

| Name | Aliases | D | Rarity | What it is |
|---|---|---|---|---|
| **3.1 Reveal on enter** | fade-up, scroll reveal, AOS | D3 | std | Elements transition in as they cross a viewport threshold. IntersectionObserver. The baseline. |
| **3.2 Staggered reveal** | cascade, waterfall | D3 | com | Grid children enter on offset delays. Same cost as 3.1, reads far more intentional. |
| **3.3 Parallax layer** | depth scroll | D3 | com | Background moves at a fraction of foreground speed. ⚠ overused; subtle values only (0.1–0.3). |
| **3.4 Pinned full-bleed scene** | **sticky panel, scroll-pinned section, pinned scene, ScrollTrigger pin** | D4 | unc | Section locks to the viewport as it arrives; media holds full-frame while copy rises from the lower edge; after a defined scroll distance the pin releases and the page resumes. **This is the one you just built.** |
| **3.5 Pinned sequence** | scroll stack, chapter stack | D4 | unc | Several 3.4 scenes chained — each pins, plays, releases into the next. Reads as chapters. |
| **3.6 Card stack / deck** | sticky stack, shuffle stack | D3 | com | Cards stick at the same offset and pile up, each overlapping the last. Cheap cousin of 3.5, CSS-only in its simplest form. |
| **3.7 Sticky media, scrolling copy** | pinned visual, "sticky left" | D4 | com | Media pins on one side while the text column scrolls; media swaps at each text milestone. The core scrollytelling pattern. |
| **3.8 Horizontal scroll section** | side-scroller, lateral pin | D4 | unc | Vertical scroll is translated into horizontal movement within a pinned section. ⚠ scroll-position ambiguity; always show progress. |
| **3.9 Image-sequence scrub** | scrollytelling frames, AirPods scroll | D5 | rare | Scroll position scrubs a numbered frame sequence or video timeline. Enormous asset weight; needs preloading strategy. |
| **3.10 Scroll-scrubbed 3D** | model scrub, WebGL scrub | D5 | rare | Camera or model state driven directly by scroll progress. |
| **3.11 Progress-driven counter** | odometer, tally reveal | D3 | com | Numbers count up when the module enters view. Cheapest possible "proof" animation. |
| **3.12 Scroll progress indicator** | reading bar, chapter rail | D2 | com | Bar or rail tracking position through an article or pinned sequence. |
| **3.13 Text scrub highlight** | word-by-word illumination | D4 | unc | A paragraph's words brighten from dim to full as scroll advances. Strong on manifesto/positioning copy. |
| **3.14 Mask-wipe reveal** | curtain, clip-path reveal | D4 | unc | A clip-path or mask expands with scroll to uncover media. |
| **3.15 Section-to-section morph** | shared element scroll | D5 | rare | An element persists across the boundary between two sections, changing role and position. |
| **3.16 Infinite / endless scroll** | continuous feed | D3 | com | Content pages in as the sentinel is reached. ⚠ kills the footer; pair with a "load more" escape. |
| **3.17 Scroll-snap sequence** | snap deck | D2 | com | CSS `scroll-snap-type` locks each panel to the viewport. Poor man's pinning, near-free. |
| **3.18 Smooth-scroll layer** | inertia scroll, Lenis/Locomotive | D3 | com | Virtualized eased scrolling. Prerequisite for polished D4 work. ⚠ accessibility and native-feel objections — honor `prefers-reduced-motion`. |

---

## 4. Media modules

| Name | Aliases | D | Rarity | What it is |
|---|---|---|---|---|
| **Image grid / gallery** | tile gallery | D1 | std | Fixed-ratio grid of images. |
| **Masonry grid** | Pinterest layout | D2 | com | Variable-height packing. Now near-free with CSS masonry / column-count. |
| **Lightbox** | modal gallery | D3 | std | Click to expand into an overlay with prev/next. |
| **Before/after slider** | comparison slider, wipe | D3 | com | Draggable divider between two states. Very high value for anything visual-results-driven. |
| **Hover-reveal image** | image-on-hover list | D3 | unc | A text list where hovering an item surfaces a floating image near the cursor. Signature agency move; low cost, big impact. |
| **Video embed block** | player module | D2 | std | Poster + facade that loads the player on click. Always use a facade — never a raw iframe. |
| **Ambient loop** | texture video, b-roll strip | D2 | com | Short muted decorative loop inside a content block. |
| **360 / spin viewer** | product spin | D4 | rare | Drag-to-rotate frame sequence. |
| **Model viewer** | 3D product embed | D5 | rare | Interactive glTF/USDZ model with orbit controls. |
| **Map module** | geo block | D3 | com | Interactive map with pins. Mapbox/Google. Static tile fallback for performance. |
| **Geo-grid / heat overlay** | rank grid, coverage map | D4 | rare | Map with a data-driven point lattice colored by metric. Domain-specific, high credibility signal. |

---

## 5. Navigation & wayfinding

| Name | Aliases | D | Rarity | What it is |
|---|---|---|---|---|
| **Sticky header** | fixed nav | D2 | std | Header pinned to the top. |
| **Shrinking header** | condensing nav | D3 | com | Header reduces height/opacity after a scroll threshold. |
| **Hide-on-scroll-down header** | smart nav, auto-hide | D3 | com | Hides on downward scroll, returns on upward. |
| **Mega menu** | drop panel | D3 | com | Full-width multi-column dropdown. |
| **Overlay menu** | fullscreen nav, curtain menu | D3 | com | Full-viewport menu with animated entrance. Standard on portfolio/agency. |
| **Off-canvas drawer** | slide-out, hamburger drawer | D2 | std | Panel sliding from an edge. Mobile default. |
| **Scrollspy nav** | active-section nav, TOC rail | D3 | com | Side nav that highlights the section currently in view. |
| **Anchor rail / dot nav** | pagination dots, section dots | D2 | com | Minimal dots marking full-page sections. |
| **Breadcrumbs** | path trail | D1 | std | Hierarchical location trail. SEO-relevant. |
| **Command palette** | ⌘K search | D4 | unc | Keyboard-invoked fuzzy search overlay. Signals technical audience. |
| **Sticky CTA bar** | action bar, mobile dock | D2 | com | Persistent bottom bar with the primary action. Strong mobile conversion lever. |
| **Footer sitemap** | fat footer | D1 | std | Multi-column link block. |
| **Reveal footer** | curtain footer, sliding footer | D3 | unc | Footer sits fixed behind the page; content scrolls off to expose it. |

---

## 6. Content & feature blocks

| Name | Aliases | D | Rarity | What it is |
|---|---|---|---|---|
| **Feature trio** | three-up, icon row | D1 | std | Three icon+heading+copy columns. |
| **Alternating feature rows** | zig-zag, z-pattern | D1 | std | Media/copy sides swap row to row. |
| **Feature bento** | capability grid | D2 | com | Mixed-span tiles, each a capability. |
| **Tabbed features** | tab switcher | D3 | std | Tabs swapping a media/copy pane. |
| **Accordion** | disclosure list, FAQ | D2 | std | Expand/collapse rows. Also the standard FAQ pattern (mark up with FAQPage schema). |
| **Stat band** | metrics strip, proof bar | D1 | std | Row of large figures with labels. |
| **Process / step sequence** | numbered steps, how-it-works | D1 | std | Ordered stages, often with a connecting rule. |
| **Timeline** | chronology, roadmap | D2 | com | Vertical or horizontal dated sequence. |
| **Comparison table** | feature matrix, vs-table | D2 | com | Rows of criteria across columns. ⚠ mobile requires card collapse or horizontal scroll. |
| **Pricing tiers** | plan cards | D2 | std | Card set with a highlighted recommended tier and a monthly/annual toggle. |
| **Pull quote** | callout quote | D1 | std | Oversized excerpt breaking the text flow. |
| **Callout / admonition** | note block, aside | D1 | std | Bordered emphasis block. |
| **Manifesto block** | statement section, big-type block | D1 | com | One oversized sentence with heavy whitespace. Highest impact-to-effort ratio on the entire list. |
| **Logo wall** | client grid, trust bar | D1 | std | Grid of client marks, usually desaturated. |
| **Logo marquee** | logo ticker | D2 | std | Same, looping horizontally. |
| **Content card grid** | blog index, resource grid | D1 | std | Paginated card list. |
| **Filterable grid** | faceted gallery, isotope grid | D3 | com | Card grid with category filters and animated re-layout. |
| **Directory / listing module** | search results block | D3 | com | Filter rail plus result rows, usually server-driven. |

---

## 7. Social proof & credibility

| Name | Aliases | D | Rarity | What it is |
|---|---|---|---|---|
| **Testimonial card grid** | quote wall | D1 | std | Static grid of quotes with attribution. Usually outperforms a carousel — everything is visible. |
| **Review carousel** | testimonial slider | D3 | std | Sliding quotes with controls. |
| **Review aggregate badge** | star bar, rating strip | D1 | std | Aggregate score plus platform marks. |
| **Live review feed** | embedded reviews | D3 | com | Pulled from Google/Trustpilot via API or widget. |
| **Case study card** | result card, outcome tile | D1 | com | Client, problem, metric, link. |
| **Case study spread** | deep-dive layout | D2 | unc | Long-form editorial with metrics, imagery, pull quotes. |
| **Video testimonial strip** | face wall | D3 | unc | Row of thumbnail portraits opening into video. Highest-trust proof format. |
| **Credential band** | awards row, association bar | D1 | std | Bar association, certification, publication marks. |
| **Team grid** | people module | D1 | std | Portraits with roles; often with a hover-state alternate image. |
| **Founder note** | letter block, signature block | D1 | com | Portrait, personal copy, signature graphic. |

---

## 8. Conversion, forms & commerce

| Name | Aliases | D | Rarity | What it is |
|---|---|---|---|---|
| **CTA band** | conversion strip | D1 | std | Headline, sub, one button, contrasting background. |
| **Split CTA** | dual-path CTA | D1 | com | Two competing actions for different intents (buy / learn). |
| **Inline lead form** | embedded form | D2 | std | Form inside the flow rather than behind a click. Materially higher completion. |
| **Multi-step form** | wizard, progressive form | D3 | com | Chunked fields with a progress indicator. Best for long intake. |
| **Conversational form** | Typeform-style | D4 | unc | One question per screen with animated transitions. |
| **Quote calculator** | estimator, configurator | D4 | unc | Inputs producing a live price or estimate. Strong qualified-lead generator. |
| **Booking / scheduler embed** | calendar module | D3 | com | Cal.com/Calendly inline. |
| **Exit-intent modal** | exit popup | D3 | com | Triggered on cursor departure. ⚠ desktop-only signal; annoyance cost is real. |
| **Timed / scroll-depth modal** | interstitial | D3 | com | Fires on dwell or depth threshold. |
| **Slide-in nudge** | corner prompt, toast CTA | D2 | com | Small corner panel appearing after a trigger. |
| **Sticky offer bar** | announcement bar, promo strip | D1 | std | Thin persistent band at the top or bottom. |
| **Product card grid** | catalog, PLP | D2 | std | Commerce listing with price and quick-add. |
| **Quick view** | peek modal | D3 | com | Product detail in an overlay without leaving the grid. |
| **Cart drawer** | slide cart | D3 | std | Off-canvas cart. |

---

## 9. Interaction patterns (non-scroll)

| Name | Aliases | D | Rarity | What it is |
|---|---|---|---|---|
| **Hover lift / tilt** | 3D card tilt | D2 | com | Card responds to pointer position with perspective transform. |
| **Magnetic button** | pull button | D3 | unc | Button translates slightly toward the cursor within a radius. |
| **Custom cursor** | cursor follower, blob cursor | D3 | unc | Replaced pointer that changes state contextually. ⚠ desktop-only; never break the native pointer on inputs. |
| **Spotlight / mask cursor** | flashlight effect | D4 | rare | Cursor reveals a hidden layer through a radial mask. |
| **Marquee (on-scroll velocity)** | speed marquee | D3 | unc | Ticker direction/speed reacts to scroll velocity. Cheap sophistication. |
| **Drag gallery** | drag-to-explore, canvas board | D4 | rare | Free-pan infinite plane of media. |
| **Physics interaction** | gravity tiles, cloth, ragdoll | D5 | rare | Matter.js/Rapier-driven elements. Pure delight, zero utility — use once per site max. |
| **Toggle / switch group** | segmented control | D2 | std | Binary or segmented state switch. |
| **Range / slider input** | scrubber | D2 | com | Continuous input, often driving a live preview. |
| **Copy-to-clipboard block** | code block with copy | D2 | com | Developer-audience staple. |
| **Sound-reactive element** | audio-visualizer | D5 | rare | Canvas/WebGL driven by an audio source. |

---

## 10. Transition & continuity

| Name | Aliases | D | Rarity | What it is |
|---|---|---|---|---|
| **Page transition** | route transition, curtain | D4 | unc | Animated cover/uncover between routes. View Transitions API makes this near-free in Astro. |
| **Shared element transition** | FLIP, morph transition, hero transition | D4 | rare | An element persists visually from list item into detail page. The single most "app-like" move available on the web. |
| **Preloader** | loading screen, splash counter | D3 | com | Held entry state with a progress figure. ⚠ pure cost unless assets genuinely justify it. |
| **Skeleton loader** | shimmer placeholder | D2 | std | Grey structural placeholders during fetch. |
| **Optimistic UI** | instant feedback | D3 | com | UI updates before server confirmation. |
| **Staggered route enter** | entrance choreography | D3 | com | New page content cascades in on mount. |

---

## 11. Generative & high-craft layers

| Name | Aliases | D | Rarity | What it is |
|---|---|---|---|---|
| **Shader background** | gradient mesh, noise field | D5 | rare | Fragment-shader surface behind content. |
| **Particle field** | point cloud, starfield | D5 | rare | Instanced points driven by data or noise. |
| **Data-driven 3D chart** | WebGL viz | D5 | rare | Real dataset rendered as 3D geometry. Domain proof, not decoration. |
| **Morphing point cloud** | layout morph | D5 | rare | Points transition between two data layouts. |
| **Distortion / ripple on media** | displacement effect | D5 | rare | Shader-warped imagery reacting to pointer or scroll. |
| **Animated SVG system** | line-draw, path animation | D3 | unc | Stroke-dashoffset drawing, morphing paths. Far cheaper than WebGL, often reads just as premium. |
| **Procedural texture layer** | grain, dither, halftone | D2 | unc | Noise/grain overlay warming flat surfaces. Nearly free; disproportionate effect on perceived quality. |
| **Variable-font animation** | weight morph, optical shift | D3 | unc | Animating font axes on interaction or scroll. |

---

## 12. Micro-detail layer

Not modules — the finish that separates D1 work that looks expensive from D1 work that looks templated.

- **Optical alignment** over mathematical alignment
- **Type scale** locked to a ratio, not arbitrary sizes
- **Consistent easing** — one custom cubic-bezier across the site, never linear or default `ease`
- **Duration discipline** — 150–250ms for state, 400–700ms for entrance, nothing above ~1.2s
- **Focus states** that are designed, not browser default
- **Scrim gradients** rather than flat overlays on media type
- **Border-hairlines** at sub-pixel opacity instead of solid greys
- **Grain / noise** over flat dark surfaces to prevent banding
- **`prefers-reduced-motion`** honored on every D3+ pattern — non-negotiable
- **Empty, loading, and error states** for every dynamic module

---

## 13. Cost & risk notes

Patterns most likely to be regretted:

| Pattern | Risk |
|---|---|
| Video hero | LCP damage, mobile data, autoplay policy |
| Image-sequence scrub (3.9) | 50–300 frames of assets, preload complexity |
| Smooth-scroll layer (3.18) | Accessibility complaints, anchor-link conflicts, iOS quirks |
| Horizontal scroll (3.8) | Users lose orientation; trackpad/wheel mismatch |
| Infinite scroll (3.16) | Footer becomes unreachable; SEO crawl issues |
| Custom cursor | Breaks on touch; interferes with form fields |
| Preloader | Adds real delay to sell a feeling |
| Carousel (any) | Below-first-slide content is rarely seen |

---

## 14. Naming convention for the internal library

Recommended component naming so the vocabulary survives into code:

```
<Category><Pattern><Variant>
```

Examples:
```
HeroSplitForm
ScenePinnedFullBleed      // pattern 3.4
ScenePinnedSequence       // pattern 3.5
ProofTestimonialGrid
ProofReviewCarousel
FeatureBentoThreeSpan
CTABandSplit
NavOverlayFullscreen
```

Each library entry should carry:

1. **Canonical name + aliases**
2. **Difficulty tier** (D1–D5)
3. **Dependencies** (GSAP, Lenis, Embla, Three, none)
4. **Content contract** — exactly which fields the CMS must supply
5. **Responsive behavior** — what it degrades to under 768px
6. **Reduced-motion behavior**
7. **Performance budget** — max asset weight, LCP impact
8. **Reference implementations** — two or three sites doing it well

---

## Quick answer to the original question

The module you built is a **Pinned Full-Bleed Scene** (§3.4) — full-bleed media pins to the viewport on entry, copy rises from the lower edge, the pin holds for a defined scroll distance, then releases into the next section. Chain two or more of them and you have a **Pinned Sequence** (§3.5). The cheaper CSS-only approximations are the **Card Stack** (§3.6) and **Scroll-Snap Sequence** (§3.17).
