The card tested `p.api_key` on a DTO that has never carried it, so the badge
was falsy for every provider and always read "API key missing".
The list and the new detail DTO now expose `has_api_key: bool` — the key
value itself never reaches the browser, where the edit form used to prefill
it in plain text. Since the form can no longer send the stored key back, an
empty `api_key` on update means "keep the one on file" instead of erasing it,
which is what the field's placeholder already promised.
Every full-page view now renders the same sticky top bar (back button,
title, right-side actions) from the new web/css/page-header.css,
replacing a dozen per-page duplicates (.page-panel-header,
.project-page-header, .task-page-header, .llm-page-header, .um-header,
.apr-header, .llmr-header, .pv-header, .sa-header, .config-page-header,
.agents-page-header). Pages that padded the whole container (config,
agents, system-agents, llm-requests, models-hub) move that padding into
a body wrapper so the bar sits flush and stays pinned on scroll.
Back buttons are standardized to the icon-only .page-header-back.