feat: theming system, documentation, and photo grid regression tests
- Add configurable theme system with 4 presets (studio, minimal, editorial, classic)
- Theme controls fonts, colors, accent, photo frames, grain, and header dot
- Resolve themes from gallery.yaml: string shorthand or full object override
- Inject theme as CSS custom properties on <html> element
- Dynamic Google Fonts loading based on theme config
- OG image route reads accent/background from theme
- Refactor Studio overrides into conditional CSS via data-attributes
Documentation:
- Add docs/gallery-config.md with comprehensive configuration reference
- Add docs/theming.md with preset reference and custom theme guide
- Slim README to link to detailed docs
Fix CSS regression:
- Fix passepartout frame overflow:visible breaking next/image fill rendering
- Remove duplicate .photo-grid__item block that stripped overflow:hidden
Testing:
- Add e2e/photo-grid.spec.ts with 3 regression tests:
- Grid items render with real dimensions
- overflow:hidden CSS guard (catches the exact bug fixed)
- Images load with real pixel data (not blurhash)
Tooling:
- Add scripts/screenshots.ts for automated theme screenshot generation
- Handles dev server lifecycle, theme cycling, FadeIn + lazy image handling
2026-02-15 12:21:02 +01:00
# Theming
Control the visual identity of your gallery from `content/gallery.yaml` . Choose a built-in preset or customize individual properties — no CSS editing required.
## Quick Start
Add a single line to your `gallery.yaml` :
```yaml
theme: minimal
```
That's it. Your entire gallery switches to the minimal theme.
## Built-in Presets
feat: add noir, monograph, botanica presets + stacked/typographic/mosaic hero styles + showcase/filmstrip/editorial-flow gallery layouts
- 3 new theme presets: noir (darkroom analog), monograph (typographic book), botanica (organic nature)
- 3 new hero styles: stacked (fullbleed + thumbnail strip), typographic (text-only), mosaic (multi-image grid)
- 3 new gallery layouts: showcase (featured + grid), filmstrip (horizontal scroll), editorial-flow (alternating pairs)
- Extended config types, validation, and CSS tokens for all new options
- Updated theming docs with new presets table, descriptions, and example configs
2026-02-15 21:58:31 +01:00
| Preset | Style | Accent | Fonts | Hero | Frame | Grain |
| ------------- | ------------------------------ | ------------ | ---------------------------------- | ----------- | ------------ | ----- |
| **studio ** | Leica-inspired, editorial | 🔴 `#e60012` | Playfair Display + DM Sans | Split | Passepartout | ✓ |
| **minimal ** | Swiss brutalist, high contrast | ⚫ `#000000` | Geist + IBM Plex Mono | Fullbleed | None | ✗ |
| **editorial ** | Cinematic magazine, warm tones | 🟤 `#8B2500` | Bodoni Moda + Newsreader | Split | Shadow | ✗ |
| **classic ** | Gilded gallery, warm luxury | 🟡 `#c49a3c` | Cinzel + Crimson Pro | Minimal | Passepartout | ✗ |
| **noir ** | Darkroom analog, film noir | 🟠 `#ff6b35` | Libre Baskerville + Source Sans 3 | Fullbleed | Passepartout | ✓ |
| **monograph ** | Typographic, book-like | ⬛ `#333333` | Instrument Serif + Inter | Typographic | None | ✗ |
| **botanica ** | Organic, nature-inspired | 🟢 `#4a7c59` | Cormorant Garamond + Nunito Sans | Split | None | ✗ |
feat: theming system, documentation, and photo grid regression tests
- Add configurable theme system with 4 presets (studio, minimal, editorial, classic)
- Theme controls fonts, colors, accent, photo frames, grain, and header dot
- Resolve themes from gallery.yaml: string shorthand or full object override
- Inject theme as CSS custom properties on <html> element
- Dynamic Google Fonts loading based on theme config
- OG image route reads accent/background from theme
- Refactor Studio overrides into conditional CSS via data-attributes
Documentation:
- Add docs/gallery-config.md with comprehensive configuration reference
- Add docs/theming.md with preset reference and custom theme guide
- Slim README to link to detailed docs
Fix CSS regression:
- Fix passepartout frame overflow:visible breaking next/image fill rendering
- Remove duplicate .photo-grid__item block that stripped overflow:hidden
Testing:
- Add e2e/photo-grid.spec.ts with 3 regression tests:
- Grid items render with real dimensions
- overflow:hidden CSS guard (catches the exact bug fixed)
- Images load with real pixel data (not blurhash)
Tooling:
- Add scripts/screenshots.ts for automated theme screenshot generation
- Handles dev server lifecycle, theme cycling, FadeIn + lazy image handling
2026-02-15 12:21:02 +01:00
Default is `studio` if no theme is specified.
2026-03-08 16:42:32 +01:00
<table>
<tr>
<td align="center"><strong>Studio</strong><br><em>Leica-inspired, red dot</em></td>
<td align="center"><strong>Minimal</strong><br><em>Swiss brutalist, fullbleed hero</em></td>
</tr>
<tr>
<td><img src="screenshots/theme-studio-home.png" width="400" alt="Studio theme" /></td>
<td><img src="screenshots/theme-minimal-home.png" width="400" alt="Minimal theme" /></td>
</tr>
<tr>
<td align="center"><strong>Editorial</strong><br><em>Cinematic magazine, warm charcoal</em></td>
<td align="center"><strong>Classic</strong><br><em>Gilded gallery, gold accents</em></td>
</tr>
<tr>
<td><img src="screenshots/theme-editorial-home.png" width="400" alt="Editorial theme" /></td>
<td><img src="screenshots/theme-classic-home.png" width="400" alt="Classic theme" /></td>
</tr>
<tr>
<td align="center"><strong>Noir</strong><br><em>Darkroom analog, film noir</em></td>
<td align="center"><strong>Monograph</strong><br><em>Typographic, book-like</em></td>
</tr>
<tr>
<td><img src="screenshots/theme-noir-home.png" width="400" alt="Noir theme" /></td>
<td><img src="screenshots/theme-monograph-home.png" width="400" alt="Monograph theme" /></td>
</tr>
<tr>
<td align="center"><strong>Botanica</strong><br><em>Organic, nature-inspired</em></td>
<td></td>
</tr>
<tr>
<td><img src="screenshots/theme-botanica-home.png" width="400" alt="Botanica theme" /></td>
<td></td>
</tr>
</table>
2026-03-08 16:59:18 +01:00
### Grid View Examples
<table>
<tr>
<td align="center"><strong>Studio</strong></td>
<td align="center"><strong>Minimal</strong></td>
</tr>
<tr>
<td><img src="screenshots/theme-studio-grid.png" width="400" alt="Studio grid" /></td>
<td><img src="screenshots/theme-minimal-grid.png" width="400" alt="Minimal grid" /></td>
</tr>
<tr>
<td align="center"><strong>Editorial</strong></td>
<td align="center"><strong>Classic</strong></td>
</tr>
<tr>
<td><img src="screenshots/theme-editorial-grid.png" width="400" alt="Editorial grid" /></td>
<td><img src="screenshots/theme-classic-grid.png" width="400" alt="Classic grid" /></td>
</tr>
<tr>
<td align="center"><strong>Noir</strong></td>
<td align="center"><strong>Monograph</strong></td>
</tr>
<tr>
<td><img src="screenshots/theme-noir-grid.png" width="400" alt="Noir grid" /></td>
<td><img src="screenshots/theme-monograph-grid.png" width="400" alt="Monograph grid" /></td>
</tr>
<tr>
<td align="center"><strong>Botanica</strong></td>
<td></td>
</tr>
<tr>
<td><img src="screenshots/theme-botanica-grid.png" width="400" alt="Botanica grid" /></td>
<td></td>
</tr>
</table>
feat: restyle themes to be visually distinct
- Minimal: Swiss Brutalist — fullbleed hero, true B&W, zero-gap grid, Geist font
- Editorial: Cinematic Magazine — warm charcoal, Bodoni Moda serif, slow transitions
- Classic: Gilded Gallery — gold accents, Cinzel headings, passepartout, ornamental dividers
Updated config presets, per-theme color palettes, ~550 lines of scoped CSS overrides,
data-preset attribute on html element, responsive breakpoints, screenshots, and docs.
2026-02-15 17:17:25 +01:00
### What makes each theme unique
**Studio** (default) — Leica-inspired with a red nav dot, passepartout photo frames, film grain, and a split hero layout. Clean editorial feel with Playfair Display headings.
**Minimal** — Swiss Brutalist aesthetic inspired by Müller-Brockmann and Dieter Rams. Fullbleed hero image, true black/white palette, zero-gap photo grid with no hover effects, ultra-tiny navigation text. Every pixel earns its place.
**Editorial** — Cinematic magazine feel inspired by Aperture and Magnum Photos. Oversized Bodoni Moda serif titles, warm charcoal backgrounds, generous grid spacing, slow cinematic transitions with desaturation-on-idle photos, and pull-quote section labels.
**Classic** — Fine art gallery aesthetic with warm gold accents, Cinzel Roman capitals for headings, decorative ornamental dividers, warm passepartout frames, rounded corners, and an elegant gold header dot. Feels like a luxury exhibition catalog.
feat: add noir, monograph, botanica presets + stacked/typographic/mosaic hero styles + showcase/filmstrip/editorial-flow gallery layouts
- 3 new theme presets: noir (darkroom analog), monograph (typographic book), botanica (organic nature)
- 3 new hero styles: stacked (fullbleed + thumbnail strip), typographic (text-only), mosaic (multi-image grid)
- 3 new gallery layouts: showcase (featured + grid), filmstrip (horizontal scroll), editorial-flow (alternating pairs)
- Extended config types, validation, and CSS tokens for all new options
- Updated theming docs with new presets table, descriptions, and example configs
2026-02-15 21:58:31 +01:00
**Noir** — Darkroom analog aesthetic with warm amber accents on a deep cool-black base. Sepia-tinted photos with vignette hover effects, film-edge EXIF labels in monospace, and a grain overlay. Inspired by wet-plate photography and film noir cinematography.
**Monograph** — Type-first book design with no hero image. Features an 8rem serif title, numbered photo indices via CSS counters, slide-up EXIF captions, hairline dividers, and generous whitespace. Feels like an artist monograph.
**Botanica** — Organic, nature-inspired with forest green accents and warm linen backgrounds. Rounded corners, botanical ornament dividers (❧), italic captions, and gentle hover animations. Feels like a botanical field guide.
feat: theming system, documentation, and photo grid regression tests
- Add configurable theme system with 4 presets (studio, minimal, editorial, classic)
- Theme controls fonts, colors, accent, photo frames, grain, and header dot
- Resolve themes from gallery.yaml: string shorthand or full object override
- Inject theme as CSS custom properties on <html> element
- Dynamic Google Fonts loading based on theme config
- OG image route reads accent/background from theme
- Refactor Studio overrides into conditional CSS via data-attributes
Documentation:
- Add docs/gallery-config.md with comprehensive configuration reference
- Add docs/theming.md with preset reference and custom theme guide
- Slim README to link to detailed docs
Fix CSS regression:
- Fix passepartout frame overflow:visible breaking next/image fill rendering
- Remove duplicate .photo-grid__item block that stripped overflow:hidden
Testing:
- Add e2e/photo-grid.spec.ts with 3 regression tests:
- Grid items render with real dimensions
- overflow:hidden CSS guard (catches the exact bug fixed)
- Images load with real pixel data (not blurhash)
Tooling:
- Add scripts/screenshots.ts for automated theme screenshot generation
- Handles dev server lifecycle, theme cycling, FadeIn + lazy image handling
2026-02-15 12:21:02 +01:00
## Custom Theme
Start from any preset and override individual properties:
```yaml
theme:
feat: restyle themes to be visually distinct
- Minimal: Swiss Brutalist — fullbleed hero, true B&W, zero-gap grid, Geist font
- Editorial: Cinematic Magazine — warm charcoal, Bodoni Moda serif, slow transitions
- Classic: Gilded Gallery — gold accents, Cinzel headings, passepartout, ornamental dividers
Updated config presets, per-theme color palettes, ~550 lines of scoped CSS overrides,
data-preset attribute on html element, responsive breakpoints, screenshots, and docs.
2026-02-15 17:17:25 +01:00
preset: studio # base preset to extend (default: studio)
accent: '#2563eb ' # brand/accent color (any hex)
feat: theming system, documentation, and photo grid regression tests
- Add configurable theme system with 4 presets (studio, minimal, editorial, classic)
- Theme controls fonts, colors, accent, photo frames, grain, and header dot
- Resolve themes from gallery.yaml: string shorthand or full object override
- Inject theme as CSS custom properties on <html> element
- Dynamic Google Fonts loading based on theme config
- OG image route reads accent/background from theme
- Refactor Studio overrides into conditional CSS via data-attributes
Documentation:
- Add docs/gallery-config.md with comprehensive configuration reference
- Add docs/theming.md with preset reference and custom theme guide
- Slim README to link to detailed docs
Fix CSS regression:
- Fix passepartout frame overflow:visible breaking next/image fill rendering
- Remove duplicate .photo-grid__item block that stripped overflow:hidden
Testing:
- Add e2e/photo-grid.spec.ts with 3 regression tests:
- Grid items render with real dimensions
- overflow:hidden CSS guard (catches the exact bug fixed)
- Images load with real pixel data (not blurhash)
Tooling:
- Add scripts/screenshots.ts for automated theme screenshot generation
- Handles dev server lifecycle, theme cycling, FadeIn + lazy image handling
2026-02-15 12:21:02 +01:00
fonts:
feat: restyle themes to be visually distinct
- Minimal: Swiss Brutalist — fullbleed hero, true B&W, zero-gap grid, Geist font
- Editorial: Cinematic Magazine — warm charcoal, Bodoni Moda serif, slow transitions
- Classic: Gilded Gallery — gold accents, Cinzel headings, passepartout, ornamental dividers
Updated config presets, per-theme color palettes, ~550 lines of scoped CSS overrides,
data-preset attribute on html element, responsive breakpoints, screenshots, and docs.
2026-02-15 17:17:25 +01:00
heading: 'Inter' # Google Fonts name for headings
body: 'Inter' # body text
caption: 'JetBrains Mono' # EXIF captions
radius: 8 # border-radius in px (0 = sharp corners)
photoFrame: none # "none" | "passepartout" | "shadow"
grain: false # film grain overlay on photos
headerDot: false # accent-colored dot in the nav bar
feat: add noir, monograph, botanica presets + stacked/typographic/mosaic hero styles + showcase/filmstrip/editorial-flow gallery layouts
- 3 new theme presets: noir (darkroom analog), monograph (typographic book), botanica (organic nature)
- 3 new hero styles: stacked (fullbleed + thumbnail strip), typographic (text-only), mosaic (multi-image grid)
- 3 new gallery layouts: showcase (featured + grid), filmstrip (horizontal scroll), editorial-flow (alternating pairs)
- Extended config types, validation, and CSS tokens for all new options
- Updated theming docs with new presets table, descriptions, and example configs
2026-02-15 21:58:31 +01:00
heroStyle: split # "split" | "fullbleed" | "minimal" | "stacked" | "typographic" | "mosaic"
feat: theming system, documentation, and photo grid regression tests
- Add configurable theme system with 4 presets (studio, minimal, editorial, classic)
- Theme controls fonts, colors, accent, photo frames, grain, and header dot
- Resolve themes from gallery.yaml: string shorthand or full object override
- Inject theme as CSS custom properties on <html> element
- Dynamic Google Fonts loading based on theme config
- OG image route reads accent/background from theme
- Refactor Studio overrides into conditional CSS via data-attributes
Documentation:
- Add docs/gallery-config.md with comprehensive configuration reference
- Add docs/theming.md with preset reference and custom theme guide
- Slim README to link to detailed docs
Fix CSS regression:
- Fix passepartout frame overflow:visible breaking next/image fill rendering
- Remove duplicate .photo-grid__item block that stripped overflow:hidden
Testing:
- Add e2e/photo-grid.spec.ts with 3 regression tests:
- Grid items render with real dimensions
- overflow:hidden CSS guard (catches the exact bug fixed)
- Images load with real pixel data (not blurhash)
Tooling:
- Add scripts/screenshots.ts for automated theme screenshot generation
- Handles dev server lifecycle, theme cycling, FadeIn + lazy image handling
2026-02-15 12:21:02 +01:00
```
All properties are optional — omitted values fall back to the preset defaults.
## Properties Reference
### `accent`
The brand color used for hover effects, navigation highlights, the header dot, and OG social preview images.
### `fonts`
Google Fonts names. Fonts are loaded automatically — just use the name as it appears on [fonts.google.com ](https://fonts.google.com ). Three font slots:
- **heading** — album titles, hero title, section labels
- **body** — navigation, descriptions, UI text
- **caption** — EXIF metadata, photo captions
### `radius`
Border radius in pixels applied to photo grid items and album cards:
feat: restyle themes to be visually distinct
- Minimal: Swiss Brutalist — fullbleed hero, true B&W, zero-gap grid, Geist font
- Editorial: Cinematic Magazine — warm charcoal, Bodoni Moda serif, slow transitions
- Classic: Gilded Gallery — gold accents, Cinzel headings, passepartout, ornamental dividers
Updated config presets, per-theme color palettes, ~550 lines of scoped CSS overrides,
data-preset attribute on html element, responsive breakpoints, screenshots, and docs.
2026-02-15 17:17:25 +01:00
feat: theming system, documentation, and photo grid regression tests
- Add configurable theme system with 4 presets (studio, minimal, editorial, classic)
- Theme controls fonts, colors, accent, photo frames, grain, and header dot
- Resolve themes from gallery.yaml: string shorthand or full object override
- Inject theme as CSS custom properties on <html> element
- Dynamic Google Fonts loading based on theme config
- OG image route reads accent/background from theme
- Refactor Studio overrides into conditional CSS via data-attributes
Documentation:
- Add docs/gallery-config.md with comprehensive configuration reference
- Add docs/theming.md with preset reference and custom theme guide
- Slim README to link to detailed docs
Fix CSS regression:
- Fix passepartout frame overflow:visible breaking next/image fill rendering
- Remove duplicate .photo-grid__item block that stripped overflow:hidden
Testing:
- Add e2e/photo-grid.spec.ts with 3 regression tests:
- Grid items render with real dimensions
- overflow:hidden CSS guard (catches the exact bug fixed)
- Images load with real pixel data (not blurhash)
Tooling:
- Add scripts/screenshots.ts for automated theme screenshot generation
- Handles dev server lifecycle, theme cycling, FadeIn + lazy image handling
2026-02-15 12:21:02 +01:00
- `0` — sharp, editorial corners
- `4-8` — subtle rounding
- `12+` — soft, modern feel
### `photoFrame`
How photos are framed in the grid:
- **`none` ** — photos fill the grid cell directly
- **`passepartout` ** — museum-style mat border around each photo with print-style EXIF captions below
- **`shadow` ** — subtle drop shadow behind each photo
### `grain`
When `true` , a subtle film grain texture overlays each photo in the grid. Adds an analog, filmic character.
### `headerDot`
When `true` , shows a small accent-colored dot in the navigation bar (inspired by the Leica red dot).
### `heroStyle`
Controls the homepage hero layout:
feat: restyle themes to be visually distinct
- Minimal: Swiss Brutalist — fullbleed hero, true B&W, zero-gap grid, Geist font
- Editorial: Cinematic Magazine — warm charcoal, Bodoni Moda serif, slow transitions
- Classic: Gilded Gallery — gold accents, Cinzel headings, passepartout, ornamental dividers
Updated config presets, per-theme color palettes, ~550 lines of scoped CSS overrides,
data-preset attribute on html element, responsive breakpoints, screenshots, and docs.
2026-02-15 17:17:25 +01:00
feat: add noir, monograph, botanica presets + stacked/typographic/mosaic hero styles + showcase/filmstrip/editorial-flow gallery layouts
- 3 new theme presets: noir (darkroom analog), monograph (typographic book), botanica (organic nature)
- 3 new hero styles: stacked (fullbleed + thumbnail strip), typographic (text-only), mosaic (multi-image grid)
- 3 new gallery layouts: showcase (featured + grid), filmstrip (horizontal scroll), editorial-flow (alternating pairs)
- Extended config types, validation, and CSS tokens for all new options
- Updated theming docs with new presets table, descriptions, and example configs
2026-02-15 21:58:31 +01:00
- **`split` ** — title/nav on the left, hero image on the right (used by Studio, Editorial, Botanica)
- **`fullbleed` ** — hero image fills the entire viewport, title overlaid in the corner (used by Minimal, Noir)
feat: restyle themes to be visually distinct
- Minimal: Swiss Brutalist — fullbleed hero, true B&W, zero-gap grid, Geist font
- Editorial: Cinematic Magazine — warm charcoal, Bodoni Moda serif, slow transitions
- Classic: Gilded Gallery — gold accents, Cinzel headings, passepartout, ornamental dividers
Updated config presets, per-theme color palettes, ~550 lines of scoped CSS overrides,
data-preset attribute on html element, responsive breakpoints, screenshots, and docs.
2026-02-15 17:17:25 +01:00
- **`minimal` ** — centered title card with decorative ornament, hero image as a banner below (used by Classic)
feat: add noir, monograph, botanica presets + stacked/typographic/mosaic hero styles + showcase/filmstrip/editorial-flow gallery layouts
- 3 new theme presets: noir (darkroom analog), monograph (typographic book), botanica (organic nature)
- 3 new hero styles: stacked (fullbleed + thumbnail strip), typographic (text-only), mosaic (multi-image grid)
- 3 new gallery layouts: showcase (featured + grid), filmstrip (horizontal scroll), editorial-flow (alternating pairs)
- Extended config types, validation, and CSS tokens for all new options
- Updated theming docs with new presets table, descriptions, and example configs
2026-02-15 21:58:31 +01:00
- **`stacked` ** — full-viewport hero image with title gradient-overlaid at the bottom, horizontal thumbnail navigation strip below
- **`typographic` ** — no hero image; massive centered title with numbered album navigation list (used by Monograph)
- **`mosaic` ** — asymmetric multi-image grid with frosted-glass title overlay centered on top
2026-03-08 16:42:32 +01:00
<table>
<tr>
<td align="center"><strong>Split</strong></td>
<td align="center"><strong>Fullbleed</strong></td>
<td align="center"><strong>Minimal</strong></td>
</tr>
<tr>
<td><img src="screenshots/hero-split-home.png" width="280" alt="Split Hero" /></td>
<td><img src="screenshots/hero-fullbleed-home.png" width="280" alt="Fullbleed Hero" /></td>
<td><img src="screenshots/hero-minimal-home.png" width="280" alt="Minimal Hero" /></td>
</tr>
<tr>
<td align="center"><strong>Stacked</strong></td>
<td align="center"><strong>Typographic</strong></td>
<td align="center"><strong>Mosaic</strong></td>
</tr>
<tr>
<td><img src="screenshots/hero-stacked-home.png" width="280" alt="Stacked Hero" /></td>
<td><img src="screenshots/hero-typographic-home.png" width="280" alt="Typographic Hero" /></td>
<td><img src="screenshots/hero-mosaic-home.png" width="280" alt="Mosaic Hero" /></td>
</tr>
</table>
feat: add noir, monograph, botanica presets + stacked/typographic/mosaic hero styles + showcase/filmstrip/editorial-flow gallery layouts
- 3 new theme presets: noir (darkroom analog), monograph (typographic book), botanica (organic nature)
- 3 new hero styles: stacked (fullbleed + thumbnail strip), typographic (text-only), mosaic (multi-image grid)
- 3 new gallery layouts: showcase (featured + grid), filmstrip (horizontal scroll), editorial-flow (alternating pairs)
- Extended config types, validation, and CSS tokens for all new options
- Updated theming docs with new presets table, descriptions, and example configs
2026-02-15 21:58:31 +01:00
### `grid.layout`
Controls the photo grid layout on album pages:
- **`masonry` ** — Pinterest-style stacked columns, images shown at natural aspect ratios (default)
- **`uniform` ** — CSS Grid with fixed aspect ratio cells
- **`showcase` ** — first image displayed at full width (16:9), rest in standard grid
- **`filmstrip` ** — horizontal scroll of tall vertical image strips with scroll snapping
- **`editorial-flow` ** — alternating full-width (21:9) and side-by-side (4:3) image pairs
feat: theming system, documentation, and photo grid regression tests
- Add configurable theme system with 4 presets (studio, minimal, editorial, classic)
- Theme controls fonts, colors, accent, photo frames, grain, and header dot
- Resolve themes from gallery.yaml: string shorthand or full object override
- Inject theme as CSS custom properties on <html> element
- Dynamic Google Fonts loading based on theme config
- OG image route reads accent/background from theme
- Refactor Studio overrides into conditional CSS via data-attributes
Documentation:
- Add docs/gallery-config.md with comprehensive configuration reference
- Add docs/theming.md with preset reference and custom theme guide
- Slim README to link to detailed docs
Fix CSS regression:
- Fix passepartout frame overflow:visible breaking next/image fill rendering
- Remove duplicate .photo-grid__item block that stripped overflow:hidden
Testing:
- Add e2e/photo-grid.spec.ts with 3 regression tests:
- Grid items render with real dimensions
- overflow:hidden CSS guard (catches the exact bug fixed)
- Images load with real pixel data (not blurhash)
Tooling:
- Add scripts/screenshots.ts for automated theme screenshot generation
- Handles dev server lifecycle, theme cycling, FadeIn + lazy image handling
2026-02-15 12:21:02 +01:00
## Examples
### Minimal portfolio
feat: restyle themes to be visually distinct
- Minimal: Swiss Brutalist — fullbleed hero, true B&W, zero-gap grid, Geist font
- Editorial: Cinematic Magazine — warm charcoal, Bodoni Moda serif, slow transitions
- Classic: Gilded Gallery — gold accents, Cinzel headings, passepartout, ornamental dividers
Updated config presets, per-theme color palettes, ~550 lines of scoped CSS overrides,
data-preset attribute on html element, responsive breakpoints, screenshots, and docs.
2026-02-15 17:17:25 +01:00
feat: theming system, documentation, and photo grid regression tests
- Add configurable theme system with 4 presets (studio, minimal, editorial, classic)
- Theme controls fonts, colors, accent, photo frames, grain, and header dot
- Resolve themes from gallery.yaml: string shorthand or full object override
- Inject theme as CSS custom properties on <html> element
- Dynamic Google Fonts loading based on theme config
- OG image route reads accent/background from theme
- Refactor Studio overrides into conditional CSS via data-attributes
Documentation:
- Add docs/gallery-config.md with comprehensive configuration reference
- Add docs/theming.md with preset reference and custom theme guide
- Slim README to link to detailed docs
Fix CSS regression:
- Fix passepartout frame overflow:visible breaking next/image fill rendering
- Remove duplicate .photo-grid__item block that stripped overflow:hidden
Testing:
- Add e2e/photo-grid.spec.ts with 3 regression tests:
- Grid items render with real dimensions
- overflow:hidden CSS guard (catches the exact bug fixed)
- Images load with real pixel data (not blurhash)
Tooling:
- Add scripts/screenshots.ts for automated theme screenshot generation
- Handles dev server lifecycle, theme cycling, FadeIn + lazy image handling
2026-02-15 12:21:02 +01:00
```yaml
theme:
preset: minimal
feat: restyle themes to be visually distinct
- Minimal: Swiss Brutalist — fullbleed hero, true B&W, zero-gap grid, Geist font
- Editorial: Cinematic Magazine — warm charcoal, Bodoni Moda serif, slow transitions
- Classic: Gilded Gallery — gold accents, Cinzel headings, passepartout, ornamental dividers
Updated config presets, per-theme color palettes, ~550 lines of scoped CSS overrides,
data-preset attribute on html element, responsive breakpoints, screenshots, and docs.
2026-02-15 17:17:25 +01:00
accent: '#0066cc '
feat: theming system, documentation, and photo grid regression tests
- Add configurable theme system with 4 presets (studio, minimal, editorial, classic)
- Theme controls fonts, colors, accent, photo frames, grain, and header dot
- Resolve themes from gallery.yaml: string shorthand or full object override
- Inject theme as CSS custom properties on <html> element
- Dynamic Google Fonts loading based on theme config
- OG image route reads accent/background from theme
- Refactor Studio overrides into conditional CSS via data-attributes
Documentation:
- Add docs/gallery-config.md with comprehensive configuration reference
- Add docs/theming.md with preset reference and custom theme guide
- Slim README to link to detailed docs
Fix CSS regression:
- Fix passepartout frame overflow:visible breaking next/image fill rendering
- Remove duplicate .photo-grid__item block that stripped overflow:hidden
Testing:
- Add e2e/photo-grid.spec.ts with 3 regression tests:
- Grid items render with real dimensions
- overflow:hidden CSS guard (catches the exact bug fixed)
- Images load with real pixel data (not blurhash)
Tooling:
- Add scripts/screenshots.ts for automated theme screenshot generation
- Handles dev server lifecycle, theme cycling, FadeIn + lazy image handling
2026-02-15 12:21:02 +01:00
fonts:
feat: restyle themes to be visually distinct
- Minimal: Swiss Brutalist — fullbleed hero, true B&W, zero-gap grid, Geist font
- Editorial: Cinematic Magazine — warm charcoal, Bodoni Moda serif, slow transitions
- Classic: Gilded Gallery — gold accents, Cinzel headings, passepartout, ornamental dividers
Updated config presets, per-theme color palettes, ~550 lines of scoped CSS overrides,
data-preset attribute on html element, responsive breakpoints, screenshots, and docs.
2026-02-15 17:17:25 +01:00
heading: 'Outfit'
body: 'Outfit'
feat: theming system, documentation, and photo grid regression tests
- Add configurable theme system with 4 presets (studio, minimal, editorial, classic)
- Theme controls fonts, colors, accent, photo frames, grain, and header dot
- Resolve themes from gallery.yaml: string shorthand or full object override
- Inject theme as CSS custom properties on <html> element
- Dynamic Google Fonts loading based on theme config
- OG image route reads accent/background from theme
- Refactor Studio overrides into conditional CSS via data-attributes
Documentation:
- Add docs/gallery-config.md with comprehensive configuration reference
- Add docs/theming.md with preset reference and custom theme guide
- Slim README to link to detailed docs
Fix CSS regression:
- Fix passepartout frame overflow:visible breaking next/image fill rendering
- Remove duplicate .photo-grid__item block that stripped overflow:hidden
Testing:
- Add e2e/photo-grid.spec.ts with 3 regression tests:
- Grid items render with real dimensions
- overflow:hidden CSS guard (catches the exact bug fixed)
- Images load with real pixel data (not blurhash)
Tooling:
- Add scripts/screenshots.ts for automated theme screenshot generation
- Handles dev server lifecycle, theme cycling, FadeIn + lazy image handling
2026-02-15 12:21:02 +01:00
```
### Film photography blog
feat: restyle themes to be visually distinct
- Minimal: Swiss Brutalist — fullbleed hero, true B&W, zero-gap grid, Geist font
- Editorial: Cinematic Magazine — warm charcoal, Bodoni Moda serif, slow transitions
- Classic: Gilded Gallery — gold accents, Cinzel headings, passepartout, ornamental dividers
Updated config presets, per-theme color palettes, ~550 lines of scoped CSS overrides,
data-preset attribute on html element, responsive breakpoints, screenshots, and docs.
2026-02-15 17:17:25 +01:00
feat: theming system, documentation, and photo grid regression tests
- Add configurable theme system with 4 presets (studio, minimal, editorial, classic)
- Theme controls fonts, colors, accent, photo frames, grain, and header dot
- Resolve themes from gallery.yaml: string shorthand or full object override
- Inject theme as CSS custom properties on <html> element
- Dynamic Google Fonts loading based on theme config
- OG image route reads accent/background from theme
- Refactor Studio overrides into conditional CSS via data-attributes
Documentation:
- Add docs/gallery-config.md with comprehensive configuration reference
- Add docs/theming.md with preset reference and custom theme guide
- Slim README to link to detailed docs
Fix CSS regression:
- Fix passepartout frame overflow:visible breaking next/image fill rendering
- Remove duplicate .photo-grid__item block that stripped overflow:hidden
Testing:
- Add e2e/photo-grid.spec.ts with 3 regression tests:
- Grid items render with real dimensions
- overflow:hidden CSS guard (catches the exact bug fixed)
- Images load with real pixel data (not blurhash)
Tooling:
- Add scripts/screenshots.ts for automated theme screenshot generation
- Handles dev server lifecycle, theme cycling, FadeIn + lazy image handling
2026-02-15 12:21:02 +01:00
```yaml
theme:
preset: studio
feat: restyle themes to be visually distinct
- Minimal: Swiss Brutalist — fullbleed hero, true B&W, zero-gap grid, Geist font
- Editorial: Cinematic Magazine — warm charcoal, Bodoni Moda serif, slow transitions
- Classic: Gilded Gallery — gold accents, Cinzel headings, passepartout, ornamental dividers
Updated config presets, per-theme color palettes, ~550 lines of scoped CSS overrides,
data-preset attribute on html element, responsive breakpoints, screenshots, and docs.
2026-02-15 17:17:25 +01:00
accent: '#d4a017 '
feat: theming system, documentation, and photo grid regression tests
- Add configurable theme system with 4 presets (studio, minimal, editorial, classic)
- Theme controls fonts, colors, accent, photo frames, grain, and header dot
- Resolve themes from gallery.yaml: string shorthand or full object override
- Inject theme as CSS custom properties on <html> element
- Dynamic Google Fonts loading based on theme config
- OG image route reads accent/background from theme
- Refactor Studio overrides into conditional CSS via data-attributes
Documentation:
- Add docs/gallery-config.md with comprehensive configuration reference
- Add docs/theming.md with preset reference and custom theme guide
- Slim README to link to detailed docs
Fix CSS regression:
- Fix passepartout frame overflow:visible breaking next/image fill rendering
- Remove duplicate .photo-grid__item block that stripped overflow:hidden
Testing:
- Add e2e/photo-grid.spec.ts with 3 regression tests:
- Grid items render with real dimensions
- overflow:hidden CSS guard (catches the exact bug fixed)
- Images load with real pixel data (not blurhash)
Tooling:
- Add scripts/screenshots.ts for automated theme screenshot generation
- Handles dev server lifecycle, theme cycling, FadeIn + lazy image handling
2026-02-15 12:21:02 +01:00
grain: true
photoFrame: passepartout
```
### Modern magazine
feat: restyle themes to be visually distinct
- Minimal: Swiss Brutalist — fullbleed hero, true B&W, zero-gap grid, Geist font
- Editorial: Cinematic Magazine — warm charcoal, Bodoni Moda serif, slow transitions
- Classic: Gilded Gallery — gold accents, Cinzel headings, passepartout, ornamental dividers
Updated config presets, per-theme color palettes, ~550 lines of scoped CSS overrides,
data-preset attribute on html element, responsive breakpoints, screenshots, and docs.
2026-02-15 17:17:25 +01:00
feat: theming system, documentation, and photo grid regression tests
- Add configurable theme system with 4 presets (studio, minimal, editorial, classic)
- Theme controls fonts, colors, accent, photo frames, grain, and header dot
- Resolve themes from gallery.yaml: string shorthand or full object override
- Inject theme as CSS custom properties on <html> element
- Dynamic Google Fonts loading based on theme config
- OG image route reads accent/background from theme
- Refactor Studio overrides into conditional CSS via data-attributes
Documentation:
- Add docs/gallery-config.md with comprehensive configuration reference
- Add docs/theming.md with preset reference and custom theme guide
- Slim README to link to detailed docs
Fix CSS regression:
- Fix passepartout frame overflow:visible breaking next/image fill rendering
- Remove duplicate .photo-grid__item block that stripped overflow:hidden
Testing:
- Add e2e/photo-grid.spec.ts with 3 regression tests:
- Grid items render with real dimensions
- overflow:hidden CSS guard (catches the exact bug fixed)
- Images load with real pixel data (not blurhash)
Tooling:
- Add scripts/screenshots.ts for automated theme screenshot generation
- Handles dev server lifecycle, theme cycling, FadeIn + lazy image handling
2026-02-15 12:21:02 +01:00
```yaml
theme:
preset: editorial
radius: 12
fonts:
feat: restyle themes to be visually distinct
- Minimal: Swiss Brutalist — fullbleed hero, true B&W, zero-gap grid, Geist font
- Editorial: Cinematic Magazine — warm charcoal, Bodoni Moda serif, slow transitions
- Classic: Gilded Gallery — gold accents, Cinzel headings, passepartout, ornamental dividers
Updated config presets, per-theme color palettes, ~550 lines of scoped CSS overrides,
data-preset attribute on html element, responsive breakpoints, screenshots, and docs.
2026-02-15 17:17:25 +01:00
heading: 'Fraunces'
body: 'Inter'
caption: 'IBM Plex Mono'
```
### Luxury gallery
```yaml
theme:
preset: classic
accent: '#b8860b '
fonts:
heading: 'Playfair Display'
body: 'Lora'
feat: theming system, documentation, and photo grid regression tests
- Add configurable theme system with 4 presets (studio, minimal, editorial, classic)
- Theme controls fonts, colors, accent, photo frames, grain, and header dot
- Resolve themes from gallery.yaml: string shorthand or full object override
- Inject theme as CSS custom properties on <html> element
- Dynamic Google Fonts loading based on theme config
- OG image route reads accent/background from theme
- Refactor Studio overrides into conditional CSS via data-attributes
Documentation:
- Add docs/gallery-config.md with comprehensive configuration reference
- Add docs/theming.md with preset reference and custom theme guide
- Slim README to link to detailed docs
Fix CSS regression:
- Fix passepartout frame overflow:visible breaking next/image fill rendering
- Remove duplicate .photo-grid__item block that stripped overflow:hidden
Testing:
- Add e2e/photo-grid.spec.ts with 3 regression tests:
- Grid items render with real dimensions
- overflow:hidden CSS guard (catches the exact bug fixed)
- Images load with real pixel data (not blurhash)
Tooling:
- Add scripts/screenshots.ts for automated theme screenshot generation
- Handles dev server lifecycle, theme cycling, FadeIn + lazy image handling
2026-02-15 12:21:02 +01:00
```
feat: add noir, monograph, botanica presets + stacked/typographic/mosaic hero styles + showcase/filmstrip/editorial-flow gallery layouts
- 3 new theme presets: noir (darkroom analog), monograph (typographic book), botanica (organic nature)
- 3 new hero styles: stacked (fullbleed + thumbnail strip), typographic (text-only), mosaic (multi-image grid)
- 3 new gallery layouts: showcase (featured + grid), filmstrip (horizontal scroll), editorial-flow (alternating pairs)
- Extended config types, validation, and CSS tokens for all new options
- Updated theming docs with new presets table, descriptions, and example configs
2026-02-15 21:58:31 +01:00
### Dark analog portfolio
```yaml
theme:
preset: noir
heroStyle: stacked
```
### Type-forward monograph
```yaml
theme:
preset: monograph
accent: '#444 '
fonts:
heading: 'DM Serif Text'
```
### Nature / travel journal
```yaml
theme:
preset: botanica
heroStyle: mosaic
grid:
layout: editorial-flow
```