Files
breadcrumb-the-shire/modules/addressbook/web/css/pages/address-book-index.css
fs 811588290c feat(core): detail drawer + address book list redesign
Introduces a reusable core detail-drawer primitive that slides in from the
right and loads any view via a `*-fragment(none).phtml` endpoint. Bundles the
address book list overhaul that is its first consumer.

Core additions:
- `app-detail-drawer.js` — generic drawer with stepper, focus trap, body
  scroll-lock, URL-hash deep-linking, session-expiry detection
- `app-fragment-init.js` — auto-wires tabs/lookups/confirm/file-upload/
  fslightbox inside injected HTML; consumers do not re-initialize components
- `app-focus-trap.js` — shared focus-trap + refcounted scroll-lock, used by
  both filter-drawer and detail-drawer
- `getHtml()` in `app-http.js` + `SessionExpiredError`; drawer reloads the
  page on auth redirect instead of rendering the login form in the panel
- `DetailDrawerFragmentContractTest` enforces that every `initDetailDrawer`
  consumer ships matching `*-fragment($id).php` + `*-fragment(none).phtml`

Address book list:
- Grid collapses from 9 columns to 4 (identity / context / phone / actions)
  with a two-line identity cell (avatar + name + email)
- Tenant register tabs above the grid using the `app-list-tabs` partial;
  tenant filter wired via hidden toolbar field so grid.js forwards it on
  every data fetch
- Profile body extracted to a shared partial so the full-page view and the
  new drawer fragment share the same markup
- New i18n keys for the drawer/list labels

Also refactors `app-filter-drawer` to reuse the shared focus-trap and
scroll-lock instead of maintaining its own copy, and documents the
detail-drawer convention in CLAUDE.md.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-22 15:22:26 +02:00

144 lines
2.6 KiB
CSS

/* Address book list — dense identity layout */
#address-book-grid .gridjs-tr {
vertical-align: middle;
}
.addr-identity-cell {
display: inline-flex;
align-items: center;
gap: 0.75rem;
min-width: 0;
}
.addr-identity-avatar {
width: 40px;
height: 40px;
flex-shrink: 0;
}
.addr-identity-text {
display: inline-flex;
flex-direction: column;
min-width: 0;
line-height: 1.25;
}
.addr-identity-name {
font-weight: 600;
font-size: 0.95rem;
color: var(--app-color-text, inherit);
text-decoration: none;
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
max-width: 28ch;
}
.addr-identity-name:hover {
text-decoration: underline;
}
.addr-identity-email {
color: var(--app-color-muted, #6b7280);
font-size: 0.82rem;
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
max-width: 28ch;
}
.addr-context-cell {
display: inline-flex;
align-items: center;
gap: 0.35rem;
min-width: 0;
color: var(--app-color-text, inherit);
font-size: 0.88rem;
}
.addr-context-primary {
font-weight: 500;
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
max-width: 20ch;
}
.addr-context-secondary {
color: var(--app-color-muted, #6b7280);
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
max-width: 20ch;
}
.addr-context-separator {
color: var(--app-color-muted, #9ca3af);
flex-shrink: 0;
}
.addr-context-extra {
display: inline-flex;
align-items: center;
justify-content: center;
min-width: 1.75rem;
height: 1.25rem;
padding: 0 0.375rem;
border-radius: 9999px;
background: var(--app-color-subtle, #f3f4f6);
color: var(--app-color-muted, #6b7280);
font-size: 0.72rem;
font-weight: 600;
margin-left: 0.25rem;
flex-shrink: 0;
}
.addr-context-empty,
.addr-phone-empty {
color: var(--app-color-muted, #9ca3af);
}
.addr-phone-cell {
color: var(--app-color-text, inherit);
text-decoration: none;
font-variant-numeric: tabular-nums;
font-size: 0.88rem;
}
.addr-phone-cell:hover {
text-decoration: underline;
}
.addr-action-cell {
display: inline-flex;
gap: 0.25rem;
justify-content: flex-end;
}
.addr-action-button {
display: inline-flex;
align-items: center;
justify-content: center;
width: 2rem;
height: 2rem;
border-radius: 0.375rem;
color: var(--app-color-muted, #6b7280);
text-decoration: none;
transition: background 0.12s, color 0.12s;
}
.addr-action-button:hover {
background: var(--app-color-subtle, #f3f4f6);
color: var(--app-color-text, #111827);
}
@media (max-width: 900px) {
.addr-identity-name,
.addr-identity-email,
.addr-context-primary,
.addr-context-secondary {
max-width: 100%;
}
}