30 KiB
TenantPilot Enterprise UI StandardsStatus: 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 ...
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.
- 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 if it navigates
render as 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
- 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
- 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
- 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
- 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:
- 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.
- 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
- 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
- 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
- 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.
- 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.
- 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
- 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
- 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
- Accessibility and Keyboard Rules Custom interactive UI MUST be accessible. Rules:
clickable navigation uses
actions use
or Filament Action componentsdo 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.
- 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
- 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
- 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
- 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
- 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.
- 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
-
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 row with hover/focusdiv hoverStatic informationStatic row/cardHover rowShow detailsProgressive disclosureRaw details by defaultCustomer outputReview Pack / Export Artifact wordingCustomer Workspace wording unless repo-real
-
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
- Dismiss for a single unresolved terminal follow-up row
- Dismiss updates when multiple unresolved terminal follow-up rows are visible and no active work remains
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
switch terminal-success rows to success-state copy instead of showing active progress after completion
keep hide or dismiss behavior browser-session-only and re-open the hint when a new run-enqueued event is accepted for the current tenant
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
show active progress UI after a run is already terminal
persist hide or dismiss 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
- 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
- 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.
- 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
- 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