Skip to content

Subject pages: guided "genre dashboard" redesign (DRAFT — not for merge)#13062

Draft
lokesh wants to merge 20 commits into
internetarchive:masterfrom
lokesh:claude/genre-taxonomy-browse-9ohm0f
Draft

Subject pages: guided "genre dashboard" redesign (DRAFT — not for merge)#13062
lokesh wants to merge 20 commits into
internetarchive:masterfrom
lokesh:claude/genre-taxonomy-browse-9ohm0f

Conversation

@lokesh

@lokesh lokesh commented Jun 29, 2026

Copy link
Copy Markdown
Collaborator

Draft — not intended for merge. This bundles a large, exploratory
subject-page redesign into one place for review and reference. It is too big
and too entangled to ship as-is; the intent is to land it later as a series of
smaller, independently reviewable PRs. Opening as a draft to make the
cumulative work visible, not to request a merge.

genre.mp4

What this is

A redesign of subject pages (/subjects/<name>) into a guided, bookstore-style
"genre dashboard" — a visual masthead, a subgenre map, curated bookstore-style
collection rails, notable authors, and reader-facing browse threads — layered on
top of the existing data-driven subject page. Featured subjects
(science fiction, fantasy, mystery, romance) get hand-curated editorial content;
every other subject falls back to generic, signal-driven intent rails.

Highlights

  • Visual masthead (<ol-subject-hero>): soft background, fanned cover stack,
    at-a-glance stats (works / readable-now / years in print).
  • Subgenre map ("choose your flavor") with Lucide icons (SubjectFlavors).
  • Curated collections driven by subject_config.py (reader favorites, award
    rails, subgenre essentials, short standalones, begin-a-series, just-published,
    read-it-right-now), rendered as <ol-carousel> web components.
  • Browse toolbar (subject-browse.js): availability + language filters
    (sticky across sessions) and era chips, all re-filtering every rail client-side.
  • "More info" book-card popover (subject-book-card.js, book-tip.css) with
    lazy-loaded descriptions.
  • "Keep exploring" browse threads built from place / person / time facets
    (SubjectThreads.html, build_browse_threads).
  • Notable-authors portraits served by global photo id (/a/id) with an
    /a/olid fallback (SubjectAuthors.html).
  • Sparse-rail suppression: a rail hides entirely below a min_books
    threshold; "Read it right now" uses min_books=5 so a 1–4 book strip never
    shows. Threaded SubjectRail → QueryCarousel → RawQueryCarousel → LazyCarousel
    partial.
  • <ol-carousel> / <ol-tooltip> refinements (uniform 2:3 covers, denser
    layout, paged-in cover loading fix, tooltip top-layer promotion).

Scope / size

~18 commits, 32 files / ~4,650 insertions excluding i18n. The raw diff also
shows large i18n/*.po and package-lock.json churn from an upstream merge —
ignore those; they're not part of this work.

Deliberately excluded

  • conf/openlibrary.yml — a dev-only change (points cover reads at the
    production CDN because the local coverstore is ephemeral). Not committed; would
    alter production config.
  • Local analysis artifacts (security-audit notes, redesign-comparison HTML/assets,
    a vendored markdown editor).

Not done / would-be follow-ups before any real merge

  • Split into small, independently reviewable PRs.
  • Tests for the new JS (browse toolbar, book-card popover) and macros.
  • Accessibility + i18n review of the new components.
  • Performance review of the added per-page Solr work (facets, author works,
    author-photo lookups).

claude and others added 20 commits June 27, 2026 02:27
Reworks plain /subjects/<topic> pages into a more visual browse
experience, as the first step toward a richer genre taxonomy:

- New ol-subject-hero Lit web component renders a darkened, blurred
  cover-wall masthead built from the subject's top covers, with the
  heading, a stat strip (works / readable now / years in print) and
  search slotted on top (server-rendered, degrades gracefully).
- Replaces the single trending carousel with a stack of intent-based
  rows reusing QueryCarousel: trending, most widely read, highly rated,
  most want-to-read, available to read now, and recently published.
- New SubjectAuthors macro shows top authors as photo cards instead of
  a plain text list.
- Person/place/time subject pages keep the existing layout via a
  subject_type branch, so only plain subjects change for now.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_011E785hXFLmZ5SsZTJ4UDQC
Replaces the Slick-based carousel with the <ol-carousel> web component
(ported from the web-component-carousel branch) on subject pages, behind
an opt-in flag so the rest of the site is untouched.

- Port OlCarousel.js into the Lit bundle and export it (debug console
  logging stripped).
- Thread a web_component flag through QueryCarousel -> RawQueryCarousel
  -> the LazyCarousel partial -> books/custom_carousel.html, so opted-in
  carousels render <ol-carousel> while keeping lazy-loading and caching.
- books/custom_carousel.html renders the same book cards as slotted
  children of <ol-carousel> when the flag is set; the Slick path is
  unchanged otherwise.
- New js/ol-carousel module wires the existing CarouselLoadMore pipeline
  onto the component: it listens for ol-carousel-page-change and appends
  more cards near the end (offset paging, mirroring the Slick wrapper).
- lazy-carousel.js and the main bundle initialise ol-carousels after
  injection / at load, and the lazy loader no longer mistakes an
  ol-carousel for an empty result.
- The six subject-page carousels opt in via web_component=True.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_011E785hXFLmZ5SsZTJ4UDQC
Reworks the subject page from a stack of near-duplicate popularity
carousels into fewer, interpreted "paths," and adds a hand-curated
editorial layer for flagship subjects.

- New subject_config.py holds editorial content (tagline, description,
  subgenre map, curated collections) for featured subjects (Science
  Fiction, Fantasy). Attached in subjects.py GET; every other subject
  falls back gracefully.
- New SubjectRail macro: an interpreted rail = title + optional badge +
  a one-line "why this is here" caption, above an <ol-carousel> of books
  for any query.
- New SubjectFlavors macro: the "choose your flavor" subgenre map.
- subjects.html now renders, for featured subjects: hero tagline,
  about-this-genre prose, the subgenre map, and curated collections
  (e.g. Hugo/Nebula winners, Cyberpunk essentials, Short standalones).
  For every other subject it renders six differentiated, captioned
  intent rails (Trending / Most loved / Want-to-read / Short standalones
  / Fresh / Read-now) instead of redundant popularity sorts.
- Collections are backed by real search queries; the curation (which
  collections, framing, subgenre map, prose) is the authored layer.
  Award rails lean on award subject tags and act as an illustrative
  target where catalog coverage is thin.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_011E785hXFLmZ5SsZTJ4UDQC
- Add romance and mystery as featured subjects (tagline, prose, subgenre
  map, curated collections), bringing the showcase set to four.
- Lead every featured subject's collections with a guaranteed-populated
  "Reader favorites" rail and broaden the award-tag queries, so a
  flagship page never renders an empty top rail even where award subject
  tags are sparse.
- Add docs/genre-browse.md: documents the shipped Phase 1, and specs
  Phase 2 (indexing the existing observations mood/pace/length/content-
  warning data into Solr to unlock reader-feel browsing) and Phase 3.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_011E785hXFLmZ5SsZTJ4UDQC
…nomy-browse-9ohm0f

# Conflicts:
#	openlibrary/components/lit/index.js
#	openlibrary/macros/RawQueryCarousel.html
#	openlibrary/plugins/openlibrary/js/lazy-carousel.js
#	openlibrary/plugins/openlibrary/partials.py
#	openlibrary/templates/books/custom_carousel.html
Includes OLSubjectHero and OlCarousel from the genre-dashboard work
alongside upstream's components.

Claude-Session: https://claude.ai/code/session_016dYJiynHPGqgUxhYtwsfPE
Cards past the first page render with a placeholder src and the real
cover URL in data-lazy (books/custom_carousel_card.html). The legacy
Slick carousel swapped these via its default lazyLoad: 'ondemand'; the
new transform-based <ol-carousel> had no equivalent, so paged-in covers
kept their placeholder and never rendered.

Add _loadVisibleImages(), called from _updateInert() (which already runs
on every page/visibility change), swapping data-lazy to src for the
visible range plus a one-page lookahead.

Claude-Session: https://claude.ai/code/session_016dYJiynHPGqgUxhYtwsfPE
…kground

- Render covers in uniform 2:3 boxes (aspect-ratio + object-fit: cover)
  instead of natural aspect ratio, so the rail reads as an even grid.
- Smaller covers: 8 columns on desktop (was 6), scaling down responsively.
- Tighter spacing: gap 12px -> 8px, and zero the per-item margin/padding
  so the carousel gap owns inter-item spacing.
- Drop the decorated cream background/borders for ol-carousel rails so they
  blend into the page. Scoped to .ol-carousel--books; legacy carousel untouched.

Claude-Session: https://claude.ai/code/session_016dYJiynHPGqgUxhYtwsfPE
- New LucideIcon macro renders inline Lucide SVGs (ISC) by name.
- subject_config: each subgenre gets an "icon" key; SubjectFlavors renders
  it beside the name in an icon+text flex layout.
- Outrank the global a:link/a:hover underline so flavor-card names and
  blurbs are no longer underlined.

Note: subject-hero.css also carries in-progress .subject-rail hovercard
styles (committed at the repo owner's request). A pre-existing stylelint
no-descending-specificity warning between .subject-rail__title a and
.subject-stat__num a:hover remains in that in-progress section.

Claude-Session: https://claude.ai/code/session_016dYJiynHPGqgUxhYtwsfPE
Replace the blurry darkened cover-wall and dark scrim with a soft warm
background and dark text. Add an overlapping, fanned stack of up to 6
representative covers on the right (hidden under 900px). Update the
slotted text colours (h1/tagline/stats/links) from white to dark for the
light background.

Note: subject-hero.css also carries in-progress .subject-rail cover
styling (committed at the repo owner's request). The pre-existing
stylelint no-descending-specificity warning in that section remains.

Claude-Session: https://claude.ai/code/session_016dYJiynHPGqgUxhYtwsfPE
Drop the per-cover fan rotation (covers now upright), shrink them
(6.75rem -> 5rem), and reduce the overlap.

Claude-Session: https://claude.ai/code/session_016dYJiynHPGqgUxhYtwsfPE
Restore a symmetric per-cover rotation so the stack flays out like a
spread deck rather than a flat row, and add pointer-events: none so the
decorative covers don't react to hover.

(OLSubjectHero.js also carries the repo owner's border-radius tweak.)

Claude-Session: https://claude.ai/code/session_016dYJiynHPGqgUxhYtwsfPE
Add a parabolic per-cover translateY (middle highest, ends at the
baseline) on top of the fan rotation, so the deck arcs like a rainbow
instead of fanning from a flat baseline.

Claude-Session: https://claude.ai/code/session_016dYJiynHPGqgUxhYtwsfPE
Pivot each cover from a shared point below the stack (transform-origin
50% 175%) with heavier overlap and a larger per-cover rotation, so the
covers fan out like a spread hand of cards. Drops the explicit translateY
lift since the arc now falls out of the rotation.

Claude-Session: https://claude.ai/code/session_016dYJiynHPGqgUxhYtwsfPE
Bump cover width 5rem -> 6.5rem. The stack is hidden under 900px, so this
only affects the desktop masthead.

Claude-Session: https://claude.ai/code/session_016dYJiynHPGqgUxhYtwsfPE
The enlarged covers' fan splayed left over long descriptions (e.g. the
science-fiction page). Shrink covers (6.5rem -> 5.25rem), tighten the fan
(rotation 8deg -> 6deg, pivot 175% -> 145%), and add left padding to the
cover-stack so the flex layout reserves room for the splay — the rotated
covers can no longer overlap the slotted text.

Claude-Session: https://claude.ai/code/session_016dYJiynHPGqgUxhYtwsfPE
Change the author-card blurb from '<title>, N more books' to
'<title> and N more' (e.g. 'Foundation and 3 more').

Claude-Session: https://claude.ai/code/session_016dYJiynHPGqgUxhYtwsfPE
Genre and author cards (.flavor-card) now shift background white ->
--lightest-grey on hover, instead of turning the border blue with a
shadow. Smooth background-color transition.

(subject-hero.css also carries the repo owner's in-progress sidebar/layout work.)

Claude-Session: https://claude.ai/code/session_016dYJiynHPGqgUxhYtwsfPE
…polish

Bundles the remaining uncommitted subject-page work on this branch:

- Browse toolbar (subject-browse.js): availability + language filters
  (sticky across sessions) and era chips that re-filter every rail.
- "More info" book-card popover (subject-book-card.js, book-tip.css) with
  lazy-loaded descriptions.
- "Keep exploring" browse threads from place/person/time facets
  (SubjectThreads.html, build_browse_threads in subjects.py).
- Notable-authors portraits served by global photo id (/a/id) with an
  /a/olid fallback, so they render once an author has a real photos id
  (SubjectAuthors.html, subjects._attach_author_photos).
- Hide a rail entirely below a min_books threshold; "Read it right now"
  uses min_books=5 so a 1-4 book strip never shows (SubjectRail →
  QueryCarousel → RawQueryCarousel → LazyCarousel partial; subject_config).
- <ol-carousel>/<ol-tooltip> refinements and subject hero/flavor styling.

Excludes the dev-only conf/openlibrary.yml cover-host change and local
analysis artifacts.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants