# TenantPilot Enterprise UI Standards**Status:** Active  **Owner:** Product / Engineering  **Applies to:** TenantPilot custom Filament UI surfaces  **Last reviewed:** 2026-05-03  ---## 1. Purpose and ScopeThis document defines the mandatory UI standards for TenantPilot custom UI surfaces that are not fully covered by native Filament components.TenantPilot is an enterprise SaaS platform for Microsoft Tenant Governance, Evidence, Tenant Reviews, Drift Detection, Baselines, Provider Health, Supportability, and MSP-/Customer-Governance workflows.The UI goal is:- Governance-of-Record- decision-first UX- Filament-native enterprise SaaS look- calm operational surfaces- clear action hierarchy- no false affordances- no fake routes- no fake data- no fake customer-safe maturityThis document applies to:- dashboards- custom cards- page headers- context chips- KPI rows- status cards- aside cards- action rows- governance summaries- evidence and review surfaces- provider health surfaces- supportability surfaces- customer-safe read-only surfaces- empty states- progress/readiness blocks- custom table/list enhancements- custom form/detail layoutsNative Filament components MUST be used first. Custom UI is allowed only when native Filament patterns are insufficient for the product need.---## 2. Non-Negotiable PrinciplesTenantPilot custom UI MUST follow these principles:1. **Decision-first, diagnostics-second, evidence-third.**2. **Filament-native first.**3. **Exactly one visually dominant Primary Action per page.**4. **Status colors belong to badges, labels and chips — not to buttons.**5. **Hover implies interactivity.**6. **Interactive affordance requires a repo-real route/action and permitted capability.**7. **No fake data, fake progress, fake routes or fake customer maturity.**8. **Blade renders. Builders/ViewModels/Presenters decide.**9. **Customer-safe surfaces MUST NOT expose raw technical details by default.**10. **Custom UI MUST use documented patterns, not ad-hoc styles.**Custom UI MUST NOT introduce one-off styling for cards, hovers, buttons, badges, icons, progressbars, empty states or interactive rows.---## 3. Surface TaxonomyTenantPilot uses the following UI surface types.| Surface | Purpose | Example ||---|---|---|| Page Header | Context and primary action | Tenant Dashboard title + Findings prüfen || Context Bar / Context Chips | Lightweight environment context | Workspace, Provider, Latest activity || KPI Row | High-level measurable status | Findings, Operations, Permissions || Decision Card | Recommended next action | Findings prüfen || Status Card | Current posture/readiness | Governance Status || Aside Card | Compact secondary context | Provider Health || Interactive Row | Clickable status or operation row | Governance row with actionUrl || Static Row | Read-only status line | Governance row without actionUrl || Empty State | Honest unavailable state | Kein aktives Review || Progress Block | Real measured progress | 2/3 Findings with outcome || Technical Details | Progressive disclosure only | Logs, JSON, raw payload || Inline Alert | Short contextual warning/info | Missing permissions warning || Table/List Row | Structured list item | Operation runs, findings, reviews || Form Section | Grouped form inputs | Settings section || Detail Section | Read-only structured information | Review metadata |A surface MUST use the matching pattern from this document. Do not treat all surfaces as generic cards.---## 4. Filament-native FirstNative Filament components SHOULD be used whenever possible.Preferred native patterns include:- Filament Pages- Filament Widgets- Filament Stats Overview- Filament Tables- Filament Actions- Filament Badges- Filament Sections- Filament Forms- Filament Infolists- Filament Modals / Slide-overs where appropriateCustom Blade markup MAY be used when:- the desired product surface is not well represented by a native Filament component- a composed dashboard/card pattern is needed- a read-only productized summary is needed- the UI must combine several domain signals into one decision-first surfaceCustom Blade markup MUST still follow this document.---## 5. Page Header PatternThe page header establishes context and action hierarchy.A Page Header SHOULD contain:- title- optional subtitle- optional status pill- exactly one primary action, if a primary action exists- secondary actions grouped or visually de-emphasizedRules:- The Page Header MUST NOT contain a button flood.- The Page Header MUST NOT expose diagnostics as primary actions.- The Page Header MUST NOT show multiple equal-weight primary buttons.- The primary action MUST represent the most important next operator action.- Secondary actions SHOULD be gray/neutral or grouped behind a menu.Example:| Page | Primary Action | Secondary Actions ||---|---|---|| Tenant Dashboard | Findings prüfen | Support anfragen, Support-Diagnostik öffnen || Review Detail | Review fortsetzen / Publish | Export, Evidence anzeigen || Provider Health | Berechtigungen öffnen | Refresh, Details |---## 6. Card and Surface PatternCustom cards MUST use a quiet Filament-like surface.Recommended base:```html<div class="rounded-xl border border-gray-200 bg-white">    ...</div>
Allowed:


bg-white


border border-gray-200


rounded-xl or rounded-2xl


compact, consistent padding


subtle shadow-sm only when the card represents a distinct elevated surface


Not allowed:


hard black borders


dark rings as default card borders


large colored status backgrounds


heavy shadows


unique one-off card treatments per feature


mixing different hover models in equivalent surfaces


Equivalent surface families MUST share the same hover and border model.
For example:
Interactive card row = border + hover:shadow-smStatic card row = border + no hover
Do not mix:
Governance rows = hover:bg-gray-50Recent operations = hover:shadow-sm
unless there is a documented product reason.

7. Interactive Row Pattern
Hover is an affordance. A row MAY only have hover, pointer, focus or shadow interaction when it is actually interactive.
7.1 Interactive Row
Allowed only when all of the following are true:


a repo-real route or action exists


the current user has the required capability/policy


the target is tenant/workspace scoped correctly


the interaction is useful in the product flow


Pattern:


render as <a> if it navigates


render as <button> if it performs an action


use cursor-pointer


use hover:shadow-sm


use focus-visible:ring


include stable data-testid


Interactive rows SHOULD use:
border border-gray-200 bg-white hover:shadow-sm focus-visible:ring
7.2 Static Row
When no route/capability exists:


render as static container


no hover state


no cursor pointer


no focus state


no fake action


no fake route


Static rows MUST NOT look clickable.
7.3 Anti-patterns
Do not introduce:


div with hover but no click target


cursor-pointer without route/action


row looks clickable but only text is shown


fake target route added just to satisfy UI


hover background on static status rows



8. Button and Action Hierarchy
TenantPilot uses a strict action hierarchy.
8.1 Page Primary Action
Each page MAY have at most one visually dominant primary action.
Allowed:


primary color


filled button


page header placement


clear action label


Example:
Tenant Dashboard: Findings prüfen
8.2 Secondary Actions
All card, aside, row and support actions are secondary unless explicitly defined otherwise.
Examples:


Review fortsetzen


Risiken prüfen


Erforderliche Berechtigungen öffnen


Export-Artefakte anzeigen


Backup-Status öffnen


Überfällige Findings öffnen


Required style:


gray/secondary/neutral


no status color


consistent height


consistent radius


consistent typography


consistent padding


8.3 Status Colors and Buttons
Status colors MUST NOT be used as button colors.
Status is represented through:


badge


chip


label


description text


Buttons communicate action hierarchy, not status.
Bad:
Failed = red buttonHealthy = green buttonWarning = yellow button
Good:
Failed = danger badge + gray action buttonHealthy = success badge + gray action buttonWarning = warning badge + gray action button

9. Badge and Status Pattern
Badges communicate state.
Recommended mapping:
MeaningBadge ToneReady / Healthy / Published / CompletesuccessWarning / Stale / Attention / Overdue soonwarningFailed / Error / BlockeddangerUnknown / Unavailable / Not configuredgray
Rules:


badges MUST be small and quiet


