From a2ac39167b19bafc60a04b529e96f8b6cdb9195b Mon Sep 17 00:00:00 2001 From: wilfordgrimley <2397930+WilfordGrimley@users.noreply.github.com> Date: Tue, 4 Aug 2026 19:41:23 +0000 Subject: [PATCH] feat(question-feed): credit each illustration cluster via ArtistSupportLink Each Level 2 illustration cluster (candidates sharing a Scryfall illustrationId) now shows an artist credit sourced from the group's own candidate.artist, reusing the existing ArtistSupportLink applet (MTGAC page link + commerce links) rather than plain text - the same applet already used for the confirmed-artist post-answer moment and the /display rail. Gating and wording deliberately diverge from those two existing callers: this credit describes a candidate printing's artist from canonical Scryfall reference data, not a vote the user has cast, so it reads "Illustration by " rather than "Art by - support them" to avoid implying an assertion about the user's own scanned card. A cluster whose members carry no artist name renders no credit at all. Compactness (one applet per cluster, potentially several per grid) is achieved via a caller-side max-width wrapper rather than forking or restyling the shared component, per its own "stretch to fill" design rule. The per-tile artist caption becomes redundant once a cluster has its own credit, so it's dropped inside grouped clusters via a new optional renderCandidateTile parameter (additive, doesn't touch the shared data-card-* attributes or testids) while staying on ungrouped tiles, which have no cluster-level credit. Ungrouped candidates keep their existing plain-text artist caption unchanged: a flat grid can hold many candidates by many different artists, so a per-tile applet there would be disproportionately heavy next to a still-unconfirmed flat list. useGetArtistExternalLinksQuery already dedupes by its string arg (RTK Query's default cache-key behaviour), so multiple clusters sharing one artist collapse to a single request with no code change needed. Refs #385 for context (data-endpoint integration); does not close it. --- docs/features/artist-support-links.md | 18 ++++- .../features/questionFeed/QuestionFeed.tsx | 81 +++++++++++++------ 2 files changed, 74 insertions(+), 25 deletions(-) diff --git a/docs/features/artist-support-links.md b/docs/features/artist-support-links.md index 1df6db969..e68ed1e13 100644 --- a/docs/features/artist-support-links.md +++ b/docs/features/artist-support-links.md @@ -83,7 +83,7 @@ non-null) or a vote the user just cast themselves - never for a vote- pending or unknown artist, since there'd be no name to build a URL from. M2 didn't widen this gate at all, only what gets rendered once it's open. -## Surfaces (three, as of the Proposal H pane migration) +## Surfaces (four, as of the question-feed illustration-cluster credit) 1. **Card Detail Modal** (`CardDetailedViewModal.tsx`'s attribute table, the `"Canonical Aritst"` row - yes, that's a pre-existing typo in the @@ -114,6 +114,22 @@ M2 didn't widen this gate at all, only what gets rendered once it's open. rail's currently-selected slot's own `CardDocument` (already resident in `cardDocumentsByIdentifier`) for the artist name - the applet's own data fetch is separate (keyed by that name), not piggybacked on this read. +4. **`/whatsthat`'s Level 2 illustration clusters** (`QuestionFeed.tsx`, + the `IllustrationGroup` wrapper `illustrationGroups` renders around + candidates sharing a Scryfall `illustrationId`). Gating here differs + from surfaces 1-3: those gate on a _confirmed_ artist (a cast vote, or + `CardDocument.canonicalArtist` consensus); this one gates on the first + non-blank `candidate.artist` across the cluster's members - the artist + of a _candidate printing_, sourced from canonical Scryfall reference + data, before the voter has picked anything. Worded `"Illustration by "` rather than the `"Art by "` phrasing surfaces 2-3 use, so + it doesn't read as an assertion about the voter's own scanned card. The + applet itself renders unmodified; a `max-width` wrapper + (`IllustrationCredit`, caller-side only, not a `className` override of + the applet's own "stretch to fill" rule) keeps one full-bleed CTA per + cluster from reading as page-width inside a multi-cluster grid. The + per-tile artist caption is dropped inside grouped clusters (redundant + with the new cluster-level credit) but kept on ungrouped tiles, which + have no cluster credit of their own. **Not built** (explicitly out of scope, noted so a future session doesn't have to re-derive why): the confidently-known-artist collapsed display diff --git a/frontend/src/features/questionFeed/QuestionFeed.tsx b/frontend/src/features/questionFeed/QuestionFeed.tsx index 9aaac0f6c..fc19a6a84 100644 --- a/frontend/src/features/questionFeed/QuestionFeed.tsx +++ b/frontend/src/features/questionFeed/QuestionFeed.tsx @@ -339,6 +339,14 @@ const IllustrationGroupLabel = styled.p` margin: 0 0 4px; `; +// Caps the width of the reused ArtistSupportLink applet so a full-bleed button (its own +// "stretch to fill" rule - see the component's docstring, not overridden here) reads as a +// compact cluster credit rather than a page-width CTA repeated once per cluster. +const IllustrationCredit = styled.div` + max-width: 220px; + margin-bottom: 8px; +`; + // The spec's `.btn` base + variants (section 1c) - min 44px thumb targets (mobile funnel // pass, WCAG 2.5.5/Apple HIG), replacing the old `ThumbButton`/`FilterToggleButton` gold // overrides with plain token-derived variants. A native