Skip to content

catalog: volume card overhaul (identity band + a11y pass)#5146

Open
QuiltSimon wants to merge 14 commits into
dx-shell-rehomefrom
dx-shell-rehome-simon-cards
Open

catalog: volume card overhaul (identity band + a11y pass)#5146
QuiltSimon wants to merge 14 commits into
dx-shell-rehomefrom
dx-shell-rehome-simon-cards

Conversation

@QuiltSimon

@QuiltSimon QuiltSimon commented Jul 24, 2026

Copy link
Copy Markdown
Contributor

Overhauls the Home volume cards so a wall of buckets differentiates at a glance and reads in clear priority order — within the Lab Instrument doctrine (quiet chrome, one accent, border-first, no gloss).

The new work (this PR's substance — top 2 commits)

  • b8f93526 — volume card overhaul. Identity band: the seeded glyph is promoted from a 32px corner avatar to a 44px identity mark on a quiet wash of the bucket's own tint (border-first, no gradient). Hierarchy re-ranked: title → s3:// URI in Roboto Mono (Mono Identity Rule) → description → tags → a first-class "Shared with N" access footer. Card rests on a hairline, not a shadow (Elevation doctrine). BucketIcon now exports resolveTint so the card header, the hover edge, the title hover, and the sibling BucketList row all read one shared --bucket-tint — card, icon, and list-row are provably one vocabulary. A meta row is reserved as the seam for a future trust readout (the Home query doesn't carry lastIndexed/counts yet — deferred deliberately).
  • 20d04016 — a11y pass (pre-PR critique fixes). Card-level :focus-within ring (tint border + soft tint outer ring, verified on both the white surface and the tinted band, WCAG 2.4.7); the s3:// URI link is tabIndex={-1} in grid + list so the title is the single keyboard tab stop per item (no double-stop); URI contrast lifted from text.hint (~2.9:1) to text.secondary (~4.6:1, AA); hover shadow dropped — the tint-border carries hover, so the card is flat at rest and on hover (no Elevation exception needed).

Impeccable review

Ran the dual-agent critique as a pre-PR gate. Verdict 32/40, initially no-ship on two P1 a11y blockers (focus ring, keyboard double-stop) + one P2 contrast token — all fixed in 20d04016 before this PR. Deterministic detector: clean (exit 0, zero findings) on both BucketGrid files. tsc clean; BucketGrid spec passing.

Deferred P3 follow-ups (not blockers): dead meta CSS is a documented seam; custom-image onError fallback; many-tags card-height balloon.

Scope note

This branch is off dx-shell-rehome-simon, and the base dx-shell-rehome is behind it — so this PR also carries the commits already under review on #5135 (bucket-icon picker, glyph model, sidebar/Athena polish, the Qurator rename) plus earlier un-merged catalog work and 3 Dependabot bumps. The two card commits above are the new content here. If preferred, this can be rebased once #5135 lands so the card diff stands alone.

Verification caveat

The card was verified via tsc, the spec, the mechanical detector, and a faithful standalone render (real tints + glyph data + the actual style values) — not the live app, since the review tooling in this environment can't screenshot the React SPA route directly. Worth a real in-app look before merge.

🤖 Generated with Claude Code

Greptile Summary

This PR overhauls the catalog’s volume identity and navigation presentation.

  • Adds deterministic and selectable bucket glyphs with optional colors.
  • Reworks volume grid/list cards, filtering controls, collaborators, logos, and the collapsible sidebar.
  • Refines Athena query layouts and updates Pillow dependency locks.
  • Updates the catalog design contract and related UI assets/configuration.

Confidence Score: 3/5

The PR should not merge until the sidebar is allowed to rerender when its live authentication, bookmark, assistant, and subscription inputs change.

The temporary Freeze comparator treats the entire navigation rail as unchanged whenever collapse state is stable, leaving multiple user-visible context-driven controls stale.

