feat(v2): Connectors and Tools rows in Direction A — marks, one worded act, mono kicker - #1782
Conversation
|
Evidence committed at Measured on the page (
Gates asked: ux-lead at 1440/720/390 (Sharpen), Wren's read and Vera's exact-head clearance (Connectors lane). Pressed by me only on both. |
|
Recut for Vera's hold at
172/172 across the two component suites, the layout invariants and the manifest test; tsc and eslint clean. |
ec6dc66 to
3084de5
Compare
lilyshen0722
left a comment
There was a problem hiding this comment.
UX-GATE: PASS @ 3084de5 — fixture build at 1440 / 720 / 390 (mock API, worktree at the head; interdiff from ec6dc66 is the kicker's key-and-timestamp composition only, re-measured on the new bundle).
1440. 11 rows on the three-track grid (140 / 502 / 120), no age column. Every row carries the Plex Mono 11 lowercase kicker (sharpen · added 6d, no pod · not connected, connectors v2 · started 2d, not yet, sharpen · granted 6d, not granted); mode word display:none. Relay mark 16×16 with the sentence in title + aria-label (attention · escalations reach the channel, relay off · messages stay in the pod); Tools write-mode glyph titled read / read and write, ask first. Gear 32×32, title + aria Manage; word acts 32 tall (Add 50, Ask 49, New code 85, Pick a pod 88). Dots: live ink #101828 (+pulse on the live Telegram and the GitHub grant), idle #e4e7ec, empty hollow #98a2b3, revoked filled grey, not-yet dashed. Nothing under 11px; no green; no cobalt inside a row. Grant aside: Change access 115×36 + ✕ (path M18 6 6 18M6 6l12 12, title + aria Revoke) → Yes, revoke it 110×40 / Keep it 68×36.
720 and 390. Rows 89–170 tall (min 72 holds); gear 44×44 in row 1 beside the name; a row's word act is full width (662 / 332) and 44 tall; the mode word rides the kicker (… · attention, … · relay off, … · nothing asks first, … · every write asks first) and the mark is hidden; no horizontal overflow (scrollWidth = viewport at both); Tools head, search and All / Granted / Not yet segments present; aside ✕ 44×44 Revoke. Min font 11 at both.
Non-blocking, for the follow-up row:
- At 1440 the aside ✕ measures 32×36 — the flex row stretches it to Change access's height. The rule names a 32 square;
align-self: center(or accept 36) — under 760 it is a correct 44 square. - After 3084de5 the not-enabled catalog row's kicker is just
no pod(wasno pod · —). Better than the dash;not enabledwould give it a verb like every other row. Nit. - On connected rows the mark sits alone on line 3 (detail is empty) — reads as the v3 chip line; taste only.
- Pre-existing, not this PR:
Discord · WhatsAppwraps in the 140 name column at 1440 and butts the sentence.
Captures at the three widths posted in Sharpen.
|
zh-CN gate: Sam passed the 13 Chinese strings as written ("All good", 2026-09-19 ~20:35Z, in his session with Wave). The native-speaker hold on this PR is cleared; remaining gates are Vera's stamp at |
|
Rebased onto main |
3084de5 to
c586c70
Compare
…d act, mono kicker The ruled direction (Sam, 2026-09-11) applied to the shipped Connectors page, drawn first as the "Connectors, quieter" artboard (v3, ux-lead's pixel read applied, Sharpen 70159–70161 and 70216–70218). Rule 1, categories are marks. Relay mode on a linked channel row is a 16px glyph (attention / mirror / off) with the sentence in title and aria-label; the state dot is ink filled, hollow, dashed or grey, never cobalt. The Tools write-mode glyph already followed this. Rule 2, only the deciding act is a word. Manage is the 32px gear on both lists (44 on the phone, right-aligned), the word in title and aria-label; Add, Pick a pod, New code and Ask keep their words. A provider row's act says Add, since the pod is chosen in the aside. In the grant aside, Revoke is the ✕ beside Change access (the Deny precedent) and still asks to confirm. Rule 3, meta is mono chips. Every row carries `pod · verb age` in mono 11 above line 1 (`rewire live demo · added 23d`, `sharpen · granted 6d`, `no pod · not connected`); the age column is gone. At 390, where tooltips do not exist, the mode word rides the kicker instead of the glyph; a row's word act is full width and rows keep one height. Tests: the linked row's kicker, mark (role img + label) and gear are pinned on both pages; ages are asserted on the kicker; the layout invariants pin the three-track grid, the ink dot, the mono-11 kicker, the hidden mode word and the 32/44 gear. 168/168 across the three suites; tsc and eslint clean. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01W7WB68pA8L2nkvSqZPx37w
…de line, with evidence From the first fixture capture: at 390 the gear sat above the row and the not-enabled row's Ask kept its old placement, because the new act rules were declared before the older phone rule in the same media block. They now follow it; the selection button is pinned to row 1 so the 44px gear shares it beside the name; a row's word act is full width under the sentence; the kicker keeps clear of the gear. The Tools row no longer pairs the write-mode glyph with its words — the audience is the sentence, the glyph carries the mode, and the words ride the 390 kicker. Evidence (fixture build, DPR 2, before = main, after = this branch), at 1440 / 720 / 390, under docs/design/evidence/connectors-direction-a-*.png. Measured on the after page: 6 kickers, 1 relay mark, gear 32px at 1440 and 44px at 720/390, nothing under 11px; worded buttons 14 → 12. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01W7WB68pA8L2nkvSqZPx37w
…es carry its keys
Vera's hold (Connectors 70299/70300): the kickers stripped " ago" off
already-rendered English, which breaks under any other locale, and six
keys were added to en.json without zh-CN.json, so the migration manifest
test went red (identical base key paths).
Now `shortAge(date)` turns the timestamp into a unit-suffixed number
through `time.age.*` keys ("23d", "5m", "just now") and each verb line is
a key with an `{{age}}` slot (`connectors.age.added|started|since|paused|
slackAnswered`, `tools.grantedAge`); the kicker composes the pod name and
that line and never touches rendered text. A row with no age (the
not-enabled row's dash) carries only the pod.
zh-CN carries every new key path. The Chinese values follow the locked
glossary (Pod stays Pod, 你 register, no English left in the 中文 UI) and
are marked for Sam's native-speaker read on the PR; the manifest test
needs the paths, not the final wording.
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01W7WB68pA8L2nkvSqZPx37w
c586c70 to
dc117c0
Compare
#1782) #1782 landed on main as ba3306f and rule 3 renders the grant age as `pod · granted 1h` — the `ago` suffix is gone (main's own assertions at this file were updated in the same PR). These two are the TASK-135 tests added by this branch, so they were the only ones left asserting the old string; they fail on the merged tree without this. Mutation-checked: reverting both to 'granted 1h ago' reds exactly these two.
…s its blocker (TASK-140) Two of the four Direction A follow-ups from ux-lead's #1782 gate. 1. The Revoke ✕ measured 32×36 at 1440. The button carries `.v2-connector-aside__secondary` as well as `--icon`, and that rule sets `min-height: 36px` — and min-height beats height, so the icon rule's own `min-height: 32px` never applied. The first cut of this fix composed the selector but set only `height: 32px`, and the gate caught it still measuring 32×36 (computed min-height 36px): the override has to land on the MINIMUM. Both are set now, and the ≤760 rule gets the same treatment so the 44px thumb target is not left to be clamped by a 36px floor. 2. A not-enabled catalog row's kicker read `no pod`. The row has no connection at all, so the pod slot named something that does not exist and read as a missing pod rather than a disabled provider. It now reads `not enabled` (en + zh-CN). Deliberately NOT here, left for ux-lead rather than decided unilaterally: - the `Discord · WhatsApp` wrap at 1440, whose cause is the 140px name track in the connector row grid — pinned as artboard geometry by v2-layout-invariants:1732 — and where the obvious CSS (nowrap) is the one-line-ellipsis-of-an-identifier pattern this repo already rejected. - the mark alone on the row's third line, a taste call by construction. Evidence: V2ConnectorsPage + v2-layout-invariants + V2ConnectorTools = 3 suites 169/169. Mutation-proved alone: dropping `min-height: 32px` reds exactly the new invariant, and reverting the kicker to the unconditional `no pod` reds exactly the new behaviour test. eslint 0 errors on the touched files. The guard for 1 is a presence assertion, and its first form pinned `height` while asserting `min-height` was ABSENT — green while the box was 36 tall. It asserts the minimum now; the browser gate remains the instrument that can actually see it.
#1782) #1782 landed on main as ba3306f and rule 3 renders the grant age as `pod · granted 1h` — the `ago` suffix is gone (main's own assertions at this file were updated in the same PR). These two are the TASK-135 tests added by this branch, so they were the only ones left asserting the old string; they fail on the merged tree without this. Mutation-checked: reverting both to 'granted 1h ago' reds exactly these two.
…s its blocker (TASK-140) Two of the four Direction A follow-ups from ux-lead's #1782 gate. 1. The Revoke ✕ measured 32×36 at 1440. The button carries `.v2-connector-aside__secondary` as well as `--icon`, and that rule sets `min-height: 36px` — and min-height beats height, so the icon rule's own `min-height: 32px` never applied. The first cut of this fix composed the selector but set only `height: 32px`, and the gate caught it still measuring 32×36 (computed min-height 36px): the override has to land on the MINIMUM. Both are set now, and the ≤760 rule gets the same treatment so the 44px thumb target is not left to be clamped by a 36px floor. 2. A not-enabled catalog row's kicker read `no pod`. The row has no connection at all, so the pod slot named something that does not exist and read as a missing pod rather than a disabled provider. It now reads `not enabled` (en + zh-CN). Deliberately NOT here, left for ux-lead rather than decided unilaterally: - the `Discord · WhatsApp` wrap at 1440, whose cause is the 140px name track in the connector row grid — pinned as artboard geometry by v2-layout-invariants:1732 — and where the obvious CSS (nowrap) is the one-line-ellipsis-of-an-identifier pattern this repo already rejected. - the mark alone on the row's third line, a taste call by construction. Evidence: V2ConnectorsPage + v2-layout-invariants + V2ConnectorTools = 3 suites 169/169. Mutation-proved alone: dropping `min-height: 32px` reds exactly the new invariant, and reverting the kicker to the unconditional `no pod` reds exactly the new behaviour test. eslint 0 errors on the touched files. The guard for 1 is a presence assertion, and its first form pinned `height` while asserting `min-height` was ABSENT — green while the box was 36 tall. It asserts the minimum now; the browser gate remains the instrument that can actually see it.
#1782) #1782 landed on main as ba3306f and rule 3 renders the grant age as `pod · granted 1h` — the `ago` suffix is gone (main's own assertions at this file were updated in the same PR). These two are the TASK-135 tests added by this branch, so they were the only ones left asserting the old string; they fail on the merged tree without this. Mutation-checked: reverting both to 'granted 1h ago' reds exactly these two.
…s its blocker (TASK-140) Two of the four Direction A follow-ups from ux-lead's #1782 gate. 1. The Revoke ✕ measured 32×36 at 1440. The button carries `.v2-connector-aside__secondary` as well as `--icon`, and that rule sets `min-height: 36px` — and min-height beats height, so the icon rule's own `min-height: 32px` never applied. The first cut of this fix composed the selector but set only `height: 32px`, and the gate caught it still measuring 32×36 (computed min-height 36px): the override has to land on the MINIMUM. Both are set now, and the ≤760 rule gets the same treatment so the 44px thumb target is not left to be clamped by a 36px floor. 2. A not-enabled catalog row's kicker read `no pod`. The row has no connection at all, so the pod slot named something that does not exist and read as a missing pod rather than a disabled provider. It now reads `not enabled` (en + zh-CN). Deliberately NOT here, left for ux-lead rather than decided unilaterally: - the `Discord · WhatsApp` wrap at 1440, whose cause is the 140px name track in the connector row grid — pinned as artboard geometry by v2-layout-invariants:1732 — and where the obvious CSS (nowrap) is the one-line-ellipsis-of-an-identifier pattern this repo already rejected. - the mark alone on the row's third line, a taste call by construction. Evidence: V2ConnectorsPage + v2-layout-invariants + V2ConnectorTools = 3 suites 169/169. Mutation-proved alone: dropping `min-height: 32px` reds exactly the new invariant, and reverting the kicker to the unconditional `no pod` reds exactly the new behaviour test. eslint 0 errors on the touched files. The guard for 1 is a presence assertion, and its first form pinned `height` while asserting `min-height` was ABSENT — green while the box was 36 tall. It asserts the minimum now; the browser gate remains the instrument that can actually see it.
#1782) #1782 landed on main as ba3306f and rule 3 renders the grant age as `pod · granted 1h` — the `ago` suffix is gone (main's own assertions at this file were updated in the same PR). These two are the TASK-135 tests added by this branch, so they were the only ones left asserting the old string; they fail on the merged tree without this. Mutation-checked: reverting both to 'granted 1h ago' reds exactly these two.
…s its blocker (TASK-140) Two of the four Direction A follow-ups from ux-lead's #1782 gate. 1. The Revoke ✕ measured 32×36 at 1440. The button carries `.v2-connector-aside__secondary` as well as `--icon`, and that rule sets `min-height: 36px` — and min-height beats height, so the icon rule's own `min-height: 32px` never applied. The first cut of this fix composed the selector but set only `height: 32px`, and the gate caught it still measuring 32×36 (computed min-height 36px): the override has to land on the MINIMUM. Both are set now, and the ≤760 rule gets the same treatment so the 44px thumb target is not left to be clamped by a 36px floor. 2. A not-enabled catalog row's kicker read `no pod`. The row has no connection at all, so the pod slot named something that does not exist and read as a missing pod rather than a disabled provider. It now reads `not enabled` (en + zh-CN). Deliberately NOT here, left for ux-lead rather than decided unilaterally: - the `Discord · WhatsApp` wrap at 1440, whose cause is the 140px name track in the connector row grid — pinned as artboard geometry by v2-layout-invariants:1732 — and where the obvious CSS (nowrap) is the one-line-ellipsis-of-an-identifier pattern this repo already rejected. - the mark alone on the row's third line, a taste call by construction. Evidence: V2ConnectorsPage + v2-layout-invariants + V2ConnectorTools = 3 suites 169/169. Mutation-proved alone: dropping `min-height: 32px` reds exactly the new invariant, and reverting the kicker to the unconditional `no pod` reds exactly the new behaviour test. eslint 0 errors on the touched files. The guard for 1 is a presence assertion, and its first form pinned `height` while asserting `min-height` was ABSENT — green while the box was 36 tall. It asserts the minimum now; the browser gate remains the instrument that can actually see it.
#1782) #1782 landed on main as ba3306f and rule 3 renders the grant age as `pod · granted 1h` — the `ago` suffix is gone (main's own assertions at this file were updated in the same PR). These two are the TASK-135 tests added by this branch, so they were the only ones left asserting the old string; they fail on the merged tree without this. Mutation-checked: reverting both to 'granted 1h ago' reds exactly these two.
…s its blocker (TASK-140) Two of the four Direction A follow-ups from ux-lead's #1782 gate. 1. The Revoke ✕ measured 32×36 at 1440. The button carries `.v2-connector-aside__secondary` as well as `--icon`, and that rule sets `min-height: 36px` — and min-height beats height, so the icon rule's own `min-height: 32px` never applied. The first cut of this fix composed the selector but set only `height: 32px`, and the gate caught it still measuring 32×36 (computed min-height 36px): the override has to land on the MINIMUM. Both are set now, and the ≤760 rule gets the same treatment so the 44px thumb target is not left to be clamped by a 36px floor. 2. A not-enabled catalog row's kicker read `no pod`. The row has no connection at all, so the pod slot named something that does not exist and read as a missing pod rather than a disabled provider. It now reads `not enabled` (en + zh-CN). Deliberately NOT here, left for ux-lead rather than decided unilaterally: - the `Discord · WhatsApp` wrap at 1440, whose cause is the 140px name track in the connector row grid — pinned as artboard geometry by v2-layout-invariants:1732 — and where the obvious CSS (nowrap) is the one-line-ellipsis-of-an-identifier pattern this repo already rejected. - the mark alone on the row's third line, a taste call by construction. Evidence: V2ConnectorsPage + v2-layout-invariants + V2ConnectorTools = 3 suites 169/169. Mutation-proved alone: dropping `min-height: 32px` reds exactly the new invariant, and reverting the kicker to the unconditional `no pod` reds exactly the new behaviour test. eslint 0 errors on the touched files. The guard for 1 is a presence assertion, and its first form pinned `height` while asserting `min-height` was ABSENT — green while the box was 36 tall. It asserts the minimum now; the browser gate remains the instrument that can actually see it.
#1782) #1782 landed on main as ba3306f and rule 3 renders the grant age as `pod · granted 1h` — the `ago` suffix is gone (main's own assertions at this file were updated in the same PR). These two are the TASK-135 tests added by this branch, so they were the only ones left asserting the old string; they fail on the merged tree without this. Mutation-checked: reverting both to 'granted 1h ago' reds exactly these two.
Artboard first
Drawn and read before this cut: Connectors, quieter v3 — https://claude.ai/artifact/4GvYVrBNoFSHukdCZDEcsu (rendered 1440 and 390 frames in Sharpen 70220/70221). ux-lead's read (70159–70161, 70216–70218) is applied; the two Sam calls are drawn as the reviewer recommended: Revoke as the ✕, providers as rows with Add.
What changes on the page
title+aria-label; the dot is ink / hollow / dashed / greytitle+aria-label; provider rows say Add; Revoke in the aside is the ✕ beside Change access and still confirmspod · verb agemono-11 kicker above line 1 on every row; the column is gone; at 390 the mode word rides the kickerFiles:
V2ConnectorsPage.tsx,V2ConnectorTools.tsx,icons/glyphs.tsx(gear act, relay marks),v2.css,en.json(six keys, all withdefaultValuefallbacks — zh-CN follows the open zh-CN coverage row).Proof
V2ConnectorsPage.test.tsx: Direction A: a linked row carries a mono kicker, a relay mark with its sentence in the label, and Manage as the gear; age assertions moved to the kicker.V2ConnectorTools.test.tsx: Manage buttons are the gear with the word in the label; the age column is gone and the kicker carries· granted.v2-layout-invariants.test.ts: three-track row grid, ink dot (not accent, no status colour), mono-11 kicker, mode word hidden above 760 and shown under it, gear 32 / 44.tsc --noEmit0 errors; eslint 0 errors.Screenshots at 1440 / 720 / 390 from the fixture build, before and after, follow in the next commit (ux-lead gates at all three).
🤖 Generated with Claude Code
https://claude.ai/code/session_01W7WB68pA8L2nkvSqZPx37w