<feed xmlns='http://www.w3.org/2005/Atom'>
<title>albumen.git/views/layout.erb, branch main</title>
<subtitle>Ruby/Sinatra photo album</subtitle>
<link rel='alternate' type='text/html' href='https://git.jots.org/albumen.git/'/>
<entry>
<title>Add photo search with Boolean operators</title>
<updated>2026-06-08T19:11:51+00:00</updated>
<author>
<name>Ken D'Ambrosio</name>
<email>ken@jots.org</email>
</author>
<published>2026-06-08T19:11:51+00:00</published>
<link rel='alternate' type='text/html' href='https://git.jots.org/albumen.git/commit/?id=00f63c03b7c5de68aea6a2305886bc1953a722b6'/>
<id>00f63c03b7c5de68aea6a2305886bc1953a722b6</id>
<content type='text'>
- Server-side search index built from all album.json files + people.json,
  cached in memory for 5 minutes.  Each photo document includes filename,
  album path words, title, caption, camera, date parts (year/month-name/
  full date), and person names.
- Recursive-descent Boolean parser: AND (explicit or implicit between
  consecutive terms), OR, NOT, with standard precedence.
- GET /search?q=... returns a photo grid (max 300 results) linking each
  photo back to its album lightbox.
- Search box added to the site header; hidden on mobile.
- Results show filename, date, person names, and album path per photo.

Co-Authored-By: Claude Sonnet 4.6 &lt;noreply@anthropic.com&gt;
</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
- Server-side search index built from all album.json files + people.json,
  cached in memory for 5 minutes.  Each photo document includes filename,
  album path words, title, caption, camera, date parts (year/month-name/
  full date), and person names.
- Recursive-descent Boolean parser: AND (explicit or implicit between
  consecutive terms), OR, NOT, with standard precedence.
- GET /search?q=... returns a photo grid (max 300 results) linking each
  photo back to its album lightbox.
- Search box added to the site header; hidden on mobile.
- Results show filename, date, person names, and album path per photo.

Co-Authored-By: Claude Sonnet 4.6 &lt;noreply@anthropic.com&gt;
</pre>
</div>
</content>
</entry>
<entry>
<title>Add people/face clustering feature</title>
<updated>2026-06-08T19:00:02+00:00</updated>
<author>
<name>Ken D'Ambrosio</name>
<email>ken@jots.org</email>
</author>
<published>2026-06-08T19:00:02+00:00</published>
<link rel='alternate' type='text/html' href='https://git.jots.org/albumen.git/commit/?id=01f52565f460a0107679999588b73b770f01a98c'/>
<id>01f52565f460a0107679999588b73b770f01a98c</id>
<content type='text'>
- scripts/cluster_faces.py: greedy centroid clustering (numpy) with 3
  refinement passes; preserves existing UUID/name mappings across re-runs;
  writes MEDIA_ROOT/people.json atomically.
- app.rb: GET /face/* serves cropped+padded face thumbnails (100x100,
  cached under cache/faces/); GET|POST /admin/people for cluster
  management; POST /admin/people/recluster runs cluster_faces.py as a
  background job; POST /admin/people/:uuid saves names+slugs; GET /people
  public grid of named people; GET /people/:slug photos for one person.
- views/admin/people.erb: lists all clusters (named first, then by size),
  face crop samples, inline name form, re-cluster button with live log.
- views/people.erb: public grid of named people.
- views/person.erb: photo grid for one person, linking back to album
  lightbox for each photo.
- views/layout.erb: People link in nav (conditional on FACES_ENABLED).
- public/css/style.css: styles for people admin list and public tiles.

Co-Authored-By: Claude Sonnet 4.6 &lt;noreply@anthropic.com&gt;
</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
- scripts/cluster_faces.py: greedy centroid clustering (numpy) with 3
  refinement passes; preserves existing UUID/name mappings across re-runs;
  writes MEDIA_ROOT/people.json atomically.
- app.rb: GET /face/* serves cropped+padded face thumbnails (100x100,
  cached under cache/faces/); GET|POST /admin/people for cluster
  management; POST /admin/people/recluster runs cluster_faces.py as a
  background job; POST /admin/people/:uuid saves names+slugs; GET /people
  public grid of named people; GET /people/:slug photos for one person.
- views/admin/people.erb: lists all clusters (named first, then by size),
  face crop samples, inline name form, re-cluster button with live log.
- views/people.erb: public grid of named people.
- views/person.erb: photo grid for one person, linking back to album
  lightbox for each photo.
- views/layout.erb: People link in nav (conditional on FACES_ENABLED).
- public/css/style.css: styles for people admin list and public tiles.

Co-Authored-By: Claude Sonnet 4.6 &lt;noreply@anthropic.com&gt;
</pre>
</div>
</content>
</entry>
<entry>
<title>Add albumen.png as app icon, favicon, and OG fallback image</title>
<updated>2026-05-12T17:28:59+00:00</updated>
<author>
<name>Ken D'Ambrosio</name>
<email>ken@jots.org</email>
</author>
<published>2026-05-12T17:28:59+00:00</published>
<link rel='alternate' type='text/html' href='https://git.jots.org/albumen.git/commit/?id=9c5704bdeb09c59c2fc2de931be3747c0e9cc210'/>
<id>9c5704bdeb09c59c2fc2de931be3747c0e9cc210</id>
<content type='text'>
- public/img/albumen.png: app logo
- public/favicon.ico: 32x32 + 16x16 multi-size
- public/apple-touch-icon.png: 180x180 for iOS home screen
- layout.erb: favicon link tags; og:image falls back to albumen.png
  when no specific photo is selected

Co-Authored-By: Claude Sonnet 4.6 &lt;noreply@anthropic.com&gt;
</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
- public/img/albumen.png: app logo
- public/favicon.ico: 32x32 + 16x16 multi-size
- public/apple-touch-icon.png: 180x180 for iOS home screen
- layout.erb: favicon link tags; og:image falls back to albumen.png
  when no specific photo is selected

Co-Authored-By: Claude Sonnet 4.6 &lt;noreply@anthropic.com&gt;
</pre>
</div>
</content>
</entry>
<entry>
<title>Add Open Graph meta tags for social media link previews</title>
<updated>2026-05-11T18:01:35+00:00</updated>
<author>
<name>Ken D'Ambrosio</name>
<email>ken@jots.org</email>
</author>
<published>2026-05-11T18:01:35+00:00</published>
<link rel='alternate' type='text/html' href='https://git.jots.org/albumen.git/commit/?id=c19b0854543abd5d05e0f1c0615c45464c169d29'/>
<id>c19b0854543abd5d05e0f1c0615c45464c169d29</id>
<content type='text'>
Co-Authored-By: Claude Sonnet 4.6 &lt;noreply@anthropic.com&gt;
</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
Co-Authored-By: Claude Sonnet 4.6 &lt;noreply@anthropic.com&gt;
</pre>
</div>
</content>
</entry>
<entry>
<title>Return to current album's edit page after admin login</title>
<updated>2026-05-11T04:01:56+00:00</updated>
<author>
<name>Ken D'Ambrosio</name>
<email>ken@jots.org</email>
</author>
<published>2026-05-11T04:01:56+00:00</published>
<link rel='alternate' type='text/html' href='https://git.jots.org/albumen.git/commit/?id=554daf97784302d4210e8e1dd2ec3c955ee33564'/>
<id>554daf97784302d4210e8e1dd2ec3c955ee33564</id>
<content type='text'>
Co-Authored-By: Claude Sonnet 4.6 &lt;noreply@anthropic.com&gt;
</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
Co-Authored-By: Claude Sonnet 4.6 &lt;noreply@anthropic.com&gt;
</pre>
</div>
</content>
</entry>
<entry>
<title>Add slideshow: root-level, shuffle, fullscreen, click-to-album</title>
<updated>2026-05-10T14:38:04+00:00</updated>
<author>
<name>Ken D'Ambrosio</name>
<email>ken@jots.org</email>
</author>
<published>2026-05-10T14:38:04+00:00</published>
<link rel='alternate' type='text/html' href='https://git.jots.org/albumen.git/commit/?id=a7c16b99a4284826ac5ac0ace4ee0f760a548ff4'/>
<id>a7c16b99a4284826ac5ac0ace4ee0f760a548ff4</id>
<content type='text'>
- Root slideshow: all_media_entries walks the full media tree so
  /slideshow/ shows every photo across all albums; Slideshow button
  always appears on the root album page
- Shuffle and Full screen checkboxes sit next to the Slideshow button
  on the album page; options pass as ?shuffle=1&amp;fullscreen=1 URL params
- Fullscreen uses a tap-to-activate overlay (browsers block auto-entry
  on page load); webkit-prefixed for Safari; ⛶ button and F key for
  mid-session toggle
- Fullscreen mode hides controls, counter, caption bar, and site header
- Exiting fullscreen auto-pauses so the current photo stays visible
- Click/tap anywhere in the stage navigates to the photo's album
  lightbox; reads the live src attribute instead of ssIdx to avoid a
  race where ssIdx advances during the cross-fade while the old photo
  is still on screen
- layout.erb excluded from slideshow (layout: false) so the site header
  never appears there
- CSS cache-busted with ?v=2

Co-Authored-By: Claude Sonnet 4.6 &lt;noreply@anthropic.com&gt;
</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
- Root slideshow: all_media_entries walks the full media tree so
  /slideshow/ shows every photo across all albums; Slideshow button
  always appears on the root album page
- Shuffle and Full screen checkboxes sit next to the Slideshow button
  on the album page; options pass as ?shuffle=1&amp;fullscreen=1 URL params
- Fullscreen uses a tap-to-activate overlay (browsers block auto-entry
  on page load); webkit-prefixed for Safari; ⛶ button and F key for
  mid-session toggle
- Fullscreen mode hides controls, counter, caption bar, and site header
- Exiting fullscreen auto-pauses so the current photo stays visible
- Click/tap anywhere in the stage navigates to the photo's album
  lightbox; reads the live src attribute instead of ssIdx to avoid a
  race where ssIdx advances during the cross-fade while the old photo
  is still on screen
- layout.erb excluded from slideshow (layout: false) so the site header
  never appears there
- CSS cache-busted with ?v=2

Co-Authored-By: Claude Sonnet 4.6 &lt;noreply@anthropic.com&gt;
</pre>
</div>
</content>
</entry>
<entry>
<title>Initial commit — Albumen photo album</title>
<updated>2026-05-09T04:41:03+00:00</updated>
<author>
<name>Ken</name>
<email>ken@jots.org</email>
</author>
<published>2026-05-09T04:41:03+00:00</published>
<link rel='alternate' type='text/html' href='https://git.jots.org/albumen.git/commit/?id=c75beda743dfd6af63f512e928d0889d9ead3973'/>
<id>c75beda743dfd6af63f512e928d0889d9ead3973</id>
<content type='text'>
Ruby/Sinatra self-hosted photo album with directory hierarchy,
per-photo captions and visibility, lightbox, slideshow, admin UI,
and Let's Encrypt HTTPS via Apache reverse proxy on prouter.

Co-Authored-By: Claude Sonnet 4.6 &lt;noreply@anthropic.com&gt;
</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
Ruby/Sinatra self-hosted photo album with directory hierarchy,
per-photo captions and visibility, lightbox, slideshow, admin UI,
and Let's Encrypt HTTPS via Apache reverse proxy on prouter.

Co-Authored-By: Claude Sonnet 4.6 &lt;noreply@anthropic.com&gt;
</pre>
</div>
</content>
</entry>
</feed>