catalog/app/containers/Sidebar/Sidebar.tsx

Important Files Changed

Filename Overview
catalog/app/components/BucketIcon/BucketIcon.tsx Adds parsing, construction, tint resolution, and inline rendering for deterministic and explicitly selected bucket glyphs.
catalog/app/containers/Admin/Buckets/Buckets.tsx Adds the glyph/color picker and persists deterministic defaults through existing bucket mutations.
catalog/app/containers/Home/BucketGrid/BucketGrid.tsx Rebuilds volume cards around tint-aware identity bands, tags, and optional collaborator footers.
catalog/app/containers/Home/BucketGrid/BucketList.tsx Applies the new volume identity and collaborator presentation to dense list rows.
catalog/app/containers/Sidebar/Sidebar.tsx Adds collapsible rail branding and navigation, but the temporary memoization wrapper suppresses live context updates.
catalog/app/containers/Queries/Athena/Athena.tsx Consolidates Athena controls, editor, results, and history into a shared width-capped layout.
lambdas/thumbnail/pyproject.toml Advances the Pillow compatibility range to the 12.3 release line.

Flowchart

%%{init: {'theme': 'neutral'}}%%
flowchart LR
  Admin[Admin bucket form] -->|stores iconUrl| Config[Bucket configuration]
  Config --> Icon[BucketIcon resolver]
  Icon -->|quilt-glyph scheme| SVG[Inline seeded SVG]
  Icon -->|custom URL| Image[Custom image]
  SVG --> Grid[Volume grid/list]
  Image --> Grid
  Grid --> Identity[Identity band, tags, collaborators]
Loading

Reviews (1): Last reviewed commit: "catalog: volume card a11y pass — focus r..." | Re-trigger Greptile

Greptile also left 1 inline comment on this PR.

Context used:

dependabot Bot and others added 14 commits July 21, 2026 06:08
…5125)

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
…eview (#5127)

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
…5128)

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Website register (landing bucket grid):
- Expand seeded BucketIcon glyphs to a 79-entry scientifically-oriented
  library (labware, molecular bio, microbiology, chemistry, data-viz,
  clinical) in components/BucketIcon/seedGlyphs.ts.
- Add page-level collision-free glyph assignment (assignGlyphs: hashed
  preferred slot + linear probe) so no two visible buckets share a glyph;
  wire glyphIndex through BucketGrid (cards) and BucketList (rows).
- Tint still hashes from name for color variety independent of glyph.

Shell: collapsible sidebar rail (animated width with content reflow),
logo/wordmark assets, NavBar + Landing Buckets adjustments.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
The collaborator count was a floating MUI Badge in the card's top-right
corner; its translate(50%,-50%) overhang collided with the rounded corner
and clipped. Replace it with a quiet lab-instrument readout in one visual
language, two densities:

- Cards (footer variant): "Shared with N" on a divider baseline that lines
  up across every card, with an "Only you" private state. Card body reorders
  to description -> tags -> flex spacer -> footer so rows stay uniform.
- Rows/list (inline variant): the label collapses to a visually-hidden span
  (kept for screen readers; tooltip carries it), leaving a compact glyph +
  tabular count that right-aligns down the list. A conditional right gutter
  keeps tags and the title/address from sliding under the readout.

Collaborators gains a variant prop ('footer' default, 'inline' for rows);
count uses tabular-nums and mutes until hover. Unmanaged roles still surface
as "N+".

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Removes the localhost:8400 dev-only <script> injection that leaked into
the committed HTML and was failing oxfmt --check (test-catalog).

Co-authored-by: Cursor <cursoragent@cursor.com>
- tagStyles.ts: one tag vocabulary (square, soft-tertiary at rest, solid
  when active) shared by the card, list row, and shortcuts so the three
  call sites can't drift apart again.
- fix chip active-state false positive: match on tokenized filter terms
  instead of substring (`filter.includes('rna')` was lighting up while
  filtering "rna-seq").
- gate the card entrance animation behind prefers-reduced-motion: no-preference.
- title reads text.primary at rest, tertiary on hover (matches the list row).
- add-tile border uses the tertiary token, not the retired off-palette indigo.
- empty-search state: calmer h6 headline + a "Clear filter" recovery button.

Co-authored-by: Cursor <cursoragent@cursor.com>
Make the seeded bucket icon a real bucket attribute rather than a
per-view render artifact.

- BucketIcon: extend the quilt-glyph: scheme to carry an optional disc
  color (quilt-glyph:<name>?c=RRGGBB) via parseGlyphSrc/buildGlyphSrc, so
  an admin-chosen color rides inside the single iconUrl string with no
  backend schema change. Thread the color through seedToArt (it overrides
  the hashed tint; wash/ring still derive from the one tint so the chip
  stays coherent). Add defaultGlyphSrcForBucket for a deterministic
  per-bucket default.
- seedGlyphs: fix the centrifuge glyph (was reading as a cloud at the 24px
  blind-read gate). Add a category model over the existing GLYPHS order
  (GLYPH_CATEGORIES boundaries + GLYPH_GROUPS) — metadata only, order is
  preserved because the website register hashes names into indices.
- BucketGrid/BucketList: render stored iconUrl first; only fall back to the
  collision-free assignGlyphs pass for legacy buckets with no stored icon.

The icon now looks identical in the grid, list, and admin, and persists on
create / on the next admin save for legacy buckets.

Co-Authored-By: Claude <noreply@anthropic.com>
…to-open

Rebuild the admin glyph picker around the persisted glyph+color model.

- Click-to-open: the live BucketIcon preview is itself the trigger (a
  keyboard-accessible button, amber two-layer focus ring that holds on both
  the white card and the canvas, reduced-motion-gated hover) — no separate
  "Choose a glyph" button.
- Findability: a pinned autoFocus search field; at rest the ~200 glyphs
  render grouped under 12 sticky category headings (from GLYPH_GROUPS);
  typing collapses to a flat prefix-then-substring ranked list; empty →
  "No glyphs match".
- Color: an Auto chip (name-hashed tint) + the six on-palette SEED_TINTS
  swatches (human-named) + an in-app Roboto Mono hex field (replaces the
  native OS colour dialog, which broke the light-theme surface). Selected
  swatch/Auto carry a checkmark — a non-colour selection cue.
- The selected glyph's human label renders under the preview.
- On create, a bucket with no chosen icon persists a deterministic default;
  the edit form pre-fills that default for legacy null-iconUrl buckets so a
  save materialises it.
- Add a file-scoped detector ignore for broken-image on BucketIcon.tsx (the
  rule naive-matches the literal <img> token in code comments); gitignore
  the impeccable critique snapshots as per-session artifacts.

Co-Authored-By: Claude <noreply@anthropic.com>
Design/UX polish thread that was in flight alongside the glyph work.

- Sidebar: collapsible rail — logo crossfade (icon <-> wordmark) and label
  fade/slide on collapse, kept compositor-only (opacity/transform) except the
  rail's own width, which must reflow the content column.
- Queries/Athena: align the query selector row with the workgroup Select
  (label + input rows match), layout containers, and empty/disabled-state
  handling so the columns line up instead of showing bare text.

Co-Authored-By: Claude <noreply@anthropic.com>
The left-rail assistant entry reads just "Qurator" (the chat-input
placeholder in the assistant panel keeps "Ask Qurator").

Co-Authored-By: Claude <noreply@anthropic.com>
Make the Home volume cards differentiate at a glance and read in clear
priority order, within the Lab Instrument doctrine (quiet chrome, one
accent, border-first, no gloss).

- Identity band: promote the seeded glyph from a 32px corner avatar to a
  44px identity mark on a quiet wash of the bucket's own tint. A wall of
  volumes now reads by colour+glyph instantly. Border-first bottom rule,
  no gradient.
