- Shipped
- September 18, 2026 at 2:57 AM UTC
- Author
- Kamo
- Commit
- dee972f
One card for every member name in kamo-internal, gated by the server rule SecurityService now serves (MemberInteractionPolicy, securityservice 5063eaa): chat, call, meet now, email up front; text, schedule and a game (chess / Texas Hold'em) behind More; their profile — or, for a customer-side member, their account — in the footer. A refused action is drawn dimmed with a lock and says why on hover (the chat policy in the org's own words); an action the viewer can never take is not drawn at all. The pieces (app/components/members/card, app/lib/memberCard): - MemberName / MemberChip / MemberHoverCard — triggers built on the mail correspondent card's useHoverCard (intent, one card at a time, anchoring, Escape returns focus, tap on touch), which gains `clickToggles` so a name that already does something on click keeps that click. - MemberCard — header tinted with the member's own hue blended into the brand, live presence ring, title · department, their local time and how far ahead or behind you, copy-to-check details. - MemberActionBar — the card's labelled buttons, or a row's compact strip. - MemberAvatar — the one avatar (sized photo, else initials on the member's hue, optional presence). - actions.ts — the ONE set of executors; the composer's `initialData.to` list, chat by userId, Hold'em as "play", not "create", each pinned by a test. - cache.ts — one read per member, shared by every trigger, 60s TTL, primed from roster rows, read through useSyncExternalStore so no state is set inside an effect. - MemberCardDialogs — mounted once in AuthedChrome for the meeting dialog, which gains `initialMode` so "Schedule" opens ready to pick a time. Layer 1305: over MUI dialogs, so a name inside a dialog still gets its card; under MUI tooltips. The three copies of these actions are gone: - Interaction Center rows draw the shared strip from `interaction` on each roster row; "⋯" opens the full card. NavTopPanel's hand-copied profile and mail gates are removed. - The chat hex-head popover follows the card's decision for a one-to-one chat. Its "View account" was offered to everyone and led to a page most members are bounced from; it now appears only when the viewer may open that profile, and goes to it. - MemberContactCard (lead lock holder / roster) draws the shared pieces instead of its own Call and Message. The webinar Presenters table puts the card on each presenter and an amber "No bookable time" warning beside any presenter a visitor cannot book (mediaservice a9f20cc), with a tooltip saying what to do. Spec and plan: **************** **************** The rest of the rollout follows. Tests: memberCard lib (parse, cache, reasons, local time, every executor), MemberCard render (hover, keyboard, hidden vs dimmed, More, footer, click preserved, no id, not found), presenter gaps, hex-head profile gate. tsc clean; eslint adds nothing to the touched files' existing counts; guards pass; 632 tests across the touched directories green.