Repository navigation
Conversation
|
The latest updates on your projects. Learn more about Vercel for GitHub.
|
|
AI review status for this pull request.
|
PR Analysis Report
Generated by PR Enrichment workflow | View current CI run |
There was a problem hiding this comment.
This pull request needs an owner decision before it can be approved, and it has independent fixes to make either way.
Owner decision: no Lightbox requirement yet covers gallery pages sharing one caption row, and this change pursues that direction while the design decision is open. The head also adds new requirements to the Lightbox record: AR9, the controls' backing and contrast with zoom on; and the zoom-settle formula with its motion roles. Approval needs a spec-gate owner to settle these: either approve the shared caption row and how it reserves its height (which today conflicts with the style-authoring rule that content renders once), or keep each caption under its own photo. An engineering owner records the decision by commenting /approve-spec <full head SHA>, and the author may do so as an engineering owner.
Blocking findings:
- The caption row renders hidden copies of the unmounted pages' captions to reserve its height, which the component style-authoring architecture's INV7 ("Content renders once") rules out unless an owner amends it.
- Against
mainthe diff is 8,108 authored lines, because the three stacked pull requests ride along with this 250-line change, so land them first or retarget so this pull request carries only its own commit. - In a gallery with
hasZoom, a click or tap on the reserved caption band under a photo without a caption no longer closes the viewer, whilemainand a gallery without zoom close it (useZoomStage.ts, the stage's tap only counts points inside the stage). .changeset/lightbox-gallery-paging.mdstill says each caption sits "right under its photo", but it now sits at the bottom of the stage, 252 px below a landscape photo on a phone.- The Lightbox record's FR5 requires the page settle to play named motion roles, and the head records it as playing the pager's own values instead, so register those values as roles or record an owner exception.
[Automated review]
8004b0f to
f53416e
Compare
There was a problem hiding this comment.
This pull request needs an owner decision before it can be approved, and it has independent fixes to make either way.
Owner decision: no Lightbox requirement covers gallery pages sharing one caption row, and the head also adds new requirements to the Lightbox record: AR9 (the controls' backing and contrast with zoom on) and the zoom-settle formula with its motion roles. A spec-gate owner needs to settle these: approve the shared caption row and how it reserves its height, which today conflicts with the style-authoring rule that content renders once, or keep each caption under its own photo. An engineering owner records the decision by commenting /approve-spec <full head SHA>, and the author may do so as an engineering owner.
Blocking findings:
- The caption row renders hidden copies of the unmounted pages' captions to reserve its height (
Lightbox.tsx, the caption sizer), which the component style-authoring architecture's INV7 ("Content renders once") rules out unless an owner amends it. - Desktop behavior change needs an owner decision: a mouse drag or a trackpad's sideways scroll now pages every gallery, with default props (
Lightbox.tsx, the pager'sallowedPointerTypes), so gate it to touch input or cite the decision that covers it. - Against
mainthe diff is 8,175 authored lines, because the three pull requests below ride along with this 294-line change, and their bodies carry a different stack line, so land them first or make the stack declaration identical in all four. - The Lightbox record's FR5 requires the page settle to play named motion roles, and the head records it as playing the pager's own values instead, so register those values as roles or record an owner exception.
[Automated review]
f53416e to
e44bf26
Compare
There was a problem hiding this comment.
This pull request needs a spec owner's decision before it can be approved, and it has independent fixes to make either way.
Spec decision: no Lightbox requirement covers gallery pages sharing one caption row, and the head adds new requirements to the Lightbox record: AR9 (the controls' backing and contrast with zoom on), the zoom-settle formula, and its motion roles. A spec-gate owner needs to approve the shared caption row and how it reserves its height, which today conflicts with the style-authoring rule that content renders once, or keep each caption under its own photo, and approve or reject the new record text. An engineering owner records the decision by commenting /approve-spec <full head SHA> on this pull request; the author may do so as an engineering owner.
Blocking findings:
- The caption row renders hidden, inert copies of the unrendered pages' captions to reserve its height (
Lightbox.tsx, the caption sizer), which the component style-authoring architecture's INV7 ("Content renders once") rules out unless an owner amends it. - Desktop behavior change needs an owner decision: with default props a mouse drag or a trackpad's sideways scroll now pages every gallery (
Lightbox.tsx, the pager'sallowedPointerTypes), and with zoom a ctrl-wheel zooms the photo and a released mouse drag coasts (useZoomStage.ts), so gate these to touch input or cite the decision that covers them. - Against
mainthe diff is 8,172 authored lines, because the three pull requests below ride along with this 294-line change and the stack line is not identical in every listed pull request, so land them first or make the stack declaration hold. - The Lightbox record's FR5 requires the page settle to play named motion roles, and the head records it as playing the pager's own values instead, so register those values as roles or record an owner exception.
[Automated review]
e44bf26 to
c98544b
Compare
There was a problem hiding this comment.
This pull request needs a spec owner's decision before it can be approved, and it has independent fixes to make either way.
Spec decision: no Lightbox requirement covers gallery pages sharing one caption row, and the head adds new requirements to the Lightbox record: AR9 (the controls' backing and contrast with zoom on), the zoom-settle formula and its motion roles. A spec-gate owner needs to approve the shared caption row and how it reserves its height, which today conflicts with the style-authoring rule that content renders once, or keep each caption under its own photo, and approve or reject the new record text. An engineering owner records the decision by commenting /approve-spec <full head SHA> on this pull request; the author may do so as an engineering owner.
Blocking findings:
- The caption row renders hidden, inert copies of the unrendered pages' captions only to reserve its height (
Lightbox.tsx, the caption sizer), which the component style-authoring architecture's INV7 ("Content renders once") rules out unless an owner amends it. - The Lightbox record's FR5 requires the page settle to play named motion roles, and the head records it as playing the pager's own values instead, so register those values as roles or record an owner exception.
- Against
mainthe diff is 8,442 authored lines, because the three pull requests below ride along with this 294-line change and #8215 does not contain #8197's head, so land the lower pull requests first or make every listed head contain the one below it. - Regression: the Chinese
hasZoomdescription still says every zoomed drag pans with momentum, while a mouse drag now stops at the release, so narrow it as the English description was narrowed.
Drag paging is now limited to touch input, so a mouse and a trackpad page a gallery as they do on main.
[Automated review]
c98544b to
20b897a
Compare
There was a problem hiding this comment.
This pull request needs a spec owner's decision before it can be approved, and it has independent fixes to make either way.
Spec decision: no Lightbox requirement covers gallery pages sharing one caption row, and the head adds new requirements to the Lightbox record: AR9 (the controls' backing and contrast with zoom on), the zoom-settle formula and its motion roles, beside unrecorded video and index behaviours. A spec-gate owner needs to approve the shared caption row and how it reserves its height, which today conflicts with the style-authoring rule that content renders once, or keep each caption under its own photo, and approve or reject the new record text. An engineering owner records the decision by commenting /approve-spec <full head SHA> on this pull request; the author may do so as an engineering owner.
Blocking findings:
- In a captioned gallery without zoom, a tap or a mouse click on the dark band between a photo and its caption, which now sits in the bottom row, leaves the viewer open, while
mainand a zoomable gallery close on it, because the hit test inLightbox.tsxtreats one box spanning photo and caption as the media. - The caption row renders hidden, inert copies of the unrendered pages' captions only to reserve its height, which the component style-authoring architecture's INV7 ("Content renders once") rules out unless an owner amends it.
- The Lightbox record's FR5 requires the page settle to play named motion roles, and the head records it as playing the pager's own values instead, so register those values as roles or record an owner exception.
- Against
mainthe diff is 8,622 authored lines, because the three pull requests below ride along and #8215 does not contain #8197's head, so land the lower pull requests first or declare a stack line that every listed head satisfies. - Miss: the caption sizer picks captions with a truthiness test (
item.caption && …) instead ofisRenderable, so a0caption reserves no height and atruecaption reserves an empty box.
The Chinese hasZoom description now matches the English one.
[Automated review]
20b897a to
86d0dd1
Compare
The restack of meta#9810 on meta#8197's head e0eab2a, which merges main again to keep meta#10406's lift record. No conflict; this pull request's own diff is unchanged.
|
/approve-spec ec7c502 |
There was a problem hiding this comment.
Changes requested: one blocking issue remains, and the record text is approved for this head.
- Regression: the
Stack: #8197 → #9810 → #10284line no longer holds, because #10284's head does not contain this head, so this pull request is judged on its own and carries #8197's increment as 6,072 authored lines with no exemption; merge this head into #10284 so every listed head contains the one below.
Non-blocking, unchanged from the last round: FR17's verification row names a black photo that no contrast case runs, FR17's review state should read settled; implementation gap, and the GalleryKeepsIndex story has lost its description. CI has not run on this head, since every job skips while the pull request is a draft.
[Automated review]
A merge in this pull request dropped the JSDoc above the story, which Storybook shows as its description. It comes back as on meta#8197.
|
/approve-spec 92d50bf |
There was a problem hiding this comment.
Changes requested: one blocking issue in #9810, and a pull request lands only when it and every pull request below it are approved.
#8197 — approve
Approve, with no blocking findings.
#9810 — request changes
- Miss: opening a gallery on a caption longer than two lines makes the browser lay the viewer out again on the main thread (three forced layouts against main's one, one of them this pull request's toggle read), and paging onto or off such a caption forces layout at the two new reads, because the toggle's attach reads
toggle.offsetWidth(Lightbox.tsx:937) and the band's attach runs the clamp check (Lightbox.tsx:910) right after the commit's writes and the task then writes and reads again, which the React runtime architecture's INV18 rules out; read both sizes in the observer deliveries instead, and keep the toggle's width across pages until its observer reports a change.
Non-blocking, unchanged: the black photo in FR17's verification row that no contrast case runs, FR17's review state, the long JSDoc in useZoomStage.ts, and the block inside a clamped Text.
Whole stack — fails
It fails on the finding above. CI has not run on this head because the pull request is a draft.
[Automated review]
Main's meta#10415 plays LightboxZoom's busy double-tap proof at tempo 5 through `slowZoom`, which this pull request replaced with the shared `slowViewer`. The merge keeps meta#10415's three constants and calls `slowViewer(page, ZOOM_TEMPO)` in the proof and its controls; every other path is the automatic merge.
The restack of meta#9810 on meta#8197's head cc382a8, which merges main again to port meta#10415's busy zoom tempo. No conflict; this pull request's own diff is unchanged.
The caption band's attach read the clamp and the caption's lines in React's commit, and the toggle's attach read its width there too, so opening a gallery or paging forced layouts before the browser's own. Both now read in their ResizeObserver's deliveries, which follow layout, and commit before the frame paints, so "more" still shows from the first frame. Such a commit only shows or hides the toggle, which stays mounted, so it adds no element mid-delivery. The held truncation reads nothing by itself: Lightbox measures it.
|
/approve-spec 218f7b4 |
There was a problem hiding this comment.
Changes requested: one blocking issue in #9810; a pull request lands only when it and every pull request below it are approved.
#8197 — approve
Approve, with no blocking findings; its branch now conflicts with main in LightboxZoom.interaction.browser.spec.ts, which only #9810's merge resolves.
#9810 — request changes
- Paging back onto a clamped caption (measured with the arrow key and with Previous) makes the browser lay the viewer out an extra time, because the new page's toggle reads
toggle.offsetWidth(Lightbox.tsx:996) right after the band'sflushSyncun-hides it in the same ResizeObserver callback, which the React runtime architecture's INV18 rules out; take the width from the delivery's entry (borderBoxSize, skipping a zero size) and correct the comment atLightbox.tsx:990-992.
Non-blocking, unchanged: the black photo in FR17's verification row that no contrast case runs, FR17's review state, the long JSDoc in useZoomStage.ts, and the block inside a clamped Text.
Whole stack — fails
It fails on the finding above, and CI has not run on this head because the pull request is a draft.
[Automated review]
Paging back onto a clamped caption delivered the band's entry and the toggle's first entry in one ResizeObserver callback, band first. The band's update showed the toggle, and the toggle's callback then read its offsetWidth after that write, which forced a layout. The width now comes from the delivery's own border-box size. A hidden toggle's zero size keeps the last width.
|
/approve-spec ac1101e |
There was a problem hiding this comment.
Changes requested: one blocking issue in #9810; a pull request lands only when it and every pull request below it are approved.
#8197 — approve
Approve, with no blocking findings; its new head only merges main into one test, and it merges cleanly with today's main.
#9810 — request changes
- Miss: each press of "more" or "less" still makes the browser lay the viewer out an extra time, because opening or closing the caption registers the band again behind the toggle (
Lightbox.tsx:938-976), so the toggle'sflushSyncwidth commit (Lightbox.tsx:1001) runs first and the band's caption read (Lightbox.tsx:912on "more",useTruncation.ts:154-163on "less") follows that write in the same ResizeObserver callback, which the React runtime architecture's INV18 rules out; read the caption before any write in that delivery, for example with one listener for both entries or by not registering the band again when the caption opens or closes.
Non-blocking, unchanged: the black photo in FR17's verification row that no contrast case runs, FR17's review state, the long JSDoc in useZoomStage.ts, and the block inside a clamped Text.
Whole stack — fails
It fails on the finding above; CI has not run on this head because the pull request is a draft.
[Automated review]
Opening or closing the caption registered the band again behind the toggle. The new label resized the toggle in the same frame, so one ResizeObserver callback ran the toggle's width commit first and the band's caption read after that write, which forced a layout. Now both callbacks only note what changed. One microtask after the callback reads the caption and commits once, before the frame paints, and the band no longer registers again when the caption opens or closes.
|
/approve-spec e48e3e0 |
The restack of meta#8197 on main 993e1fa, which brings meta#10436's PowerSearch play fix for the story play guard. No conflict; this pull request's own diff is unchanged.
The pager's onSettle reset every photo outside the page marked current. On a slow runner the settle ends before the render that moves that mark, so the photo left behind was still marked current and kept its zoom. Each page now carries its index, and the reset skips only the page the pager names.
The restack of meta#9810 on meta#8197's head 3963547, which merges main and resets the photo left behind by the page the pager names. One conflict, in Lightbox.tsx: this pull request indents the gallery's track one level deeper, and meta#8197 gives each page its index there. The resolution keeps both.
There was a problem hiding this comment.
Approved pending CI: CI has not run on this head yet; as a draft from a fork, it runs once the pull request is marked ready and a maintainer adds the ci:run label.
#8197 — approve
No blocking findings.
#9810 — approve
No blocking findings: "more" and "less" now read the caption before any write, so neither press lays the viewer out an extra time.
Whole stack — passes
A pull request lands only when it and every pull request below it are approved.
[Automated review]
|
/approve-spec 9572a26 |
There was a problem hiding this comment.
Approved pending CI: CI has not run on this head yet; as a draft from a fork, it runs once the pull request is marked ready and a maintainer adds the ci:run label.
#8197 — approve
No blocking findings; unchanged since the last review.
#9810 — approve
No blocking findings. The new commit resets the photo left behind by the page the pager reports, so a settle that arrives before the new page is marked current no longer leaves the previous photo zoomed.
Non-blocking, worth acting on before #8197 lands:
- Miss: that fix changes #8197's own
onSettle, but #8197's branch still has the old reset, so #8197 landing alone would ship the race; push the fix to #8197's branch.
The earlier non-blocking notes (FR17's verification row and review state, the useZoomStage comment, the block inside the clamped caption) still stand.
Whole stack
Passes: both heads merge cleanly with main, and the stack's net behaviour matches its approved records. A pull request lands only when it and every pull request below it are approved.
[Automated review]
| }, | ||
| // The pager names the page it rests on. Its report can come before the | ||
| // render that marks that page current, so the page, not the mark, decides. | ||
| onSettle: settled => { |
There was a problem hiding this comment.
Non-blocking (Miss): this fixes #8197's own onSettle, but #8197's branch still has the reset that skips the page marked current, so #8197 landing alone would keep a settle that reports before the render from resetting the photo it left. Push this commit to #8197's branch so the fix lands with the code it fixes.
Stack: #8197 → #9810
Stacked on #8197's 3963547, on main 993e1fa. This head, 9572a26, merges #8197's new head into e48e3e0. One conflict, in Lightbox.tsx: this pull request indents the gallery's track one level deeper, and #8197 gives each page its index there. The resolution keeps both. Before it, e48e3e0 answers CodeBunny's 04:34Z review: a caption delivery reads the caption first and commits once, vjeux@e48e3e0. The two commits before it answer the 03:52Z review, where the caption toggle takes its width from its own ResizeObserver delivery, and the 01:37Z review: the caption is measured in its ResizeObserver's deliveries, after layout, instead of in React's commit. Their base, 7968e0a, merges #8197's head into the previous head 92d50bf with no conflict, and this pull request's own diff is otherwise unchanged. Review this pull request's six commits: the caption band, vjeux@0fc994c, the answers to CodeBunny's 10:27Z review, vjeux@c83f03d, the restored description, vjeux@92d50bf, the measurement after layout, vjeux@218f7b4, the toggle's width from its delivery, vjeux@ac1101e, and one read and one commit per delivery, vjeux@e48e3e0
The design owner's option C for a gallery's captions (card 46): a constant photo area; the caption in a fixed two-line band; a longer caption clamps, and "more" opens the full caption over the bottom of the photo on a scrim; the full caption is always in the accessible description; no hidden sizing copies.
It answers the design owner's re-check (card 46C (Cindy)): the caption sat too close to the bottom, its second line was indented, its size was unusual, and the Close button showed an outline on a tap's opening. The caption must also meet 4.5:1 over a mid-grey photo (Specs decision, Nov 5 2026). Lightbox renders through Astryx parts on a media surface:
MediaTheme(dark), so its controls, caption and counter take the theme's dark surface tokens and its rules for them. No Lightbox color is left beyond the controls' and caption's backing and the on-dark color (AR9).Textin the body type, so both caption lines start at one edge. Owner decision, Nov 5 2026 (Cindy): body text.Buttonone caption line tall, at the end of the caption's last line, so the caption keeps the band's whole width and the clamp's "…" comes just before "more" (card 46D). Its hit area reaches out toward 44 px under a finger, sideways and down, never into the line above. An open caption that scrolls in its panel keeps the toggle's width clear at the end of every line.This round answers the review on the rebased head: the toggle no longer sits inside the zoom button, "less" keeps its focus, and FR17 names the caption's backing. Out of scope: the backdrop keeps the page theme's
--color-overlayand blur, as today.::backdropinherits from the dialog element, outside the media surface.User impact
In a Lightbox gallery, every page has a caption band two caption lines tall under its photo, whatever its caption. So the photo area is the same on every page, and paging never resizes it. A caption longer than two lines shows two lines and a "more" button. "More" opens the whole caption over the bottom of the photo, on a dark backing, and "less" or paging closes it. Under a finger the button takes taps out toward 44 px, and its tap is its own, not the photo's. A screen reader gets the whole caption as the viewer's description, clamped or open.
Contrast
Measured on #10084's exact preview (4c07f5c, stacked on this pull request) in Chromium: default theme, a 402 px phone viewport, coarse pointer, text against what lies under it:
Across the shipped themes (butter, chocolate, gothic, matcha, stone), body stays at or above 7.3:1, matcha the lowest. Supporting in its secondary color falls to 2.7:1 in matcha and 3.8:1 in chocolate over a white photo; the other themes give 5.0–5.6:1.
Record change
component:LightboxFR1 gains: "In a gallery, Caption sits in a band two caption lines tall under every page's Media. A longer caption shows two lines and a "more" button that opens it in full over the bottom of the Media, on a scrim. The full caption is always the viewer's accessible description. The caption band uses Astryx parts: the caption text isTextwith the body type, and "more"/"less" is a ghostButton, not hand-styled elements."MediaTheme(dark), so its controls and caption take the theme's dark surface tokens and the active theme's component rules (architecture:theme-applicationINV8), with no Lightbox-owned colors beyond AR9's backing, the caption's backing and the on-dark color." Its basis reads "Specs decision, Nov 5 2026". Its verification row names the unit file and the browser interaction spec, and states the caption's contrast over a white, a mid-grey and a black photo (body 14.7:1 over white).spec:AST-038's existing-code row now reads: "Lightbox's caption renders through Text under MediaTheme (component:Lightbox)", with the rest of the row unchanged.Writing rubric results
Visual authority
DDrow reused or amended.Design decisionstable by a team design owner.docs/design/.The design owner chose option C on card 46 and asked for these fixes on card 46C; the record states them in FR1 and FR17.
How to check
State matrix
Minimal DOM
Element counts for the current page's caption, measured in Chromium on Storybook builds. Main renders a gallery's caption as one
Textunder the photo, with no clamp and no toggle.Every captioned page renders the same elements in every state. The toggle is the only element that comes and goes, and only while the caption runs past two lines. Each element's job:
aria-controls.Text: the caption itself, also the viewer's description.Button(4 elements with its label), only while the caption runs past two lines. It hosts its own position, so the slot that wrapped it is gone.Testing
At this head (9572a26), on feat(Lightbox): swipe between gallery photos like Photos #8197's 3963547: Text and Lightbox units 196/196; core
tsc0. Lightbox a11y specs: 41/41 in Chromium, 39 in WebKit (2 skips). Lightbox interaction specs: 90 in Chromium (3 skips) and 84 in WebKit in a 4-CPU container, the CI profile (9 skips). feat(Lightbox): swipe between gallery photos like Photos #8197's "a zoomed photo keeps the drag until its edge" passes 5 of 5 there with 6 busy threads.At this head (e48e3e0), CodeBunny's 04:34Z review (vjeux@e48e3e0):
tsc0. Lightbox a11y specs: 41/41 in Chromium, 39 in WebKit (2 skips). Lightbox interaction specs: 90 in Chromium (3 skips) and 83 in WebKit in a 4-CPU container, the CI profile (9 skips), with the one failure main has too, LightboxZoomModes' Reduce Motion "+ then −" proof, which test(Lightbox): the Reduce Motion +/- proof freezes on the fade's dip #10446 fixes.At this head (ac1101e), CodeBunny's 03:52Z review (vjeux@ac1101e):
tsc0. Lightbox a11y specs: 41/41 in Chromium, 39 in WebKit (2 skips). Lightbox interaction specs: 89 in Chromium (3 skips) and 82 in WebKit in a 4-CPU container, the CI profile (9 skips), with the one failure main has too, LightboxZoomModes' Reduce Motion "+ then −" proof, which test(Lightbox): the Reduce Motion +/- proof freezes on the fade's dip #10446 fixes.At this head (218f7b4), CodeBunny's 01:37Z review (vjeux@218f7b4):
useTruncation.flushSync, it fails 3 of 3 in each engine.tsc0. Lightbox a11y specs: 41/41 in Chromium, 39 in WebKit (2 skips). Lightbox interaction specs: 88 in Chromium (3 skips) and 81 in WebKit in a 4-CPU container, the CI profile (9 skips), with one failure that main has too: LightboxZoomModes' Reduce Motion "+ then −" proof fails 5 of 30 on main 84a2254 and 7 of 30 here, against 0 of 40 on main a888b3d. test(Lightbox): the Reduce Motion +/- proof freezes on the fade's dip #10446 is its test-only fix.At this head (ced33fe): the same own diff as c83f03d (patch-id unchanged), merged onto feat(Lightbox): swipe between gallery photos like Photos #8197's 3ee5207 without conflict.
At this head (c83f03d), CodeBunny's 10:27Z items and two pre-review follow-ups (vjeux@c83f03d):
useHeldTruncation, a variant ofuseTruncationinternal to core. It keeps its answer while the caption is open, so the toggle stays mounted, with its focus, as the caption closes.useTruncation's public options don't change, and plainuseTruncationruns no new effect, so Text and Heading pay nothing new.useTruncationthat adds one.pnpm install --frozen-lockfile0; Lightbox, Text and Heading units 476/476;pnpm check:knowledgeandpnpm check:changesetspass; coretsc0; strict ESLint 0; comment sentence lengths 0 over. Leak and public-text checks clean.LightboxPaging"the page settle keeps advancing every frame while the main thread is blocked" fails as on 0fc994c: feat(Lightbox): swipe between gallery photos like Photos #8197's tempo commit fixes it below this pull request.Red first:
At this head (0fc994c): Lightbox units 139/139; core
tsc0, strict ESLint 0, comment sentence lengths 0 over. On a Storybook build of this head: Chromium Lightbox a11y specs 38/38; WebKitLightboxViewportandLightboxKeyboard17/17; Lightbox Paging, Zoom and EveryPointer specs 78 passed in Chromium (3 WebKit-only skips); WebKit Paging, EveryPointer and Keyboard 38 passed (5 skips).Lightbox.tsx(the clamped caption isDIV(DIV(SPAN(),SPAN())), the one that fitsDIV()) and passes here.At c56f4e1: Lightbox units 138/138; core
tsc0, strict ESLint 0, comment sentence lengths 0 over, Prettier clean;pnpm check:knowledgeandcheck:repopass. On a Storybook build of this head: Chromium Lightbox a11y specs 38/38; Lightbox Paging, Zoom and EveryPointer specs 55 passed in Chromium (3 WebKit-only skips); WebKit Paging and EveryPointer plus theLightboxViewportcaption cases 34 passed (5 skips).LightboxViewport.a11y.browser.spec.ts: "a gallery page without a caption shows no caption backing, and every page's photo keeps its top" and "a clamped caption's "more" ends its second line, with no column of its own" (402 × 874 and 1440 × 900), and "… still ends its second line after the viewport narrows (402 → 360)" fail on 053f321's build and pass here. "An open caption scrolled to its end keeps every line beside "less" clear of it" (360 × 150, 390 × 150) fails on a build that keeps the inline place while the caption scrolls, and passes here. The unit case "follows the caption in reading order, and its place in the last line is hidden from assistive technology" fails on 053f321's product.iPhone 17 Pro simulator (iOS 26.2, Safari), on c56f4e1's Storybook build, every frame viewed: every page's photo top is 189 pt; page 1's two lines end in "…" and "more" (its last line ends at 318 pt, "more" sits at 328–390 pt on that line); page 2's two lines fit with no toggle; page 3 has no caption and no backing (
rgba(0, 0, 0, 0)); page 4's one line sits on its backing.c56f4e1's preview on the iOS 26.2 simulator (Safari, every frame viewed), pages 1 to 4:
Desktop, Chromium at 1440 × 900. Before (main, which has no captioned gallery story: "Gallery" page 1 and its captionless page 2, and "With caption" for a long caption):
After (c56f4e1, "Gallery with captions"): "more" collapsed, the same caption expanded, the captionless page, and a short caption:
At 053f321: core
tsc0, strict ESLint 0, comment sentence lengths 0 over, Lightbox units 137/137. Red first: the new case "returns focus to the opener without scrolling the page when the viewer closes" fails on 57425e7's product, whose close focused the opener withoutpreventScroll. On a Storybook build of this head: Chromium Lightbox a11y specs 31/31; Paging and EveryPointer 28 passed in Chromium (3 WebKit-only skips); Paging, EveryPointer and Keyboard 26 passed in WebKit (5 skips); the a11y audit finds 0 new violations;pnpm check:knowledgeandcheck:repopass.At 57425e7 (053f321 without the shared focus return): the LightboxKeyboard spec 9/9 in Chromium; Lightbox Paging and EveryPointer specs 28 passed in Chromium (3 WebKit-only skips), and Paging, EveryPointer and Keyboard 26 passed in WebKit (5 skips).
At 40e8001, the same behavior before the focus handoff moved to the shared helpers (the head also differs by the FR17 basis cell and two comments):
tsc0; strict ESLint on every changed file 0; comment sentence lengths 0 over;pnpm check:knowledgeandcheck:repopass (check:changesets,check:i18n-catalog,check:i18n-runtime,check:use-clientandcheck:package-boundariesat 65534b6, the same code without the viewport hook).Existing cases: the fine-pointer touch-action lists gain the media surface's
auto; the scroll case's viewport is 240 px tall so the body-size caption still overflows its panel; the paging specs find the pager's viewport bydata-lightbox-viewport, since the zoom button is now the photo box.iPhone 17 Pro simulator (iOS 26.2, Safari), on 4dded66's build, every frame viewed: a tap's opening leaves Close without a ring, and a key's opening shows it; the caption is body
Text(16 px in the default theme), its lines start at one edge, and the band keeps 12 px under them.