- Hierarchy: title (scan anchor) -> s3:// URI in Roboto Mono (Mono Identity
  Rule) -> description -> tags -> access footer. Card rests on a hairline,
  not a shadow (Elevation doctrine); a `meta` row is reserved as the seam
  for a future trust readout (the Home query doesn't carry lastIndexed /
  counts yet — deferred deliberately).
- Access: the "Shared with N" collaborator readout is a first-class footer
  on a consistent baseline.
- Hover: the card edge takes the bucket tint and lifts one step; single
  transition, reduced-motion-gated.
- BucketIcon exports resolveTint so the card header and the list-row hover
  reuse the same tint hashing (explicit ?c= wins, else name-hash) instead
  of re-deriving it. BucketList row hover + title/name hover now track the
  bucket tint too, so grid and list stay one vocabulary.

Co-Authored-By: Claude <noreply@anthropic.com>
…trast

Pre-PR critique fixes on the redesigned card (grid + list, kept in parity):

- Focus (WCAG 2.4.7): add a card-level :focus-within ring (tint border + a
  soft tint outer ring) so keyboard focus is visible on both the white
  surface and the tinted identity band. Previously only :hover was styled.
- Keyboard path: the s3:// URI link is now tabIndex={-1} in both the grid
  card and the list row, so the title is the single tab stop per item — no
  more confusing double-stop to the same route for keyboard/AT users. The
  URI stays a mouse target with its title attr.
- Contrast: the s3:// URI moves from text.hint (~2.9:1, below AA) to
  text.secondary (~4.6:1, AA) — it's copy-paste machine identity and must be
  legible. List scheme prefix likewise lifted off the near-invisible hint.
- Hover: drop the transient box-shadow; the tint-border alone carries the
  hover state, so the card is flat at rest AND on hover (Elevation doctrine,
  border-first) — no shadow exception needed.

Co-Authored-By: Claude <noreply@anthropic.com>
@cursor

cursor Bot commented Jul 24, 2026

Copy link
Copy Markdown

Bugbot is not enabled for your account, so this pull request was not reviewed.

Enable Bugbot in the Cursor dashboard to get automatic reviews on future PRs.

@QuiltSimon

Copy link
Copy Markdown
Contributor Author

@nl0 — new PR for the Home volume-card overhaul, off the dx-shell-rehome-simon line. The two new commits are b8f9352 (card redesign: tinted identity band, hierarchy, first-class access footer, single-sourced --bucket-tint shared with the icon + list row) and 20d0401 (a11y pass).

Ran it through the Impeccable dual-agent critique as a pre-PR gate: 32/40, and the two P1 a11y blockers it found (focus-visible ring, keyboard double-stop) plus a P2 URI contrast token are all fixed in 20d0401. Detector clean, tsc clean, spec passing.

Heads-up on scope: because the base (dx-shell-rehome) is behind this branch, the PR also carries everything already on #5135 — the card commits are the only new content here. Happy to rebase once #5135 lands so the card diff stands alone. Also: verified via a faithful standalone render, not the live app (tooling here can't screenshot the SPA route) — worth a real in-app look.

Comment on lines 332 to 335
const Freeze = React.memo(
({ children }: { children: React.ReactNode }) => <>{children}</>,
() => true,
({ children }: { children: React.ReactNode; sig?: unknown }) => <>{children}</>,
(prev, next) => prev.sig === next.sig,
)

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P1 Memoization freezes sidebar state

When bookmarks, subscription status, assistant availability, authentication, or roles change without a collapse toggle, this comparator treats the entire rail as unchanged because it compares only sig. The sidebar therefore retains stale badges, warnings, navigation entries, and account information until it is collapsed, expanded, or remounted.

Knowledge Base Used: Catalog Frontend (catalog/app)

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