Skip to content

Start each value under its label when the Details rows stack - #43

Merged
threeqube merged 1 commit into
mainfrom
stacked-rows-left
Nov 6, 2026
Merged

threeqube merged 1 commit into
mainfrom
stacked-rows-left

Conversation

@threeqube

@threeqube threeqube commented Nov 6, 2026 •

Copy link
Copy Markdown
Collaborator

For digitalcredentials/lcw-front-end#177 (make the web wallet usable on a phone).

What changes

The card's Details rows (Tampering, Issuer, Status, Dates, How it was built) are a label and a value.

  • In a wide card, they sit side by side, with the value at the right. This doesn't change.
  • In a card 380px wide or less, each row already stacked: the label, then the value on the line under it. But the value stayed aligned to the right. A short value sat at the far edge of the card, away from its label, and a long one wrapped ragged ("LCW Sandbox Issuer — a known / issuer").

Stacked, the value now starts under its label, with its mark at the start of the line.

Where a reader sees it:

  • the demo page at phone width;
  • the wallet's credential page, on phones and on laptops. On a laptop the wallet shows the card in a 370px side column, so the rows stack there too.

The wallet picks this up when it next takes the release build: digitalcredentials/lcw-front-end#208, which already plans to.

The code (5 lines of CSS)

In src/verifier-credential.ts, .check .v sets the value's alignment:

  • The narrow-card rule gains .check .v { text-align: start; }. That's @container (max-width: 380px).
  • That rule moves below .check .v { text-align: end; … }. The two selectors are equally specific, so the later rule wins. Left where it was, above, the new line would have been silently ignored.
  • right becomes end and the new rule uses start, rather than right and left. In English these are the same thing, and the screenshots below are byte-identical. In a right-to-left page they follow the reading direction. With left, a stacked value there would hug the far edge, the same problem in mirror image. The card isn't translated today, so this just avoids building in a new problem.

How it was checked

New browser tests in test/browser/states.spec.ts:

  • stacked on a phone, each value starts under its label (360px, on the "Verified" and "Registry offline" demo credentials): each value is below its label and starts within 1px of the label's left edge. Fails on main ("Tampering: the value does not start under its label"); passes here.
  • side by side in a wide card, each value keeps to the right (1024px, same two credentials): each value is beside its label and ends within 1px of the row's right edge. Passes on main and here; it guards the wide layout.
  • stacked in a right-to-left page, each value starts under its label, at the right (360px): the same check, mirrored. It fails if the stacked rule uses left, and passes with start.

One existing test changed on purpose: a value too long for the row, such as an issuer's did:key, stays inside the card.

  • At 360px it expected the mark just above a long identifier, at the right. With the rows stacked and starting under the label, it's now just above, at the left, where the identifier starts.
  • With the new expectation it fails on main (the mark is 252px away), as it should.
  • Its "fits inside the card" and "just above" checks are unchanged.

Deliberate breaks, each judged by the test run's exit code, with control runs before and after to show the unbroken code passes. 7 of 7 caught:

  • the new rule back above .check .v, where it loses;
  • no start-align when stacked;
  • start-aligned in wide cards too;
  • rows never stack;
  • centred when stacked;
  • rows stack only below 300px;
  • left instead of start.

Screenshots of the demo card, two runs each, main against this branch. They cover Verified, Registry offline, Issuer unknown, Expired and Not their seal, plus the Developer and JSON views:

  • at 1024px: all 7 byte-identical;
  • at 360px: only the 5 Details views differ, as intended. The Developer and JSON views are byte-identical.

In the wallet: main and this branch were each built and installed into a separate copy of the wallet, signed in to the sandbox demo account, and shown the demo credential.

  • The card changes on a phone (293px wide) and on a laptop (370px wide), as described above, and the page still fits a 375px screen.
  • The wallet's served bundle was checked to contain the new rule only in the "after" run, so the comparison was real, not a cached copy.

Repeated runs:

  • Chromium: the changed and added tests 5 of 5; the whole browser suite 3 of 3 (65 passed, plus 1 skipped by design, since it only runs against a published copy).
  • WebKit: the changed and added tests 3 of 3.
  • The whole suite in WebKit has one failure, switching views does not re-announce, and keeps focus on the button used. It fails on main in WebKit too: Safari's engine doesn't focus a button when it's clicked. CI runs Chromium only, where it passes. It's unrelated to this change.

Repo checks: npm run lint, npm run typecheck, npm test (156,425 passed) and npm run build pass.

Independent review: a fresh reviewer, given only the code and the goal. 2 findings, neither blocking.

  • Nit, fixed: left/right are physical, so a right-to-left page would show the stacked value at the far edge. This was reproduced (up to 209px off), fixed with start/end, and is now covered by the right-to-left test.
  • Pre-existing, not changed here: when a value starts with one word too long for the line, such as a did:key, its mark sits alone on the line above it. The reviewer thinks the whitespace between the mark and the value in the markup lets the line break there. That's for a separate ticket if it's wanted.

The reviewer also confirmed:

  • the change takes effect at exactly 380/381px;
  • all five rows share one template;
  • the Developer and JSON views don't use these rules;
  • each new test fails with the feature removed.

By hand: Sunny opened this PR's preview on a phone, and in Chrome at 400px, and checked the Details rows on the Verified, Registry offline and Issuer unknown credentials: each value starts under its label, including a value that wraps onto a second line.

How to undo

Revert the one commit. Nothing stored changes, and the wallet only sees the change once #208 takes a new release build.

Reading guide (about 3 minutes)

  1. src/verifier-credential.ts, the .check rules. The narrow-card block now comes after .check .v, and holds both the one-column grid and text-align: start. .check .v itself says end instead of right.
  2. test/browser/states.spec.ts:
    • valueEdges, which measures where each value starts and ends;
    • the three new tests that use it;
    • the one changed line in the did:key test (fromRight → fromLeft).

🤖 Generated with Claude Code

In a card 380px wide or less, as on a phone or in the wallet's side column,
each Details row stacks: the label, then its value on the line under it. The
value kept the end alignment it has when the two sit side by side, so a short
value sat at the far edge of the card, away from its label, and a long one
wrapped ragged. Stacked, it now starts where the label does. Side by side,
in a wider card, nothing changes.

The narrow-card rule moves below `.check .v`, so its text-align wins. Both
alignments are start and end rather than left and right, so a right-to-left
page mirrors the layout instead of breaking it; left-to-right renders
pixel-for-pixel as with left and right.

The did:key test expected the mark at the right, above a long identifier; at
360px the rows stack, so it is now at the left, where the identifier starts.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@github-actions

github-actions Bot commented Nov 6, 2026

Copy link
Copy Markdown
Contributor

Try it: https://digitalcredentials.github.io/verifier-plugin/pr-43/

Updates on every push to this PR, and goes away when it closes. The browser tests run against this copy too.

@threeqube

Copy link
Copy Markdown
Collaborator Author
Screenshot 2026-11-06 at 1 47 02 PM Screenshot 2026-11-06 at 1 47 31 PM Screenshot 2026-11-06 at 1 47 37 PM

@threeqube

Copy link
Copy Markdown
Collaborator Author

Smoke test before merge, 6 November 2026, on b50acb1. main is still at 72683b8, which this branch is built on, so the code tested is the code that merges.

Against the published preview (https://digitalcredentials.github.io/verifier-plugin/pr-43/):

  • Whole browser suite, Chromium, run twice: 63 passed, 3 skipped. The 3 skipped need a second local site, so they only run locally; CI's test-published skips the same 3.
  • The alignment tests in WebKit, three runs: 6 of 6 each time. These cover stacked, side by side, right-to-left, and the long did:key value. WebKit is Safari's engine.
  • By hand (Sunny): checked on a phone and in Chrome at 400px. On Verified, Registry offline and Issuer unknown, each value starts under its label, including one that wraps.

CI on b50acb1: test, browser, build, publish and test-published pass. remove is skipped, as it only runs when the PR closes.

What merging changes:

Not checked: a real screen reader. The marks are hidden from screen readers, and the text read out is unchanged by this PR.

Found while testing, out of scope here: two small problems with how the mark sits beside its value. Both happen on main too, or only show once this is in. They'll be filed together as one ticket after this merges.

@threeqube

Copy link
Copy Markdown
Collaborator Author

In the wallet: lcw-sandbox.org (9 November 2026)

All clear. This PR has now reached the wallet. James deployed lcw-sandbox.org with lcw-front-end 0034b08, which pins release at a2a2181, the build of main 7c57591. That build includes #31, #33, #38, #39, #41, #42 and #43. I wrote the expectations down before checking.

  • Right build: a2a2181's dist/ is byte-identical to a fresh build of 7c57591, and its wording is in the live wallet's JavaScript.
  • Same behaviour as main: I gave the deployed <verifier-credential> on lcw-sandbox.org and the live demo (also 7c57591) the same 107 credentials and the same registries: the 12 demo situations, 4 built for No status behind a seal that didn't hold #33 and Say when a seal can never be checked, instead of "try again" #42, and the 91 in vc-test-fixtures. All 107 gave the same verdict, severity and card text.
  • Signed in to the wallet (the deployed smoke test's demo account, read only): the LCW Experience Badge reads "Verified", with the issuer "a known issuer" and Tampering "none detected", at desktop and phone widths. The card logs no console errors of its own. The only errors are the known ones: the OpenID Federation registries block browser requests.
What this PR changed In the wallet
Stacked rows start under their label ✅ the card is 370px wide in the wallet's desktop side column and 308px on a phone; every Details value starts at its label's left edge
Side by side unchanged ✅ a 600px card: label at the start, value at the end

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant