What the role you just picked actually hands somebody, in words, from the same source of truth the app enforces.
16 Sept 2026 · branch lane-a-teammates-role-card · captured against propflow-stage · at 8431078d30
Data note. Every name and balance below comes from propflow-stage, which is anonymized by construction (ADR-0097/0110 — phones in the impossible +1000 NPA, emails @example.test). The identical capture against prod would carry real tenants' names and balances and is not safe to attach anywhere, which is why the generator refuses to run against one.
Every row HAS a role — a blank one starts on Property manager — so “render the card when a role is picked” cannot mean “when row.role is set”. It means once the row has been touched. This is the untouched state: no card, and the footer is where it has always been.
Asserted in the captured DOM — Add your team · Finish. The step renders; the card is absent rather than empty.
Typing an address is one of the two ways to touch a row, and it is the one that matters most: the default role is now being handed to a real person. Both halves render — what they can do, and the part an admin is actually checking, what they can't. Every line is a quote from a gate that ships today: the fail-closed entity matrix, the invite ladder, and building scope.
Look at the inset and the glyph alignment: the check and cross are flexShrink: 0 against sentences that wrap, and the body ink is --color-text-muted (5.34:1) rather than the --color-text-mid the rest of the step uses, which globals.css measures at 3.98:1 and calls a knowing AA failure at 12px.
Asserted in the captured DOM — What they can do · Run the day to day: leasing, maintenance, collections, residents and vendors. · Make somebody an organization admin.. The heading, a can-line and a cannot-line of the DEFAULT role, in the state the screenshot shows.
Picking a role is the other way to touch a row. “Open maintenance or vendors at all” is the fail-closed reading and it is exact: this role has no key for either entity in the matrix, so every action is denied, not just editing. The same role's list says “change a setting” rather than “open settings”, because it does hold settings: READ — a distinction the copy draws on purpose, and differently again for Maintenance.
Asserted in the captured DOM — Run leasing end to end: prospects, tours and renewals. · Open maintenance or vendors at all.. The LEASING AGENT card, after a pick — not the default role's.
.ob-row-grid collapses the row to one column at ≤640px. The card sits under the select it explains at both widths, which is why it is a sibling of the row grid rather than a fourth cell inside it.
Asserted in the captured DOM — What they can do · Make somebody an organization admin.
Neither identity this tool signs in as can reach the wizard: the smoke account is platform_admin, which the wizard layout redirects to /dashboard, and the seeded non-staff identity is already onboarded, which redirects too. A local dev server serves the step unauthenticated (middleware.ts short-circuits outside production, and the layout runs its redirects only when a session exists), so these frames are the step exactly as a customer meets it. The run's own guard confirmed the data source was propflow-stage before a browser launched.