status text MUST remain visible


color alone MUST NOT be the only status signal


badges MUST NOT become large colored panels


badges SHOULD NOT be duplicated by additional status icons unless needed for accessibility


buttons MUST NOT inherit badge/status colors


Example:
Provider Health    [Healthy]    0 missing permissions

10. Icon Pattern
Icons improve scanability. They do not replace labels or badges.
Rules:


use Heroicons / Filament-native icons


size SHOULD be 16px / h-4 w-4


color SHOULD be neutral gray


exactly one semantic icon per row/action when used


icon describes type, not status


outcome/status remains in badges


no colorful icon bubbles


no decorative illustrations in operational surfaces


no large circle containers around standard operational icons


Recommended icon mapping:
ConceptIconBaseline Compareheroicon-m-scaleEvidence Coverageheroicon-m-document-checkReviewheroicon-m-clipboard-document-checkProvider Permissionsheroicon-m-keyBackup / Recoveryheroicon-m-arrow-path-rounded-squareInventory Syncheroicon-m-arrow-pathReview Packheroicon-m-document-arrow-downReview Compositionheroicon-m-document-textEvidence Snapshotheroicon-m-document-duplicateProvider Healthheroicon-m-shield-checkPermission Postureheroicon-m-keyFindings / Attentionheroicon-m-shield-exclamationOverdue / Timeheroicon-m-clock
Principle:
Icon = TypeBadge = StatusButton = Action

11. Progress Bar Pattern
Progress bars are only allowed when real numerator/denominator or percent values exist.
Allowed examples:


findings reviewed / total findings


findings with outcome / total findings


completed sections / total sections


evidence attached % only if real numerator/denominator exists


review completion % only if real section/status data exists


Not allowed:


fake percentages


static demo arrays


inferred readiness without real denominator


progress bars for Provider Health unless real progress data exists


progress bars for Risk Exceptions unless real progress data exists


Required:


visible text value remains present


role="progressbar"


aria-valuenow


aria-valuemin="0"


aria-valuemax="100"


percentage must be derived from repo-real values


Visual pattern:


full width


6–8px height


rounded-full


gray track


quiet primary/success/warning fill


no animation by default


Recommended markup shape:
<div class="space-y-1.5">    <div class="flex items-center justify-between gap-3 text-sm">        <span class="text-gray-600">Findings with outcome</span>        <span class="font-medium text-gray-900">2/3 (67%)</span>    </div>    <div        class="w-full overflow-hidden rounded-full bg-gray-100"        style="height: 8px;"    >        <div            class="h-full rounded-full"            style="width: 67%; background-color: var(--primary-500);"            role="progressbar"            aria-valuenow="67"            aria-valuemin="0"            aria-valuemax="100"            aria-valuetext="2/3 (67%)"        ></div>    </div></div>
For custom progress bars, fixed inline height MAY be used when Tailwind height utilities are not reliably present in the loaded Filament theme.

11A. Cross-Domain Indicator Semantics
Indicator-like cues are not interchangeable. A bar, percentage, score, KPI count, status badge, readiness label, health label, risk count, usage/capacity value, or generation-state hint MUST state what it measures and must not borrow execution-progress language unless it measures active execution.

Allowed indicator categories:

- execution progress
- activity state
- coverage
- completion
- health
- readiness
- risk
- pressure
- usage
- capacity
- score
- generation state
- unknown/ambiguous

Rules:

- each indicator gets one primary category at the cue level
- execution progress is only active work progress
- coverage, completion, health, readiness, risk, pressure, usage, capacity, score, and generation state MUST NOT look or read like execution progress
- determinate progress UI requires truthful numerator/denominator or percent values plus visible text and ARIA
- unknown, stale, or missing source truth MUST stay visible and MUST NOT default to calm, ready, healthy, complete, or zero
- scores MUST expose direction, scale, freshness, and source before they are treated as customer-safe or decision-ready
- usage and capacity indicators MUST NOT use success-progress styling unless the copy makes clear that they measure consumption or remaining allowance
- provider-owned health and permission-posture cues remain provider examples; they MUST NOT define platform-core health, readiness, score, or success semantics by default
- dashboard rollups MUST keep execution outcome, data completeness, governance result, lifecycle/readiness, risk pressure, and customer handoff maturity distinct enough for the first operator decision

