Skip to content

fix(Lightbox): a single photo's caption sits on the caption's backing - #10284

Open
vjeux wants to merge 19 commits into
meta:mainfrom
vjeux:uikit/c13-single-caption-backing
Open

vjeux wants to merge 19 commits into
meta:mainfrom
vjeux:uikit/c13-single-caption-backing

Conversation

@vjeux

@vjeux vjeux commented Nov 6, 2026 •

Copy link
Copy Markdown
Contributor

Batch: B7 Lightbox
Stack: #9810 → #10284

Stacked on #9810, which adds a gallery's caption band. This head merges #9810's main merge, vjeux@9a9b0f7, where #9810's media-surface requirement became FR19, and FR1b now quotes only the owner's exact words, vjeux@801fa11. It then merges #9810's second main merge, which brings main's fix to the double-tap zoom's busy proof; the caption's backing is unchanged: vjeux@785873b. It then merges #9810's head for this round, which carries main's drag to close and shows "more" and "less" as an inline link: vjeux@c6efc6e. On this branch every item is a page of the track, a single photo too. So the drag to close moves each page's photo box, and the track takes its touches. Main's cases that read the old single caption read its band, and the zoom core drops the fit callback that placed that caption. A single photo's "more" is the same inline link as a gallery's. It then merges two more #9810 commits. One takes the toggle's touch target from Core's touch hit area, and one merges main for the drag to close's tempo: vjeux@2b0b009. FR19 stays settled here, since this branch closes the single photo's contrast gap. This pull request has four commits on #9810's 232f499, the same four as before (each patch unchanged): the earlier single-photo plate, vjeux@d2e76e4, the rework that replaces it with the gallery's band, vjeux@d398515, the notes and records that now cover a single photo, vjeux@50875b6, and FR1b's scope for a single captioned video, vjeux@b565bdc. Review them together: vjeux/astryx@232f499...b565bdc

User impact

A single photo and a set of photos now show their caption the same way. Before, a single photo's caption sat under the photo, centred with it, on a plate as wide as its text. A gallery's caption sits in a band at the bottom of the viewer: two lines tall, with "more" for a longer caption, and no band when no photo has a caption. The two looked like different components. Now a single photo uses the gallery's band, so a caption, its backing and the photo's place are the same whether the viewer holds one photo or many.

The caption keeps 4.5:1 contrast over any page behind the viewer, on the band's backing, as the earlier version of this pull request did with its plate.

Problem and solution fit

  • Why the difference occurred: a single photo laid out its own photo and caption, a separate path from the gallery's pages.
  • Why it harms the task: the same caption read differently by the photo count, its place moved, and a long caption on a single photo had no "more".
  • Why that matters: the caption is the photo's description. A reader who opens one photo and then a set should find it in the same place, in the same type.

The fix renders a single photo through the gallery's own page code. A single photo is the one page of the viewer's track, with the gallery's photo box and caption band. Only paging stays a gallery's.

Expected behavior and authority

component:Lightbox FR1b, as the record states it:

A single captioned item, a photo or a video, and a gallery present the caption the same way: the same plate, width, text treatment, inline "more", spacing and photo position, and no plate when there is no caption. (Owner direction, Nov 6 2026 (Cindy): the single-photo caption behaved differently from the gallery's, and "they really should be consistent".)

Named exceptions, in the same row:

  • A single photo has no Previous or Next button, no Counter and no paging, since there is no other item.
  • A drag past a zoomed single photo's edge rubber-bands and returns (FR6), where a gallery's pager takes it (FR7).

FR1b sits beside FR1 as its own row, because FR1's cell has 37 characters of slack and a longer FR1 would re-pad the whole table. The owners can fold it into FR1 if they prefer. Edits to the owners' line, for their re-stamp: a card id a reader can't resolve is dropped, and the citation keeps their "Owner direction" but quotes only Cindy's exact words, "they really should be consistent", with the rest in plain prose. FR19's verification row drops a black photo that no contrast case ran, and FR19 stays settled: this pull request removes the Current-state gap #9810 names.

What changed

  • Lightbox.tsx: a single photo renders as the one page of the track, with the gallery's pageMedia box (the zoom target) and caption band. The single photo's own wrapper, its plate style, the caption's lift under a fitted photo and the fit callback are removed. isGallery now gates only the pager, Previous/Next, the counter and the arrow keys. A single photo attaches no pager.
  • A zoomable photo box takes the stage's cursor instead of the CSS reset's button cursor. The zoom-in cursor shows over the fitted photo and the default arrow beside it, as a single photo always did. A gallery's photo row showed the reset's pointer cursor, which the shared code now fixes too.
  • Lightbox.doc.mjs: the caption prop says it shows in the band at the bottom of the viewer for every viewer.
  • New story "Single with long caption", with the same photo and caption as the gallery story's first page.
  • The changeset is rewritten.
  • Lightbox.spec.md: the "Captioned media" state says the caption shows in the band under the active page, for one photo or a gallery, and FR1b's exception names the touch pager. en.json: the "more" and "less" translator notes cover a single photo too.
  • Lightbox.spec.md, in the spec owners' scope: FR1b's first sentence covers a single captioned item, a photo or a video, and the "Captioned media" state says "for one item or a gallery". The code already shows a single video's caption in the band.

What stays different, and why: the two exceptions above. Nothing else.

Evidence

  • Side by side: a single photo beside a gallery's first page, with the same photo and caption, at 390 px and on a desktop, in light and dark. The band, the text, "more" and the photo's box match; only the gallery's counter and Previous/Next differ.

    390 px, light 390 px, dark
    a single photo beside a gallery's first page, 390 px, light the same, dark

    a single photo beside a gallery's first page, desktop, light

    the same, desktop, dark

    A short caption sits centred in the same band: short caption, 390 px, light

  • iPhone 17 Pro simulator (iOS 26.2, Safari): a single photo, a gallery's first page with the same photo and caption, and the single photo's caption opened by "more":

    a single photo, a gallery page, and the caption opened by more

    Zoomed by a pinch, the photo fills its box and the band stays put; with no caption, the photo box fills the viewer:

    a zoomed single photo a single photo with no caption

  • Red first: the new LightboxSingleCaption spec (band shape against a gallery's, "more" and "less", no band with no caption, no paging controls) fails 8/8 on fix(Lightbox): a single photo's caption sits on the caption's backing #10284's previous build in Chromium, and passes at this head in Chromium and WebKit, 24/24 each over three repeats.

  • Gallery unchanged: a pixel diff of every state of "Gallery with captions" (clamped, open, each page) at 1440, 402 and 360 px, LTR and RTL, against the previous build: 30/30 identical in Chromium.

Scope

  • One change: the single photo's caption path joins the gallery's.
  • Separable contradictory or unsettled tagalongs were removed or split.
  • No new public API, prop or token. The visible change is the band, named above with its before and after.
  • Public text and artifacts contain no internal Meta context.

Writing rubric results

  • R1 narration: none. FR1b and the "Captioned media" state describe the present behavior.
  • R2 research in the record: none.
  • R3 evidence naming a change: none.
  • R4 rejected alternatives: none in the record.
  • R5 pull request or issue references: none in the record.
  • R6 answered open questions still listing options: none.

Testing

At 2b0b009, on #9810's d038a4b, core tsc is clean. The Lightbox, motion, Text, Layer and Link unit files pass 1,891/1,891. pnpm check:knowledge, pnpm check:changesets, the motion role table check and CI's Changeset coverage step pass. In a 4-CPU container the Lightbox interaction specs pass 132 in Chromium (4 skips) and 125 in WebKit (11 skips). The Lightbox a11y specs pass 44 of 44 in Chromium and 42 in WebKit (2 skips), the toggle's touch target case included. Against #9810's head, this pull request's own diff changes in two places only. It re-indents #9810's new toggle lines, as it does the rest of that block, and FR19's state stays "settled".

At c6efc6e, on #9810's 5c56c40, core tsc is clean and strict ESLint is clean on the changed Lightbox files. The Lightbox, motion, Text, Layer and Link unit files pass 1,890/1,890. pnpm check:knowledge, pnpm check:changesets, the motion role table check and CI's Changeset coverage step pass. In a 4-CPU container the Lightbox interaction specs pass 130 in Chromium (4 skips) and 123 in WebKit (11 skips). The Lightbox a11y specs pass 43 of 43 in Chromium and 41 in WebKit (2 skips). Main's drag to close cases that read the old single caption read its band now. Held sideways, a dragged photo draws above the band. Without the photo box's z-index while dragged, that case fails in both engines: vjeux@37e5124 (not for landing). This head differs from 15ca3b9 only in one comment's line wrapping. The unit files and browser specs above ran at 15ca3b9. The Lightbox unit files pass again here, 159/159. Before and after stills of a single photo and a gallery, phone and desktop, from a sandbox page: https://github.com/vjeux/astryx/tree/000b3c2965f46b456998e6095c8a78ecf6730022/lightbox-caption-link-r8

At 785873b: core tsc is clean; the Lightbox, motion, Text and Layer unit files pass 1,740/1,740; pnpm check:knowledge passes.

At 801fa11, on #9810's 18d4bb5: core tsc is clean; the Lightbox, motion, Text and Layer unit files pass 1,740/1,740; pnpm check:knowledge passes. Before the merge, at b565bdc on #9810's 232f499 and main 88ba279: core tsc is clean; the Lightbox, motion, Text and Layer unit files pass 1,730/1,730; pnpm check:knowledge passes; the Lightbox interaction specs pass 100 in Chromium (3 skips) and 94 in WebKit in a 4-CPU container (9 skips); the Lightbox a11y specs pass 41 of 41 in Chromium.

At bd721e6, which merges #9810's e60fcca (the caption band joins the surfaces that read the device's safe-area insets themselves): this pull request's own diff is unchanged (the same patch-id); layerViewportInset.test.ts and the Text and Lightbox unit files pass 204/204; core tsc is clean.

At d56431d, which changes only the record's two lines: pnpm check:knowledge passes.

At fcf9c27, on #9810's dd85656 (main 5c1b7d4): core tsc 0; Text and Lightbox units 198/198; pnpm check:knowledge and pnpm check:changesets pass. Lightbox a11y specs: 41/41 in Chromium, 39 in WebKit (2 skips). Lightbox interaction specs: 100 in Chromium (3 skips) and 94 in WebKit in a 4-CPU container, the CI profile (9 skips), the new spec among them. The rework's one conflict with #9810's later caption measurement, in Lightbox.tsx, keeps both: this pull request's single track, with the band's always-mounted toggle and #8197's settled-page index.

At 2b845bc, on a Storybook build of that head (this head replays its two commits on #9810's d036f15 with the same patches, after main's v0.7.10 release):

  • core tsc 0; strict ESLint 0 on the changed files; Prettier clean; comment sentence lengths 0 over; pnpm check:knowledge and pnpm check:changesets pass;
  • Lightbox units 142/142, and usePager with them, 270/270;
  • Chromium Lightbox interaction specs: 95 passed, 3 WebKit-only skips, the new spec among them; Chromium Lightbox a11y specs: 40/40;
  • WebKit in a 4-CPU container (the CI profile): Lightbox interaction specs 90 passed, 8 Chromium-only skips; LightboxFinePointer, LightboxViewport and LightboxKeyboard 38 passed, 2 skips;
  • red first: the new spec fails 8/8 in Chromium on a Storybook built from 59c8fff, the single-photo plate commit before the rework, with this head's stories, the long caption on its missing "more".

On a Storybook build of 74bbab3, which differs from this head only by the zoom core's unused fit callback, a comment, the changeset's wording and FR1b's two edits: the gallery's pixels, every state of "Gallery with captions" (clamped, open, each page) at 1440, 402 and 360 px, LTR and RTL, match #10284's earlier build 1b7ae73, 30/30 identical in Chromium; and the new spec passes 24/24 in Chromium and 24/24 in WebKit (CI profile) over three repeats.

@vercel

vercel Bot commented Nov 6, 2026 •

Copy link
Copy Markdown

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated
astryx Ready Ready Preview Nov 8, 2026 7:44pm UTC

Request Review

@meta-cla meta-cla Bot added the CLA Signed This label is managed by the Meta Open Source bot. label Nov 6, 2026
@astracat-bot

astracat-bot Bot commented Nov 6, 2026 •

Copy link
Copy Markdown
Contributor

AI review status for this pull request.

Review status Updated
🟢 Reviewed (for maintainers only) Nov 8, 2026, 8:03 PM UTC

@github-actions github-actions Bot added the needs:design-review Affects visuals — Design should review label Nov 6, 2026
@github-actions github-actions Bot added the needs:spec-owner-review Current knowledge records await owner approval label Nov 6, 2026
@github-actions

github-actions Bot commented Nov 6, 2026 •

Copy link
Copy Markdown
Contributor

PR Analysis Report

🔎 Preview · 2b0b009

Storybook · Sandbox · built from this PR's head

Modified components

Component Size LoC Visual · A11y · RTL
LayerProvider 4.2 kB (0) · 20 B CSS (0) — ✓ · ✓ · ✗
Lightbox · Storybook 🔴 135.3 kB (+16.0 kB) · 11.0 kB CSS (+511 B) 4,184 (+810) ✓ · ✓ · ✓
Timer 13.4 kB (+121 B) · 6.0 kB CSS (0) — — · — · —
101 more components
Component Size LoC Visual · A11y · RTL
ListItem 68.8 kB (+109 B) · 11.3 kB CSS (0) — — · — · —
ChatToolCalls 31.5 kB (+107 B) · 8.3 kB CSS (0) — — · — · —
TextInput 66.7 kB (+106 B) · 11.1 kB CSS (0) — — · — · —
Timestamp 32.4 kB (+106 B) · 10.2 kB CSS (0) — — · — · —
ChatMessageList 27.6 kB (+105 B) · 7.0 kB CSS (0) — — · — · —
BreadcrumbItem 83.5 kB (+102 B) · 12.1 kB CSS (0) — — · — · —
CommandPaletteInput 31.1 kB (+102 B) · 7.5 kB CSS (0) — — · — · —
Spinner 24.2 kB (+102 B) · 6.2 kB CSS (0) — — · — · —
AppShell 89.7 kB (+99 B) · 13.5 kB CSS (0) — — · — · —
DateTimeInput 204.8 kB (+98 B) · 18.6 kB CSS (0) — — · — · —
Heading 11.9 kB (+97 B) · 5.4 kB CSS (0) — — · — · —
Table 116.5 kB (+97 B) · 17.9 kB CSS (0) — — · — · —
Text · Storybook 11.3 kB (+97 B) · 5.4 kB CSS (0) 758 (+44) ✓ · ✓ · —
CheckboxListItem 69.9 kB (+95 B) · 11.3 kB CSS (0) — — · — · —
TextArea 61.2 kB (+95 B) · 9.3 kB CSS (0) — — · — · —
FileInput 68.1 kB (+93 B) · 10.9 kB CSS (0) — — · — · —
DropdownMenu 95.8 kB (+91 B) · 17.3 kB CSS (0) — — · — · —
DateRangeInput 91.2 kB (+90 B) · 12.4 kB CSS (0) — — · — · —
Markdown 179.6 kB (+90 B) · 20.3 kB CSS (0) — — · — · —
Carousel 68.7 kB (+89 B) · 10.9 kB CSS (0) — — · — · —
MoreMenu 96.1 kB (+89 B) · 17.3 kB CSS (0) — — · — · —
MultiSelector 93.6 kB (+89 B) · 16.8 kB CSS (0) — — · — · —
RadioListItem 66.2 kB (+89 B) · 10.1 kB CSS (0) — — · — · —
CheckboxInput 63.3 kB (+88 B) · 9.1 kB CSS (0) — — · — · —
CheckboxList 68.1 kB (+88 B) · 8.1 kB CSS (0) — — · — · —
ComplexSelector 69.8 kB (+88 B) · 11.8 kB CSS (0) — — · — · —
CommandPalette 72.5 kB (+87 B) · 12.5 kB CSS (0) — — · — · —
ContextMenu 106.4 kB (+87 B) · 17.2 kB CSS (0) — — · — · —
TableSelectionToolbar 69.5 kB (+87 B) · 13.2 kB CSS (0) — — · — · —
DateInput 183.1 kB (+86 B) · 16.9 kB CSS (0) — — · — · —
BaseTypeahead 70.1 kB (+85 B) · 10.9 kB CSS (0) — — · — · —
Calendar 70.3 kB (+85 B) · 10.5 kB CSS (0) — — · — · —
MobileNav 69.6 kB (+85 B) · 10.6 kB CSS (0) — — · — · —
NumberInput 70.7 kB (+85 B) · 11.4 kB CSS (0) — — · — · —
RadioList 55.2 kB (+85 B) · 7.2 kB CSS (0) — — · — · —
TabMenu 70.8 kB (+85 B) · 11.1 kB CSS (0) — — · — · —
TopNavMenu 73.5 kB (+84 B) · 11.2 kB CSS (0) — — · — · —
AlertDialog 104.3 kB (+83 B) · 14.4 kB CSS (0) — — · — · —
ToggleButton 85.7 kB (+83 B) · 10.0 kB CSS (0) — — · — · —
MobileNavToggle 59.6 kB (+82 B) · 9.9 kB CSS (0) — — · — · —
Stepper 60.9 kB (+82 B) · 10.1 kB CSS (0) — — · — · —
TableHeaderCell 107.2 kB (+82 B) · 17.4 kB CSS (0) — — · — · —
ChatLayout 79.5 kB (+80 B) · 10.5 kB CSS (0) — — · — · —
Thumbnail 63.6 kB (+80 B) · 11.5 kB CSS (0) — — · — · —
TopNav 71.3 kB (+80 B) · 10.9 kB CSS (0) — — · — · —
TopNavMegaMenu 68.7 kB (+80 B) · 11.8 kB CSS (0) — — · — · —
DropdownMenuSubMenu 69.1 kB (+79 B) · 9.7 kB CSS (0) — — · — · —
Slider 106.2 kB (+79 B) · 8.8 kB CSS (0) — — · — · —
Typeahead 78.6 kB (+79 B) · 12.4 kB CSS (0) — — · — · —
IconButton 59.3 kB (+78 B) · 9.9 kB CSS (0) — — · — · —
ChatSendButton 59.7 kB (+77 B) · 9.9 kB CSS (0) — — · — · —
InputGroup 55.5 kB (+77 B) · 7.8 kB CSS (0) — — · — · —
ChatComposer 76.9 kB (+76 B) · 12.0 kB CSS (0) — — · — · —
ChatDictationButton 59.8 kB (+76 B) · 10.0 kB CSS (0) — — · — · —
CodeBlock 73.9 kB (+76 B) · 11.2 kB CSS (0) — — · — · —
DrawerHeader 62.3 kB (+76 B) · 12.9 kB CSS (0) — — · — · —
Field 53.8 kB (+76 B) · 7.2 kB CSS (0) — — · — · —
PowerSearch 282.8 kB (+76 B) · 23.8 kB CSS (0) — — · — · —
TableCell 107.6 kB (+76 B) · 17.6 kB CSS (0) — — · — · —
Toast 97.1 kB (+76 B) · 10.2 kB CSS (0) — — · — · —
DialogHeader 62.1 kB (+75 B) · 11.5 kB CSS (0) — — · — · —
Popover 88.0 kB (+75 B) · 14.1 kB CSS (0) — — · — · —
SideNavCollapseButton 60.1 kB (+75 B) · 10.0 kB CSS (0) — — · — · —
TopNavHeading 73.9 kB (+75 B) · 11.0 kB CSS (0) — — · — · —
SideNavHeading 74.5 kB (+74 B) · 11.2 kB CSS (0) — — · — · —
ChatComposerTokenElement 74.6 kB (+73 B) · 11.2 kB CSS (0) — — · — · —
ChatLayoutScrollButton 59.8 kB (+73 B) · 10.1 kB CSS (0) — — · — · —
ChatComposerInput 74.6 kB (+72 B) · 11.2 kB CSS (0) — — · — · —
Switch 100.7 kB (+72 B) · 9.9 kB CSS (0) — — · — · —
Tokenizer 90.3 kB (+71 B) · 18.6 kB CSS (0) — — · — · —
Link 52.1 kB (+70 B) · 7.0 kB CSS (0) — — · — · —
Banner 61.3 kB (+69 B) · 10.5 kB CSS (0) — — · — · —
Button 59.2 kB (+69 B) · 9.9 kB CSS (0) — — · — · —
Pagination 108.5 kB (+69 B) · 17.7 kB CSS (0) — — · — · —
SideNavItem 69.4 kB (+69 B) · 11.1 kB CSS (0) — — · — · —
Selector 98.4 kB (+68 B) · 17.3 kB CSS (0) — — · — · —
TimeInput 158.7 kB (+66 B) · 15.9 kB CSS (0) — — · — · —
SideNav 111.0 kB (+62 B) · 11.3 kB CSS (0) — — · — · —
charts/Chart 198.0 kB (new) · 494 B CSS (new) — — · — · —
charts/ChartLegend 48.6 kB (new) · 224 B CSS (new) — — · — · —
charts/ChartTooltip 175.2 kB (new) · 423 B CSS (new) — — · — · —
layer — — — · ✓ · —
Layer — — ✓ · ✓ · —
lab/ChatEmojiPicker 102.5 kB (new) · 773 B CSS (new) — — · — · —
lab/ChatReactionBar 103.7 kB (new) · 1.1 kB CSS (new) — — · — · —
lab/CommentComposer 147.4 kB (new) · 1.9 kB CSS (new) — — · — · —
lab/Comments 343.1 kB (new) · 2.5 kB CSS (new) — — · — · —
lab/CommentThread 336.6 kB (new) · 2.4 kB CSS (new) — — · — · —
lab/DialogHeroHeader 81.9 kB (new) · 372 B CSS (new) — — · — · —
lab/DiffViewer 85.7 kB (new) · 2.1 kB CSS (new) — — · — · —
lab/EmojiPicker 85.3 kB (new) · 751 B CSS (new) — — · — · —
lab/LineClamp 13.4 kB (new) · 168 B CSS (new) — — · — · —
lab/ListInput 100.6 kB (new) · 1.6 kB CSS (new) — — · — · —
lab/Schedule 104.7 kB (new) · 3.9 kB CSS (new) — — · — · —
lab/SelectableCardGroup 63.2 kB (new) · 162 B CSS (new) — — · — · —
lab/TourStep 94.3 kB (new) · 590 B CSS (new) — — · — · —
lab/TransferList 106.5 kB (new) · 1.7 kB CSS (new) — — · — · —
lab/TransferListSelector 113.2 kB (new) · 1.9 kB CSS (new) — — · — · —
richtext/RichTextEditor 295.7 kB (new) · 2.6 kB CSS (new) — — · — · —
richtext/RichTextEditorToolbar 276.2 kB (new) · 454 B CSS (new) — — · — · —
richtext/RichTextView 275.0 kB (new) · 2.3 kB CSS (new) — — · — · —

Package size: measured; main has no measurement of the merge base to compare yet.

API changes: cli +22 · ~7 · −0 (against the merge base's committed report); theme-butter +1 · ~0 · −0 (against the merge base's committed report); theme-y2k +1 · ~0 · −0 (against the merge base's committed report)

Committed API report behind this build: cli 29 rows, core 35 rows, theme-butter 1 row, theme-y2k 1 row; run pnpm api:report.

31 API changes (advisory)
Package Where Signature Usage
+ cli ./api · Functions · function exportSearchIndex function exportSearchIndex @experimental: (options?: { cwd?: string | undefined; package?: string | undefined }) => Promise<SearchIndex> import {exportSearchIndex} from '@astryxdesign/cli/api'; exportSearchIndex(…)
+ cli ./api · Functions · function rankSearchIndex function rankSearchIndex @experimental: (query: string, indexes: SearchIndex | SearchIndex[], options?: { type?: SearchDomain | undefined; limit?: number | undefined }) => Promise<SearchResponse> import {rankSearchIndex} from '@astryxdesign/cli/api'; rankSearchIndex(…)
+ cli ./api · Types · type DocsListChild type DocsListChild = DocsNodeChild & { topic: string; description: string; children?: DocsListChild[]; childCount?: number } import type {DocsListChild} from '@astryxdesign/cli/api'
+ cli ./api · Types · type DocsListNamespace childCount?: number | undefined import type {DocsListNamespace} from '@astryxdesign/cli/api'; const x: DocsListNamespace = {childCount: …}
+ cli ./api · Types · type DocsListNamespace children?: DocsListChild[] | undefined import type {DocsListNamespace} from '@astryxdesign/cli/api'; const x: DocsListNamespace = {children: …}
+ cli ./api · Types · type SearchIndex type SearchIndex import type {SearchIndex} from '@astryxdesign/cli/api'
+ cli ./api · Types · type SearchResultEntry deprecated?: ComponentDeprecation | undefined import type {SearchResultEntry} from '@astryxdesign/cli/api'; const x: SearchResultEntry = {deprecated: …}
+ cli ./authoring · Types · interface ComponentDeprecation interface ComponentDeprecation import type {ComponentDeprecation} from '@astryxdesign/cli/authoring'
+ cli ./authoring · Types · interface ComponentIconSlotDoc interface ComponentIconSlotDoc import type {ComponentIconSlotDoc} from '@astryxdesign/cli/authoring'
+ cli ./authoring · Types · interface ComponentIconSlotStateDoc interface ComponentIconSlotStateDoc import type {ComponentIconSlotStateDoc} from '@astryxdesign/cli/authoring'
+ cli ./authoring · Types · interface MultiComponentDoc deprecated?: ComponentDeprecation import type {MultiComponentDoc} from '@astryxdesign/cli/authoring'; const x: MultiComponentDoc = {deprecated: …}
+ cli ./authoring · Types · interface SingleComponentDoc deprecated?: ComponentDeprecation import type {SingleComponentDoc} from '@astryxdesign/cli/authoring'; const x: SingleComponentDoc = {deprecated: …}
+ cli ./doc · Types · interface ComponentBaseDoc deprecated?: ComponentDeprecation import type {ComponentBaseDoc} from '@astryxdesign/cli/doc'; const x: ComponentBaseDoc = {deprecated: …}
+ cli ./doc · Types · interface SubComponentDoc deprecated?: ComponentDeprecation import type {SubComponentDoc} from '@astryxdesign/cli/doc'; const x: SubComponentDoc = {deprecated: …}
+ cli ./doc · Also exported from an earlier entry point · ComponentDeprecation ComponentDeprecation (./authoring) import {ComponentDeprecation} from '@astryxdesign/cli/doc'
+ cli ./doc · Also exported from an earlier entry point · ComponentIconSlotDoc ComponentIconSlotDoc (./authoring) import {ComponentIconSlotDoc} from '@astryxdesign/cli/doc'
+ cli ./doc · Also exported from an earlier entry point · ComponentIconSlotStateDoc ComponentIconSlotStateDoc (./authoring) import {ComponentIconSlotStateDoc} from '@astryxdesign/cli/doc'
+ cli ./json · Also exported from an earlier entry point · DocsListChild DocsListChild (./api) import {DocsListChild} from '@astryxdesign/cli/json'
+ cli ./json · Also exported from an earlier entry point · SearchIndex SearchIndex (./api) import {SearchIndex} from '@astryxdesign/cli/json'
+ cli ./template · Also exported from an earlier entry point · ComponentDeprecation ComponentDeprecation (./authoring) import {ComponentDeprecation} from '@astryxdesign/cli/template'
+ cli ./template · Also exported from an earlier entry point · ComponentIconSlotDoc ComponentIconSlotDoc (./authoring) import {ComponentIconSlotDoc} from '@astryxdesign/cli/template'
+ cli ./template · Also exported from an earlier entry point · ComponentIconSlotStateDoc ComponentIconSlotStateDoc (./authoring) import {ComponentIconSlotStateDoc} from '@astryxdesign/cli/template'
~ cli ./api · Functions · function search function search: (query: string, options?: { cwd?: string | undefined; type?: "template" | "component" | "hook" | "theme" | "doc" | undefined; limit?: number | undefined }) => Promise<SearchResponse> → function search: (query: string, options?: { cwd?: string | undefined; type?: "template" | "component" | "doc" | "theme" | "hook" | undefined; limit?: number | undefined }) => Promise<SearchResponse> import {search} from '@astryxdesign/cli/api'; search(…)
~ cli ./api · Types · type SwizzleCopyResponse data: { component: string; package: string; outputDir: string; filesCopied: number; files: string[]; usesStyleX: boolean; feedback?: SwizzleFeedback | undefined } → data: { component: string; package: string; outputDir: string; filesCopied: number; files: string[]; usesStyleX: boolean; dependencies: Record<string, string>; marker … #84d9505b import type {SwizzleCopyResponse} from '@astryxdesign/cli/api'; const x: SwizzleCopyResponse = {data: …}
~ cli ./authoring · Types · interface MultiComponentDoc theming?: { container?: boolean; targets: ComponentThemingTarget[]; vars?: ComponentThemingVar[]; derived?: ComponentThemingDerivedVar[] } → theming?: { container?: boolean; targets: ComponentThemingTarget[]; vars?: ComponentThemingVar[]; derived?: ComponentThemingDerivedVar[]; componentIcons?: ComponentIconSlotDoc[] } import type {MultiComponentDoc} from '@astryxdesign/cli/authoring'; const x: MultiComponentDoc = {theming: …}
~ cli ./authoring · Types · interface SingleComponentDoc theming?: { container?: boolean; targets: ComponentThemingTarget[]; vars?: ComponentThemingVar[]; derived?: ComponentThemingDerivedVar[] } → theming?: { container?: boolean; targets: ComponentThemingTarget[]; vars?: ComponentThemingVar[]; derived?: ComponentThemingDerivedVar[]; componentIcons?: ComponentIconSlotDoc[] } import type {SingleComponentDoc} from '@astryxdesign/cli/authoring'; const x: SingleComponentDoc = {theming: …}
~ cli ./authoring · Types · type TemplateCategory type TemplateCategory = | 'Dashboard - Analytics' | 'Dashboard - Comparison' | 'Dashboard - KPI Summary' | 'Dashboard - Monitoring' | 'Dashboard - Executive Summary' | 'Dashboard - Sco … #e7c18378 → type TemplateCategory = | 'Dashboard - Analytics' | 'Dashboard - Comparison' | 'Dashboard - KPI Summary' | 'Dashboard - Monitoring' | 'Dashboard - Executive Summary' | 'Dashboard - Sco … #a8be998f import type {TemplateCategory} from '@astryxdesign/cli/authoring'
~ cli ./doc · Types · interface ComponentBaseDoc theming?: { container?: boolean; targets: ComponentThemingTarget[]; vars?: ComponentThemingVar[]; derived?: ComponentThemingDerivedVar[] } → theming?: { container?: boolean; targets: ComponentThemingTarget[]; vars?: ComponentThemingVar[]; derived?: ComponentThemingDerivedVar[]; componentIcons?: ComponentIconSlotDoc[] } import type {ComponentBaseDoc} from '@astryxdesign/cli/doc'; const x: ComponentBaseDoc = {theming: …}
~ cli ./doc · Types · interface SubComponentDoc theming?: { container?: boolean; targets: ComponentThemingTarget[]; vars?: ComponentThemingVar[]; derived?: ComponentThemingDerivedVar[] } → theming?: { container?: boolean; targets: ComponentThemingTarget[]; vars?: ComponentThemingVar[]; derived?: ComponentThemingDerivedVar[]; componentIcons?: ComponentIconSlotDoc[] } import type {SubComponentDoc} from '@astryxdesign/cli/doc'; const x: SubComponentDoc = {theming: …}
+ theme-butter Public attributes · attr data-astryx-pressable attr data-astryx-pressable (public data attribute) [data-astryx-pressable] { … }
+ theme-y2k Public attributes · attr data-astryx-pressable attr data-astryx-pressable (public data attribute) [data-astryx-pressable] { … }

Touched components checked; add ci:run-visual or ci:run-rtl to run the full suites.

Accessibility: 1 violation(s)

Accessibility Audit

Status: 1 accessibility violation(s) found — 1 serious.

Text - 1 issue(s)
  • 🟠 serious: Ensure the contrast between foreground and background colors meets WCAG 2 AA minimum contrast ratio thresholds
    • Rule: color-contrast · Affects 1/24 stories · Learn more
    • WCAG: 1.4.3 (Level AA)

Generated by PR Enrichment workflow | View full report

@astracat-bot astracat-bot Bot left a comment

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.

This pull request needs an owner decision on its Lightbox spec changes, and it has two blocking findings that need changes either way.

  • A single zoomed photo no longer pans on a drag that starts at its side edge, because useZoomStage.ts (lines 214–227) refuses that pan for every Lightbox rather than only for a gallery whose pager can take it, so please hand the drag off at an edge only in a gallery and add a single-photo test that drags out from an edge.
  • Against main this pull request is 5,488 changed lines, and since its Stack: line does not match the one in #8197 and #9810 (neither lists this pull request) the stack size exemption does not apply, so please give all three descriptions one identical Stack: line, bottom first with this pull request last, or split the change.

The head adds requirements the current records do not state: the gallery caption-band sentences in component:Lightbox FR1, the new FR17 media-surface rule, and a rewrite of the spec:AST-038 Lightbox row that currently keeps centred large captions. Approval needs an engineering owner to approve or reject those record changes by commenting /approve-spec <full head SHA> on this pull request, and the author can do that as an engineering owner. The review shows before and after captures for both findings.

[Automated review]

@astracat-bot astracat-bot Bot left a comment

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.

This pull request needs an engineering owner's decision on its Lightbox spec changes, and it has two blocking findings that need changes either way.

Approval waits on an engineering owner approving or rejecting three spec changes, as written at this head: component:Lightbox FR1's gallery caption-band sentences (the two-line band, the "more"/"less" button for every pointer, the full caption as the accessible description); the new FR17 media-surface row, which also restyles a single photo's caption as body text on a dark plate; and spec:AST-038's rewritten Lightbox row, which drops the "Centered large captions … remain intentional" guidance. An engineering owner records the decision by commenting /approve-spec <full head SHA> on this pull request; the author may do so if they are an engineering owner.

Blocking findings:

  • .changeset/pager-settle-tempo.md says a Carousel with hasSnap now settles at the theme's tempo, but only hasSnap={useSnapPaging()} runs the pager (plain hasSnap keeps CSS scroll snap), so it should read "in a Carousel given hasSnap={useSnapPaging()}".
  • The diff is 5,947 authored lines with no size exemption, because the Stack: line is not the one #8147 and #8148 carry and it lists #8215, which this head does not contain; give every listed pull request one identical linear line of pull requests that each contain the one below (for example #8197 → #9810 → #10284), or split the change.

Non-blocking: spec:AST-094's FR45 verification row still lists the pager's tempo gap, and the proposed FR1 does not yet state the toggle's expanded state or where focus goes when paging removes it. The single zoomed photo's drag from its edge pans again, as on main.

[Automated review]

Comment thread .changeset/pager-settle-tempo.md Resolved

@astracat-bot astracat-bot Bot left a comment

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.

This stack is waiting on one engineering-owner decision: #8197 and #9810 are approved, and #10284 needs its new Lightbox spec line approved.

#8197

Approved at its current head, with no blocking findings.

#9810

Approved at its current head, with no blocking findings.

#10284

Approval waits on an engineering owner approving or rejecting component:Lightbox FR1b and its verification row, as written at this head: a single photo presents its caption the same way a gallery page does (the two-line band at the bottom of the viewer on the caption's backing, the inline "more"/"less" for every pointer, the photo centred above it, no band without a caption), with no paging controls and the zoomed photo's rubber band as its exceptions. No current record states this. An engineering owner records the decision by commenting /approve-spec <full head SHA> on this pull request; the author may do so if they are an engineering owner. There are no blocking findings beyond that decision.

Non-blocking: the record's "Captioned media" state still says the caption follows the photo in a centred group, FR1b's exception should say a gallery's touch pager takes the edge drag, and the description should say this pull request also carries #8197's busy-proof test rewrite and a merge of main.

Whole stack

No blocking issue across the three pull requests, and the head merges cleanly with main. Each pull request lands only when it and every pull request below it are approved; CI has not run on these drafts yet.

[Automated review]

@astracat-bot astracat-bot Bot left a comment

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.

This stack waits on engineering-owner approvals for #9810 and #10284, and #8197 needs one fix. Each pull request lands only when it and every pull request below it are approved.

#8197

Changes needed:

  • Regression: this head conflicts with main, because the v0.7.10 release deleted .changeset/lightbox-every-pointer.md and this pull request still edits one line of it; merge main here and drop that edit (the merge already in #9810's history does exactly this), then have the record approval re-stamped at the new head.

#9810

No blocking findings. Its own changes are identical to the approved head, but the new head merges #8197 and main, so the record approval no longer applies: an engineering owner re-approves its unchanged record text by commenting /approve-spec <full head SHA> on #9810.

#10284

Approval waits on an engineering owner approving or rejecting component:Lightbox FR1b and its verification row as written: a single photo presents its caption the same way a gallery page does (the two-line band at the bottom of the viewer on the caption's backing, the inline "more"/"less" for every pointer, the photo centred above it, no band without a caption), with no paging controls and the zoomed photo's rubber band as its exceptions. No current record states this. An engineering owner records the decision by commenting /approve-spec <full head SHA> on this pull request; the author may do so if they are an engineering owner. There are no other blocking findings.

Non-blocking: the translator notes for "more" and "less" in en.json still say they follow a gallery caption (Miss), the record's "Captioned media" state still describes the old centred group, and FR1b's exception should say a gallery's touch pager takes the edge drag.

Whole stack

No blocking issue in the combined change: it merges cleanly with main, its records agree with each other, and the touched unit suites pass. CI has not run on these drafts yet.

[Automated review]

Comment thread packages/core/locales/en.json Resolved
@cixzhang

cixzhang commented Nov 7, 2026

Copy link
Copy Markdown
Contributor

/approve-spec e902d9a

@github-actions github-actions Bot removed the needs:spec-owner-review Current knowledge records await owner approval label Nov 7, 2026

@astracat-bot astracat-bot Bot left a comment

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.

Changes needed before this can land; one rebase fixes all three blocking findings. This pull request is reviewed on its own against main, because #8197 and #9810 no longer list it in their Stack: line and this head does not contain their current heads; its record changes, component:Lightbox FR1b included, carry an engineering owner's /approve-spec for this head, so no spec decision is pending.

  • Regression: the stack exemption no longer covers this branch's 6,681 authored lines, so rebase it onto #9810's current head and give #8197, #9810 and #10284 one identical Stack: #8197 → #9810 → #10284 line.
  • Regression: merging this head into main stops on a conflict in packages/core/src/Lightbox/__tests__/LightboxZoom.interaction.browser.spec.ts, which #9810's current head already resolves.
  • Miss: onSettle in Lightbox.tsx resets only photos outside the page marked current, so when a swipe's render lands after the settle ends the photo left behind keeps its zoom; #8197's current head fixes this by skipping only the page the pager reports as settled.

Non-blocking: the "more"/"less" translator notes in en.json still say "gallery caption", and the record's "Captioned media" state still describes the old centred caption. The rebased head will need a fresh /approve-spec.

[Automated review]

Comment thread packages/core/src/Lightbox/Lightbox.tsx Resolved
@vjeux
vjeux force-pushed the uikit/c13-single-caption-backing branch from e902d9a to fcf9c27 Compare November 7, 2026 18:02
@github-actions github-actions Bot added the needs:spec-owner-review Current knowledge records await owner approval label Nov 7, 2026
@cixzhang

cixzhang commented Nov 8, 2026

Copy link
Copy Markdown
Contributor

/approve-spec b565bdc

@github-actions github-actions Bot removed the needs:spec-owner-review Current knowledge records await owner approval label Nov 8, 2026
vjeux added 3 commits November 7, 2026 22:43
Main's Lightbox record now has FR17, an index past either end, and
FR18, a paged-away video. This branch's media-surface requirement,
also numbered FR17, becomes FR19, with its verification row and its
Current-state entry.
The caption band now carries main's FR17 and FR18, and its media-surface
requirement is FR19. This branch's verification row for it follows as
FR19, and the single photo's caption-contrast gap stays removed: this
branch fixes it.
The owner's message reads differently from the sentence FR1b quoted.
FR1b now keeps only her exact fragment, "they really should be
consistent", and says the rest in plain prose.

@astracat-bot astracat-bot Bot left a comment •

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.

Changes requested: one blocking finding, in #9810's record and carried into #10284; the record text itself is owner-approved and the Stack: line now holds.

#9810: request changes

  • Regression: main now defines its own component:Lightbox FR17 (the nearest valid item for an out-of-range index) and FR18 (a paged-away video), so this pull request's media-surface FR17 row and its verification row collide with them and GitHub reports a merge conflict in docs/specs/components/Lightbox/Lightbox.spec.md; please rebase onto main and renumber the media-surface requirement to FR19 wherever the record cites it.

#10284: request changes

  • Regression: this pull request edits the same media-surface FR17 verification row and removes #9810's FR17 gap, so it conflicts with main the same way; please rebase it onto #9810 once the row is renumbered.

Whole stack

The stack fails until that rebase, though the code itself merges with main, typechecks and passes the Lightbox, Text and Layer unit tests. A pull request lands only when it and every pull request below it are approved, and after the rebase an engineering owner records the spec approval again by commenting /approve-spec <full head SHA> on each pull request, which the author may do as an engineering owner.

  • Non-blocking: FR1b names a single captioned video, but its exceptions, its verification row and the changeset speak only of a single photo, and no test pins the video's caption in the band.

[Automated review]

vjeux added 2 commits November 8, 2026 02:38
Main now judges the double-tap zoom's busy proof on the photo's top
edge instead of its height, which this branch's last run failed on.
The caption band now carries main's busy-proof fix for the double-tap
zoom; this branch changes nothing there.
@github-actions github-actions Bot added the needs:spec-owner-review Current knowledge records await owner approval label Nov 8, 2026
@cixzhang

cixzhang commented Nov 8, 2026

Copy link
Copy Markdown
Contributor

/approve-spec 801fa11

@github-actions github-actions Bot removed the needs:spec-owner-review Current knowledge records await owner approval label Nov 8, 2026

@astracat-bot astracat-bot Bot left a comment

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.

Changes requested. The record text now has an engineering owner's approval at this head, and two blocking findings remain.

  • Regression: since this branch was written, main made a labelled Button's size a minimum height, so once merged the caption's "more"/"less" button, whose captionToggle style sets blockSize: '1lh' (Lightbox.tsx:400-405), grows to 28 px and sits 4 px above the caption's last line on a desktop (2 px on a phone); adding minBlockSize: 0 to captionToggle keeps it one line tall.
  • Regression: #9810 has moved to a new head that this branch does not contain, so the Stack: #9810 → #10284 line no longer holds and this 3,870-line pull request is reviewed alone, without the stack's size exemption; merging #9810's current head, with the toggle fix, into this branch restores the stack.

Non-blocking: FR1b names a single captioned video, but its exceptions, its verification row and the changeset speak only of a single photo, and no test pins the video's band. After the push, an engineering owner records /approve-spec <full head SHA> for the new head; the author may do so as an engineering owner.

[Automated review]

Comment thread packages/core/src/Lightbox/Lightbox.tsx Resolved
@cixzhang

cixzhang commented Nov 8, 2026

Copy link
Copy Markdown
Contributor

/approve-spec 785873b

@astracat-bot astracat-bot Bot left a comment •

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.

Changes requested on both pull requests in this stack; the record text is approved for each head.

#9810: request changes

  • Regression: main's Button now takes its size as a minimum height, so captionToggle (Lightbox.tsx:400-405) renders "more"/"less" 28 px tall on a 20 px caption line and 4 px above the caption's last line (2 px on a phone), which fails five of the stack's own browser specs (LightboxViewport ×4 and LightboxPaging "…ends the last"); adding minBlockSize: 0 to captionToggle brings it back to one line.
  • Regression: main now includes #8215 (drag a photo down to close), and this branch no longer merges with it: Lightbox.tsx and LightboxEveryPointer.interaction.browser.spec.ts conflict, including #8215's new layer around the controls, which this branch wraps in MediaTheme, and its caption fade, which needs to reach the new band.

#10284: request changes

  • Regression: this head also conflicts with #8215 in Lightbox.tsx, including the stage style it rewrites for a single photo; merge #9810 here once #9810 has taken main.

#10284 also shows #9810's lifted "more" on a single long caption until it merges that fix. Whole stack: fails; a pull request lands only when it and every pull request below it are approved. Non-blocking: FR1b now covers a single captioned video, but no test pins that case.

[Automated review]

vjeux added 8 commits November 8, 2026 06:54
Main's drag to close and this branch both change Lightbox.tsx, and the
merge keeps both. The controls sit in the drag's click-through layers
inside the media surface, and each takes its own clicks. A page's
photo box keeps its row in the band's grid and takes the dismissal's
overflow and stacking. The every-pointer spec keeps a new case from
each side. Main's new fine-pointer case counts the media surface too.
Main's drag to close fades the controls and the caption with its
travel. In a gallery the caption's backing is its band, which stayed
opaque over the fading backdrop. The band now fades in the caption's
place, once.
The caption's toggle was a ghost Button with a size of its own. It is
now Link's button form: a native button in the caption's own font and
line height, underlined, at the end of the caption's last line. It
keeps aria-expanded and aria-controls, and the shared hit area still
grows its tap toward 44 px under a finger. Lightbox's record, docs and
changeset say so.
The caption band now carries main's drag to close, and shows "more"
and "less" as an inline link. On this branch every item is a page of
the track, a single photo too. So the drag to close moves each page's
photo box, and the track takes its touches. After a cancelled drag,
the stage's own tap beside the photo still closes the viewer. The zoom
core drops its fit callback, which only placed the old single caption.
Main's cases that read that caption read its band instead.
The caption's "more" and "less" grew their touch target through their
own copy of the shared hit area: a watch and a band of their own. They
now use Core's touch hit area and its layer, as other controls do,
with a growth that never reaches up into the caption's line above.
Lightbox's record marks FR19's single-photo gap, and the contrast case
adds the black photo its verification row names.
The caption band's "more" and "less" now take their touch target from
Core's touch hit area, growing toward 44 px down and to each side but
never up. A single photo's caption uses the same toggle, so it gets
the fix too. FR19 stays settled here, since this branch closes the
single photo's contrast gap the caption band's record lists.
Main now plays the drag to close at the theme's tempo, and Lightbox's
record says so in FR5 and its Motion section. The merge keeps main's
FR5 row, Motion paragraph and verification row, and this branch's FR1
and FR19 rows. The dismissal spec keeps both sides' new cases.
The caption band now carries main's tempo for the drag to close, and
its record's FR5 row and Motion section. Every item here is a page of
the track, so a single photo's drag to close plays at that tempo too.
@github-actions github-actions Bot added the needs:spec-owner-review Current knowledge records await owner approval label Nov 8, 2026
@cixzhang

cixzhang commented Nov 8, 2026

Copy link
Copy Markdown
Contributor

/approve-spec 2b0b009

@github-actions github-actions Bot removed the needs:spec-owner-review Current knowledge records await owner approval label Nov 8, 2026

@astracat-bot astracat-bot Bot left a comment •

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.

Approved: both pull requests in this stack. The Lightbox record changes carry an engineering owner's approval at each head, and the stack merges cleanly with main.

#9810: approve. No blocking findings. The caption's "more"/"less" is now one caption line tall, and the merge with the drag to close keeps the band fading with it.

#10284: approve. No blocking findings. A single captioned photo now shows its caption exactly as a gallery page does.

Whole stack: passes. A pull request lands only when it and every pull request below it are approved.

Non-blocking: FR1b's single-video half has no test, and FR19's verification row here drops the black photo that #9810's contrast loop now runs (inline note).

[Automated review]

| FR16 | Touch tests closing by Close, Escape, platform close, and a tap beside the photo with the controls shown; Reduce Motion | With and without `experimental`; controls shown and hidden | A touch close without the exit, a literal timing, input reaching the viewer during the exit, or a tap beside the photo that closes while the controls are hidden fails. | `audit:Lightbox/touch` |
| FR17 | `Lightbox.test.tsx` index cases | An index below 0 and past the end, controlled and default | An index past either end that opens an empty viewer, or any item but the nearest, fails. | `audit:Lightbox/anatomy` |
| FR18 | `Lightbox.test.tsx` video paging cases (pause, keep, autoplay) | A playing video paged away from and back to | A neighbouring video that unmounts, keeps playing, or starts again from its beginning fails. | `audit:Lightbox/anatomy` |
| FR19 | Unit: `Lightbox.test.tsx` media surface cases; browser: `LightboxPaging` and `LightboxZoom` interaction specs, Chromium and WebKit | Gallery with captions, with and without zoom; a single photo's caption; over a white and a mid-grey photo (body 14.7:1 over white) | A viewer outside `MediaTheme`, a Lightbox-set text color, a caption or counter that is not `Text`, a toggle that is not Link's button form, two start edges, or a caption under 4.5:1 fails. | `audit:Lightbox/theming` |

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.

Non-blocking: #9810 now runs the contrast case over a black photo too (LightboxZoom.interaction.browser.spec.ts:469), so this row names less than the stack tests. Keeping "over a white, a mid-grey and a black photo" here would match the tests.

This branch was successfully deployed

1 active deployment
Preview — 2b0b009a Deployed Nov 8, 2026 by vercel[bot]
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

ci:run A maintainer lets this outside contributor's pull request run CI (AST-030 FR17) ci:run-a11y Run the accessibility suite on this PR; write access, next push (AST-030 FR12) CLA Signed This label is managed by the Meta Open Source bot. needs:design-review Affects visuals — Design should review

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants