diff --git a/frontend/src/components/PlexPersonView.dom.test.tsx b/frontend/src/components/PlexPersonView.dom.test.tsx index 931ef8de..11b5630e 100644 --- a/frontend/src/components/PlexPersonView.dom.test.tsx +++ b/frontend/src/components/PlexPersonView.dom.test.tsx @@ -251,3 +251,40 @@ describe("PlexPersonView — a bio on its way (E30 S6)", () => { expect(screen.queryByText("plex.person.more")).toBeNull(); // jsdom: nothing is cut }); }); + +describe("PlexPersonView — the hero's columns (E30 S6)", () => { + const heroGrid = async (knownFor: number) => { + plexPerson.mockReset(); + plexPerson.mockResolvedValue({ + name: "Jane Doe", + photo: null, + biography: "Bio.", + also_known_as: [], + known_for: Array.from({ length: knownFor }, (_, i) => card(`k${i}`, `Known ${i}`)), + movies: [card("m1", "Movie One")], + shows: [], + }); + const { container, unmount } = wrap( + {}} + onOpenCard={() => {}} + onRestartCard={() => {}} + onInfoCard={() => {}} + onFilter={() => {}} + />, + ); + await screen.findByText("Movie One"); + const cls = container.querySelector('section[class~="@container"] > div')!.className; + unmount(); + return cls; + }; + + it("gives a full rail half the hero and puts a short one right beside the text", async () => { + expect(await heroGrid(4)).toContain("@3xl:grid-cols-[minmax(0,1fr)_minmax(0,1fr)]"); + const short = await heroGrid(1); + expect(short).toContain("@3xl:grid-cols-[auto_auto]"); + expect(short).toContain("@3xl:justify-start"); + expect(await heroGrid(0)).not.toContain("grid"); + }); +}); diff --git a/frontend/src/components/plexViews.tsx b/frontend/src/components/plexViews.tsx index 3f7d3d09..47eb2755 100644 --- a/frontend/src/components/plexViews.tsx +++ b/frontend/src/components/plexViews.tsx @@ -122,8 +122,9 @@ export function PlexInfoView({ // How often, and for how long, a person page asks again for a bio that is on its way (E30 S6). The // background fetch takes a second or two; twenty seconds covers a slow TMDB without waiting on a dead one. const BIO_POLL_MS = 1500; -// From this many "Known for" titles the rail gets half the hero; fewer (about one person in five) get -// just their posters' width, so a lone poster doesn't sit in an empty half (E30 S6, measured). +// From this many "Known for" titles the rail gets half the hero. Fewer (about one person in five) sit +// right beside the text, at their posters' width, and what is left over is the panel's end — not a hole +// between the text and a lone poster at the far edge (E30 S6, owner pick "b"). const KNOWN_FOR_HALF = 4; const BIO_WAIT_MS = 20_000; @@ -297,11 +298,13 @@ export function PlexPersonView({ d.known_for.length >= KNOWN_FOR_HALF ? "grid gap-6 @3xl:grid-cols-[minmax(0,1fr)_minmax(0,1fr)]" : d.known_for.length > 0 - ? "grid gap-6 @3xl:grid-cols-[minmax(0,1fr)_auto]" + ? "grid gap-6 @3xl:grid-cols-[auto_auto] @3xl:justify-start" : undefined } > -
+ {/* The person's column is at most the bio's reading measure (text-sm, as the bio is), so a + short rail can sit right beside it. */} +
{d.photo ? (