Forbidden:

- fake percentages or demo progress
- outcome counters reused as progress counters
- provider health, risk, pressure, usage, score, readiness, or generation-state bars with no real denominator
- stale or missing basis shown as current truth
- generic labels such as Progress, Score, Health, Ready, Active, or Complete when the source truth measures something narrower

12. Context Chip Pattern
Context chips provide lightweight environment context.
Examples:


Workspace


Provider / Tenant type


Latest activity


Billing state


Scope


Rules:


chips SHOULD appear below the page header and above the KPI row


chips are not primary actions


chips MUST NOT collapse to 0px


long values SHOULD truncate


mobile MAY wrap


desktop SHOULD remain horizontal where possible


no fake provider labels


provider labels MUST be repo-real or neutral fallback


Allowed provider fallback:
Provider-VerbindungProvider connection
Do not invent:
Microsoft Graph
unless the repo-real provider identity supports it.

13. Dashboard Main / Aside Pattern
TenantPilot dashboards use a decision-first main/aside layout.
Desktop:


Main content: col-span-8


Aside: col-span-4


Mobile:


stacked layout


Main content SHOULD contain:


recommended actions


governance status


primary decision surfaces


recent operational context where appropriate


Aside SHOULD contain:


current review


risk exceptions


provider health


customer-safe output


readiness context


Rules:


aside cards are compact


no long tables in aside


no raw logs/json in aside


each aside card has at most one action


actions inside aside cards are secondary/gray


aside cards must not imply unavailable product maturity



14. Empty State Pattern
Empty states must be honest and action-aware.
Every empty state SHOULD include:


clear title


short explanation


optional next action only if repo-real route and capability exist


Good:
Kein aktives ReviewFür diesen Tenant ist aktuell kein Review in Bearbeitung.
Good:
Keine kundensichere Ausgabe verfügbarErzeuge ein Review-Paket, sobald Evidence und Review bereit sind.
Bad:
Kunden-Workspace öffnen
when no customer-safe workspace is repo-verified.
Rules:


no fake CTA


no implied product maturity


no placeholder/demo content


no customer-safe claim without repo verification


no action without route and capability



15. Loading, Stale and Error States
15.1 Loading
Loading states SHOULD use:


skeleton


quiet placeholder


short loading text when needed


Avoid:


spinner spam


layout shifting


blocking entire dashboard unless necessary


15.2 Stale
Stale states SHOULD show:


badge or label


reason if available


last refreshed/checked timestamp when repo-real


Stale states MUST NOT use alarming surfaces unless operator action is required.
15.3 Error
Error states SHOULD show:


reason


impact


next action if available


Technical details MUST remain behind progressive disclosure.
Never default to:


raw exception


JSON payload


stack trace


logs


raw API response



16. Table and List Pattern
Tables should remain Filament-native unless there is a strong product reason.
Rules:


row hover only if row click is enabled


otherwise use explicit row action


status columns use badges


raw IDs hidden by default


technical columns behind toggle or detail view


destructive actions are never primary


no button flood in each row


no raw technical fields as default operator experience


TenantPilot tables SHOULD support decision-first scanning:


status


reason


impact


owner/scope


next action


details only on demand


Anti-pattern:
Operator must inspect raw IDs, payloads and logs to understand what matters.

17. Form and Detail Page Pattern
17.1 Forms
Forms SHOULD:


group fields into sections


use clear section titles


keep primary save/submit action consistent


separate destructive actions


hide advanced/technical fields behind collapsible sections where appropriate


Forms MUST NOT:


expose raw internal fields as primary inputs unless needed


mix destructive and primary actions at equal visual weight


rely on placeholder text as the only explanation


17.2 Detail Pages
Detail pages SHOULD:


be read-first


show status/reason/impact before technical details


use progressive disclosure for diagnostics


avoid looking like edit forms when read-only


Technical details SHOULD be grouped under:
Technical DetailsDiagnosticsRaw Details
and collapsed or secondary by default.

18. Customer-safe Surface Rules
Customer-safe surfaces must be read-only, calm and evidence-first.
Rules:


no raw technical logs by default


no internal operation noise by default


no admin-only actions


no unsupported maturity claims


no Open customer workspace unless Customer Review Workspace is repo-verified


use Export-Artefakte anzeigen or Review-Paket öffnen when only artifacts/packs exist


customer-safe copy must be especially precise


customer-safe output must distinguish between:


Review Pack


Evidence Snapshot


Export Artifact


Customer Workspace




Do not label the whole customer-safe output as failed if only the latest export/review-pack generation failed.
Prefer precise copy:
Review-Paket fehlgeschlagenExport fehlgeschlagenKeine kundensichere Ausgabe verfügbar

19. Component Ownership Rules
Business logic belongs in:


SummaryBuilder


ViewModel


Presenter


Link service


Policy/capability layer


domain service


Blade may:


render fields


branch on explicit view model flags


render provided URLs/icons/badges/progress values


Blade MUST NOT:


invent routes


infer capabilities


calculate business status


hardcode provider maturity


calculate fake progress


infer customer-safe maturity


parse raw payloads for product decisions


duplicate business logic from services/builders


Preferred flow:
Domain model/service→ SummaryBuilder/ViewModel/Presenter→ Blade render
Not allowed:
Blade template→ queries database→ invents status→ decides capability→ renders action

20. Localization Rules
Visible UI copy MUST use localization keys.
Rules:


no new hardcoded user-facing copy in Blade


DE/EN mixture is accepted only as explicit Localization v1 debt


customer-facing copy must be especially careful


labels must not overclaim product maturity


status labels should use shared badge/status language where possible


Until Localization v1 is complete:


mixed language may exist in operator-only surfaces


new copy should still be added through localization files


PR/close-out notes SHOULD mention known localization debt when relevant



21. Accessibility and Keyboard Rules
Custom interactive UI MUST be accessible.
Rules:


clickable navigation uses <a>


actions use <button> or Filament Action components


do not use clickable div without semantics


focus-visible style required for custom interactive elements


icon-only buttons require accessible label


color alone must not communicate status


progress bars require ARIA attributes


keyboard navigation must not be broken


Required for progress bars:
role="progressbar"aria-valuenow="..."aria-valuemin="0"aria-valuemax="100"
Required for icon-only actions:
aria-label="..."
or visible text.

22. Responsive, Truncation and Overflow Rules
Custom UI MUST remain stable on desktop and mobile.
Rules:


desktop dashboards may use main/aside grid


mobile stacks main and aside


chips may wrap on mobile


chips must not overlap


long names must truncate


no 0px grid columns


no horizontal scroll leaks


cards must not collapse due to long tenant/workspace/provider names


actions must remain visible and usable on mobile


Recommended:
truncate long labelsuse minmax() carefullytest actual browser widthavoid fixed widths unless intentional
Every dashboard-like custom surface SHOULD be checked in:


desktop viewport


narrow/mobile viewport


long tenant/workspace name scenario where practical



23. Data Freshness Rules
Governance, Evidence, Review and Provider statements SHOULD show freshness when repo-real freshness exists.
Examples:


Last checked 20 minutes ago


Last snapshot 2 days ago


Latest activity 5 minutes ago


Likely stale


No recent signal


Rules:


stale data must not be presented as fresh


