{{end}}
{{/* user-rows renders just the list rows; shared by the full page and the htmx
"load more" fragment so appended pages match the first. The Actions dropdown
loads the Permissions/History fragments into the shared #user-modal. */}}
{{define "user-rows"}}
{{range .Users}}
Joined {{ts .CreatedAt "date"}} · Last login: {{if .LastLoginAt}}{{ts .LastLoginAt "datetime"}}{{else}}never{{end}}
{{end}}
{{end}}
{{/* user-more is the "load more" control; it replaces itself with the next page's
rows + a fresh control. The cursor already carries sort, search, and filter. */}}
{{define "user-more"}}
{{end}}
{{/* users-frag is the htmx response: rows + next control, no page chrome. */}}
{{define "users-frag"}}{{template "user-rows" .}}{{if .NextCursor}}{{template "user-more" .}}{{end}}{{end}}
{{define "content"}}
{{if .Error}}
{{.Error}}
{{end}}
{{/* Search/filters come FIRST in the DOM and move to the right of the list at lg
(order-lg-last). Source order governs both the mobile stack and the tab order,
so ordering with CSS alone would leave keyboard and screen-reader users
traversing every row to reach the control that exists to avoid exactly that. */}}