Build cinematic case study pages — the kind you see on film production company sites, documentary showcases, and photographer portfolios. Warm analog palette, domain-specific components, scroll-choreographed reveals. Single-file HTML, zero build step.
"Pellicola" is Italian for film — literally "little skin," the celluloid stock.
Creative Direction
The aesthetic is analog cinema on the web — warm cream backgrounds like unbleached paper stock, deep ink-black text, a single red accent reserved exclusively for the play button. Typography pairs a dramatic display serif (headlines, names) with a precise geometric sans (labels, navigation). Every image is framed like a film still — cream padding, rounded corners, subtle shadow creating a polaroid/celluloid look.
If the minoan-frontend-design skill is available, read it for broader aesthetic principles. Pellicola encodes those principles into a concrete design system for the cinematic case study genre. Pages built with Pellicola should score 16+/20 on /design-audit and 28+/40 on /design-critique.
Name the conceptual direction before coding. Default: "analog screening room." Override with project-specific direction when appropriate — "70mm documentary," "festival press kit," "darkroom portfolio."
Quick Start
# Generate a full case study page
python3 scripts/pellicola_generator.py --mode case-study --title "Taboo" --output taboo.html
# Generate just the hero section
python3 scripts/pellicola_generator.py --mode hero --title "Ana Maxim" --output hero.html
# Generate a credits grid
python3 scripts/pellicola_generator.py --mode credits --output credits.html
# Generate a dark footage gallery
python3 scripts/pellicola_generator.py --mode gallery --output gallery.html
# Validate a pellicola page
python3 scripts/validate_pellicola.py output.html
Or let Claude generate directly from the templates and references.
Modes
| Mode | Template | What it generates |
|---|---|---|
case-study | assets/templates/case-study.html | Full page: hero + credits + footage gallery + prizes + investors + next-project |
hero | assets/templates/hero-section.html | Film-frame hero + title overlay + play button only |
credits | assets/templates/credits-grid.html | Credit grid + director portrait card only |
gallery | assets/templates/footage-gallery.html | Dark gallery section only (reusable dark image grid) |
Components (9)
| Component | Class Prefix | What it renders |
|---|---|---|
pel-hero | .pel-hero | Film-frame image with title overlay, genre label, play button, down arrow |
pel-credit-grid | .pel-credits | Role/name pairs in bordered grid (2-3 columns), tracked small caps roles |
pel-director-card | .pel-director | Cropped portrait with dark overlay, display serif name, small caps role |
pel-context-widget | .pel-widget | Sticky top-right nav: thumbnail, title, metadata tags, dropdown |
pel-play-button | .pel-play | Red circle + play triangle + text reveal on hover |
pel-gallery | .pel-gallery | Dark-background masonry image grid with hover scale + brightness shift |
pel-prizes | .pel-prizes | Festival award logos + names in grid layout |
pel-next-project | .pel-next | Large typography + image preview for adjacent case study navigation |
pel-section-divider | .pel-divider | Labeled line divider between content sections |
Copy-paste HTML snippets for every component: references/component-catalog.md.
Color System
All components read from --pel-* CSS custom properties. Override at :root to re-theme:
:root {
/* Background */
--pel-cream: oklch(97.5% 0.012 85);
--pel-cream-deep: oklch(95% 0.015 80);
--pel-black: oklch(10% 0 0);
/* Text */
--pel-ink: oklch(15% 0.005 80);
--pel-ink-muted: oklch(40% 0.01 80);
--pel-ink-light: oklch(98% 0 0);
/* Accent */
--pel-red: oklch(55% 0.22 25);
/* Borders */
--pel-border: oklch(85% 0.01 80);
--pel-border-dark: oklch(25% 0 0);
/* Typography */
--pel-font-display: 'Playfair Display', 'Cormorant Garamond', serif;
--pel-font-body: 'DM Sans', 'Outfit', sans-serif;
/* Easing */
--pel-ease: cubic-bezier(.19, 1, .22, 1);
--pel-ease-back: cubic-bezier(.175, 0, .77, 1);
--pel-duration: 0.8s;
--pel-duration-long: 1.1s;
}
Full token reference: references/design-tokens.md.
OKLCH palette deep-dive: references/color-system.md.
Typography
Display serif carries the cinematic weight — dramatic, editorial, italic for emphasis. Geometric sans handles navigation, labels, metadata — precise and clean. Never Inter, Roboto, Arial, or system-ui. Follow minoan-frontend-design font reflex-reject procedure.
Primary pairings (Google Fonts):
| Role | Font | Weight | Usage |
|---|---|---|---|
| Display | Playfair Display | 400, 700, 400i | H1, H2, names, pullquotes |
| Body/UI | DM Sans | 400, 500, 700 | Body text, labels, navigation, metadata |
Alternative pairings:
- Cormorant Garamond (display) + Outfit (body)
- Lora (display) + Karla (body)
Full pairing guide: references/typography-pairing.md.
Scroll Animation System
Pellicola uses declarative data-pel attributes to orchestrate scroll-triggered reveals via IntersectionObserver. No animation library required.
| Attribute | Effect | Default |
|---|---|---|
data-pel="y" | translateY(40px → 0) + fade in | duration: 0.8s |
data-pel="alpha" | opacity 0 → 1 | duration: 0.6s |
data-pel="line" | scaleX(0 → 1) horizontal line reveal | duration: 0.6s |
data-pel="parallax" | Parallax scroll offset on image | speed: 0.15 |
data-pel="stagger" | Parent: children animate with cascade delay | delay: 0.1s each |
data-pel="title" | Split text into lines, per-line translateY reveal | delay: 0.12s/line |
All animations respect prefers-reduced-motion — reduced to instant opacity with no transforms.
Full spec with IntersectionObserver setup and stagger math: references/animation-system.md.
Section Sequence
Case study pages follow a canonical section order. Sections can be omitted but the order is fixed:
- Hero — Film-frame image, title, genre label, play button
- Credits — Director card + credit grid
- Footage / Gallery — Dark-background image grid
- Prizes — Festival awards and selections
- Investors / Partners — Logo grid or text list
- Next Project — Navigation to adjacent case study
Each section separated by a pel-section-divider with label text.
Full page architecture: references/page-architecture.md.
Implementation Rules
- Vanilla only. No React, Vue, Svelte, Angular. Plain HTML + CSS + JS.
- Single-file output. Everything in one HTML file. CDN imports for Google Fonts and optional Phosphor Icons only.
- Warm-first. Body background is
--pel-cream, not white, not dark. The dark gallery is one section, not the whole page. --pel-*tokens everywhere. Never hardcode colors — always reference custom properties.prefers-reduced-motionrequired. Everydata-pelanimation must have a reduced-motion fallback.requestAnimationFrameonly for parallax scroll. NeversetInterval.- Semantic HTML.
<article>for case study,<section>for each content block,<figure>for images,<dl>for credits. - Skip link required.
<a href="#main" class="pel-skip-link">as first body child. - Credits are grids, not cards. Role/name pairs in a CSS grid with border separators — not card containers with shadows.
- One accent, one purpose.
--pel-redis for the play button only.
Anti-Patterns
- Never use white (
#FFFFFF) backgrounds — always--pel-cream - Never use card containers with shadows for credits — use bordered grid cells
- Never use avatar circles for the director portrait — cropped photographic portrait with dark overlay
- Never use Inte