stale state should be quiet unless action is required


freshness belongs in badge/description/context, not aggressive layout


no fake timestamps


no generic “synced recently” without a real timestamp



24. Raw Technical Details and Progressive Disclosure
TenantPilot is not a raw admin mirror.
Default surfaces MUST NOT show:


raw JSON


raw logs


stack traces


internal IDs


raw API payloads


technical exception details


provider-specific debug output


These MAY be available under:


Technical Details


Diagnostics


Raw Payload


Operation Log


Developer / Support view


Decision-first default:
StatusReasonImpactNext Action
Then:
EvidenceDiagnosticsRaw Details

25. Data-testid and Browser-Smoke Rules
Custom UI surfaces SHOULD use stable data-testid attributes.
Rules:


test product concepts, not styling implementation


avoid fragile assertions on Tailwind class order


avoid assertions on SVG attribute order


use browser smoke for layout-critical surfaces


use feature tests for capability/action visibility


use markup tests for stable structural contracts


do not assert exact class ordering unless explicitly testing a UI contract


Examples:
tenant-dashboard-governance-statustenant-dashboard-secondary-actiontenant-dashboard-current-review-progresstenant-dashboard-context-chipstenant-dashboard-recommended-actiontenant-dashboard-recent-operation
Browser-smoke SHOULD verify:


page loads


key sections render


critical layout does not collapse


important actions are visible/hidden correctly


no false interactive affordance where known


Browser-smoke SHOULD NOT rely on:


theme CSS being loaded in unit-test-only contexts


exact Tailwind class order


fragile screenshot pixel matching unless explicitly required



26. UI Review Checklist
Before merging custom UI changes:


 Filament-native component was used where possible.


 Custom styling follows this standard.


 Exactly one visually dominant Primary Action exists on the page.


 Card actions are secondary/gray.


 Status colors are only used in badges/chips/labels.


 Hover exists only on interactive elements.


 Every interactive element has a repo-real route/action.


 Capabilities/policies are respected.


 Tenant/workspace scope is respected.


 No fake routes were introduced.


 No fake actions were introduced.


 No fake progress or demo values were introduced.


 Empty states are honest.


 Customer-safe maturity is not overclaimed.


 Raw JSON/logs are not shown by default.


 Icons are small, neutral and semantic.


 Progressbars include accessible attributes.


 Mobile layout does not overlap or collapse.


 Long labels truncate or wrap safely.


 Browser smoke was run or explicitly documented as not run.


 New visible copy uses localization keys.


 Blade does not invent domain logic, routes, capabilities or maturity.



27. Anti-Patterns
Do not introduce:


hover without clickability


cursor-pointer without route/action


primary buttons inside cards


status-colored buttons


fake customer workspace actions


fake provider names


fake progress bars


static demo chart arrays


raw JSON/logs as default


technical table sprawl


new top-level page for every technical state


custom one-off card styles


mixed hover models in the same surface family


icon-only status without text


large colored status panels


decorative icon bubbles in operational UI


route guessing in Blade


capability guessing in Blade


customer-safe maturity overclaims


provider-specific hardcoding in platform core unless repo-real and scoped


destructive actions with primary visual weight


button floods in page headers or table rows



28. Pattern Decision Matrix
Use this matrix when choosing a pattern.
NeedUseDo Not UseShow statusBadge / chip / labelButton colorShow actionButton / link / Filament ActionBadgeShow typeSmall neutral iconColored status iconShow progressProgress bar with real denominatorFake percentShow unavailable stateEmpty stateDisabled fake CTANavigate row<a> row with hover/focusdiv hoverStatic informationStatic row/cardHover rowShow detailsProgressive disclosureRaw details by defaultCustomer outputReview Pack / Export Artifact wordingCustomer Workspace wording unless repo-real

29. TenantPilot-specific Product Guardrails
TenantPilot MUST avoid drifting into:


generic M365 admin mirror


helpdesk tool


raw device-action tool


debug surface collection


log viewer as primary UX


feature-per-page sprawl


TenantPilot SHOULD reinforce:


Governance-of-Record


OperationRun truth


Evidence-first reporting


capability-first RBAC


workspace-first multi-tenancy


customer-safe review consumption


decision-first surfaces


provider-extensible architecture


UI copy and actions MUST NOT claim a product capability is mature unless repo-verified.
Examples:
CapabilityAllowed CopyAvoidReview Pack existsReview-Paket öffnenKunden-Workspace öffnenExport artifact existsExport-Artefakte anzeigenCustomer Portal öffnenEvidence existsNachweise anzeigenAudit abgeschlossenProvider permissions missingBerechtigungen öffnenFix automaticallyCustomer Review Workspace not implementedKundensichere Ausgabe nicht verfügbarOpen customer workspace

29.1 OperationRun Activity Feedback Pattern
The tenant-shell OperationRun activity hint is a bounded start-surface hint, not a second monitoring page.

It MUST:

derive rows from existing OperationRun truth only

show queued or running rows plus only the bounded terminal states that complete the same-shell feedback loop:

- just-completed successful runs that remain visible briefly
- unresolved terminal follow-up runs that were blocked, partial, failed, or automatically reconciled

render inside the TenantPilot application shell, directly below the topbar/context bar or inside the main content shell as a compact in-flow banner

stay in-flow and non-obstructive instead of floating over row actions or page CTAs

show at most three items in the shell

keep the visible shell order deterministic by using the existing shell ordering contract:

- active queued or running rows first
- unresolved terminal follow-up rows next
- recent terminal success rows only as the bounded close-the-loop state

use one grouped banner action area with a dominant action that reflects whether the banner is about one operation or multiple operation updates:

- when exactly one visible operation update is shown, use View operation to open that run detail
- when multiple visible operation updates are shown, use Review operations to open the canonical Operations collection instead of any single run detail

use Active operations as the header label only when all visible rows are active queued or running work. If any visible row is terminal, switch the header label to Operation updates.

keep a secondary action labeled Show all operations and one lifecycle-sensitive tertiary affordance for the current browser session:

- Hide activity for queued or running rows
- Dismiss or Close for terminal-success rows
- Acknowledge for unresolved terminal follow-up rows, including grouped states

use Show all operations to open the canonical Operations collection with the current tenant encoded as the contextual tenant_id prefilter

keep overflow copy collective and calm, for example 19 more operation updates available in Operations.

show at most one concise next-step cue per item and leave diagnostics, logs, raw payloads, and failure detail to the canonical Operations pages

show determinate progress only when summary_counts.total and summary_counts.processed are real numeric values, clamp the progressbar to 0-100, and only show processed or percentage text when it is derived from those repo-real values

derive progress treatment from one shared OperationRun progress contract instead of local Blade or widget math

allow counted progress only for current run families that persist truthful summary_counts.total plus summary_counts.processed during execution:

- inventory sync
- review-pack generation
- evidence-snapshot generation
- backup-set policy additions
- backup-set bulk restore

keep all other run families on activity-only, phased, or composite treatment until they persist equally trustworthy progress truth through the shared contract

limit the current non-counted phase or composite contract to these run families only:

- baseline_capture
- baseline_compare
- tenant.review.compose

keep queued rows activity-only even when a planned total exists

keep running rows without trustworthy processed and total counts activity-only or indeterminate

keep summary_counts.succeeded, summary_counts.failed, and summary_counts.skipped outcome-only; they must not silently replace processed as progress truth

for baseline_capture and baseline_compare, use canonical progress.phase metadata with short operator-safe, non-technical labels such as Preparing baseline capture., Capturing evidence., Refreshing comparison evidence., Evaluating baseline drift., Saving baseline snapshot., and Finalizing baseline comparison.

for tenant.review.compose, use canonical progress.composite metadata only for bounded aggregate status copy such as Review composition is aggregating 3 operations.; this remains composite indeterminate copy, not counted progress, even when operation_count is visible

when canonical phase or composite metadata is absent or malformed, degrade safely to the existing generic phased or composite fallback instead of inventing percentages, strategy detail, provider detail, or raw technical diagnostics in the shell

switch terminal-success rows to success-state copy instead of showing active progress after completion

separate successful completion from unresolved terminal follow-up in the shell helper copy:

- successful terminal rows use no-action-needed completion copy and remain locally dismissible
- unresolved terminal follow-up rows use review-needed copy and MUST NOT inherit generic Dismiss semantics

keep hide, dismiss, or acknowledge behavior browser-session-only and re-open the hint when a new run-enqueued event is accepted for the current tenant

record these as follow-up work instead of widening the current contract:

- provider health or support-diagnostics progress rollout
- review-pack or evidence-snapshot overlap with other progress specs
- child-run graph persistence or composite child-link expansion
- dashboard cards or workflow-engine generated progress explanations

It MUST NOT:

render as a detached document-level BODY_START banner above the TenantPilot application chrome

turn the shell hint into a permanent terminal inbox, tray, or second monitoring page

use raw route strings or non-canonical OperationRun links

show fake percentages, guessed completion, or fake progress

let outcome counters, aggregate operation counts, or phase hints masquerade as counted progress

show active progress UI after a run is already terminal

persist hide or dismiss state in the database or on the OperationRun record

persist acknowledge state in the database or on the OperationRun record

render as a fixed overlay that can cover findings row actions, table actions, or page-primary actions

30. Maintenance Rules
This document is a living standard.
Changes to this document SHOULD happen when:


a repeated UI decision appears in multiple specs


a new custom pattern is introduced


a drift issue is found during browser smoke


a Filament-native alternative becomes available


Localization v1 changes copy rules


Customer Review Workspace v1 changes customer-safe surface rules


Feature specs SHOULD NOT override this document casually.
Any intentional exception SHOULD document:


affected surface


reason for exception


expected duration


follow-up cleanup if needed



31. Minimal Constitution Reference
The project constitution SHOULD reference this document with a short rule, not duplicate the full standard.
Recommended constitution text:
### Custom Filament UITenantPilot custom Filament UI MUST follow `docs/ui/tenantpilot-enterprise-ui-standards.md`.Feature specs MUST NOT introduce ad-hoc card, hover, button, badge, icon, progressbar, empty-state or interactive-row styling.Interactive affordance MUST only be used when a repo-real route/action and permitted capability exist.Status colors MUST be represented through badges, chips or labels, not through action buttons.Customer-safe maturity MUST NOT be implied by copy, routes or actions unless repo-verified.

32. Spec / PR Close-out Reference
Visible custom UI changes SHOULD include a short close-out note.
Recommended format:
## UI Standards CheckChanged custom UI surfaces:- ...Patterns used:- Card / Surface- Interactive Row- Secondary Action- Progress Bar- Empty StateConfirmed:- [ ] Filament-native used where possible- [ ] No ad-hoc styling- [ ] No fake data/routes/progress- [ ] Capabilities respected- [ ] Browser smoke run- [ ] Localization debt documented if applicable

33. Quick Reference
Buttons
Page primary action = primary filledCard action = gray/secondaryAside action = gray/secondaryStatus = badge, not button color
Rows
Interactive row = route + capability + hover/focusStatic row = no hover, no pointer
Icons
SmallNeutralOne per row/actionType, not status
Progress
Only real numerator/denominator/percentText value remains visibleARIA requiredNo fake progress
Customer-safe
Do not imply Customer Review Workspace maturity unless repo-verifiedUse Review Pack / Export Artifact wording when that is what exists
Blade
Render onlyDo not invent domain logicDo not invent routesDo not infer capabilities
