feat: apply AppFoundation Screens design to the Identity UI#82
Merged
Conversation
Import the "AppFoundation Screens" Claude Design project and use it as the target design for the Blazor Identity UI and the Aspire sample host. - Add a design-token stylesheet that remaps Radzen's --rz-* variables onto the emerald AppFoundation palette, with matching light + dark themes and Manrope / Space Grotesk / JetBrains Mono fonts (RCL wwwroot). - Add a no-flash theme switcher (auto/light/dark) persisted to localStorage. - Rebuild LoginLayout as the centered login card; restyle the Login heading. - Replace the sample host header with the AppFoundation app shell: sidebar nav (Home, Account, role-gated Administration), topbar page title, theme toggle and user chip. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Bring every login-card auth screen in line with the updated AppFoundation Screens design (heading + subtitle, label-above full-width fields, stacked full-width sentence-case buttons, centered footer link): - Login: inline forgot-password on the password row, outline passkey button, "Don't have an account? Create account" / "Resend confirmation" footer. - Register, Forgot password, Resend confirmation, Two-factor, Recovery code: vertical label/field layout, heading + subtitle, and a centered footer link back to log in (or to the alternate 2FA method). - appfoundation.css: login form/control/button rules and an outline passkey variant targeted via data-af. - Update the LoginTests register-link constant to the new "Create account" copy. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
The library's Login/LoginForm pages don't self-declare a render mode but require interactivity: SignInHandoff performs the cookie handoff to /login in OnAfterRenderAsync (JS), and the Radzen "Remember me" checkbox only binds interactively. The sample rendered <Routes> statically, so sign-in silently failed (fields cleared, no cookie) and Remember me was always false. - App.razor: apply global InteractiveServer render mode to <HeadOutlet> and <Routes>. RCL pages that redeclare the same mode coexist fine (verified). - Home.razor: also serve /dashboard, the cookie middleware's DefaultRedirect after a no-ReturnUrl login, so a successful sign-in no longer 404s. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
…lationToken in RoleStore - Relocate the identity feature-flag types (IdentityFeature, IdentityFeatureFlags, IIdentityFeatureProvider, OptionsIdentityFeatureProvider, the gate middleware and its app-builder extension) into the AndreGoepel.Marten.Identity.Blazor.Features namespace, updating Login.razor, Initialization, MartenIdentityBlazorOptions and the affected tests accordingly. - RoleStore: pass the ambient CancellationToken into GetCurrentUserIdAsync on the create/change/delete/restore paths instead of dropping it. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
UseMartenIdentityFeatureGate moved to the .Features namespace; add the matching using so the Aspire sample compiles. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Replace Radzen's floating-label RadzenFormField (watermark that jumps to the top line) with a static RadzenLabel above each field, and unwrap the RadzenFieldset groupings, so the account and admin forms match the flat AppFoundation card design used by the login screens. Covers Profile, Manage Email, Change Password, Set Password, Enable Authenticator, Two-Factor, Rename Passkey, Delete Personal Data, and the admin User Cleanup page. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
andregoepel
force-pushed
the
feat/appfoundation-theme
branch
from
July 6, 2026 07:48
8a61358 to
79d0a5f
Compare
Verified in the running Aspire sample against the AppFoundation design:
- Suppress the focus ring Blazor's FocusOnNavigate paints on page headings
(the stray box around each card title).
- Global sentence-case buttons (Radzen's Material theme upper-cased them).
- Card footer actions: a bordered, natural-width action row (af-card-actions),
right-aligned for forms and left-aligned for Personal Data — replacing the
centered / full-width button stacks on Profile, Change Password, Manage Email,
Set Password, Enable Authenticator, Delete Personal Data, Rename Passkey,
Personal Data, and User Cleanup.
- Soften Radzen's filled alerts into the design's tinted banners (correct
.rz-alert.rz-{info,warning,danger,success} selectors); the 2FA "disabled"
notice now uses the amber warning tone.
- Two-Factor: fieldset replaced by a flat sub-heading, and the lone action
button no longer stretches full width (af-actions-inline).
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Three design-detail refinements verified in the running sample: - Manage Email: show a "✓ Confirmed" status pill beside the current-email field instead of plain green text. - Change Password: lay New password / Confirm new password out in a two-column grid (collapses to one column on narrow viewports). - Roles grid: replace the plain Deleted True/False column with a Status badge (Active / Deleted). Adds shared .af-badge / .af-form-grid styles. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
…tables Addresses design-review feedback, verified in the running sample: - Buttons: force the dark on-accent text colour (Radzen forced white in dark mode); tighten to the design's 13px. Labels are now 12.5px / 600 / muted globally, not just inside the login card. - Theme toggle: reorder to light / auto / dark with crisp sun / monitor / moon SVG icons to match the design pill. - Two-Factor: move the status banner outside (above) the card. - Passkeys: move the register action into the page header (top-right) and use a dashed empty-state card instead of an info alert. - Personal Data: buttons pick up the dark on-accent text and danger-soft styling. - Users / Roles grids: merge the id under the name/email (mono, muted), add Status / Confirmed badges, drop the per-column filter funnels, and uppercase the column headers. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
…ow menu Further design-review fixes, verified in the running sample (dark mode): - Disabled/read-only inputs now read as greyed out (hover bg, muted text) — define --rz-input-disabled-background and style .rz-textbox[readonly]. - Danger buttons use the design's danger-soft tint + red text (Radzen's filled danger forced a solid red; overridden with !important). - Data-grid row hover uses the dark --af-hover (Radzen's white grid-hover var broke dark mode); grids fill the card and no longer overflow horizontally (auto table layout, id truncated with ellipsis). - Users / Roles actions: keep the primary action (Users / Roles) visible and move Delete / Restore behind a compact "⋯" overflow menu (ContextMenuService); rows are no longer selectable. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Add DESIGN.md documenting how to build components that fit the AppFoundation theme — tokens, typography, page/form/card/table/alert recipes, the af-* helper classes, and the Radzen overrides to be aware of — and link it from the Blazor project README. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
- Alerts: tint the icon to the status colour (was white), shrink it, and set the banner text to 13px — matching the design's tinted banners. - Two-Factor: the "Authenticator app" description now uses the muted secondary colour instead of the bright body colour. - Sample sidebar: rename account nav items to the design's labels (Email, Password, Two-factor authentication, Personal data). - DESIGN.md: document the muted-description and alert-icon conventions. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
- Sidebar brand now shows the configured application name (AppName config, default "Marten Identity") and its initial, instead of a hard-coded label; footer follows suit. - Topbar shows a Section / Page breadcrumb derived from the current route (e.g. "Account / Email") instead of a static title. - Row overflow (⋯) menus: dark, readable hover (Radzen's default was a white block that erased the text in dark mode), and the Delete item now has a trash icon and the danger red colour (icon + text). Restore gets a restore icon. - Sample: add AppName to appsettings; sentence-case the "User cleanup" nav item. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Radzen fills the sharp-cornered menu-item wrapper near-white on hover, which showed through the four rounded corners of the dark item highlight. Force the wrapper/item hover background transparent so only the rounded --af-hover link shows. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
- Override Radzen's compact-density cells (4px/8px) with the design's roomier padding — 12px 20px headers, 13px 20px rows — so cell text has breathing room in the Users/Roles grids. - Render .af-badge as inline-flex so its padding and rounded corners show as a clean pill instead of a cramped inline box. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
- Users/Roles grids: add the design's in-card toolbar — a live filter box (client-side, matches name/email or id) and an "X of Y" row count. - User Cleanup: narrow the retention (140px) and cron (240px, monospace) inputs to match the design, and render "Next scheduled run" as a soft info box (af-info-box) instead of plain text. - DESIGN.md: document the new toolbar and info-box helper classes. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Translate the design's isCompact/isMobile behaviour into real CSS media queries plus a tiny toggle script: - <=1000px: the sidebar becomes a fixed off-canvas drawer toggled by a topbar hamburger, with a dimming backdrop. State is data-nav-open on .af-shell, flipped by appfoundation-nav.js (also closes on Escape / after a nav link). - <=700px: tighter padding, the user email is hidden, af-form-grid collapses to one column, and data grids get a min-width + horizontal scroll. Adds appfoundation-nav.js, the hamburger/backdrop to the sample MainLayout, and documents the breakpoints in DESIGN.md. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Wrap the long RoleDeleted/RoleRestored constructor calls so `dotnet csharpier check .` (the CI format gate) passes. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
andregoepel
added a commit
that referenced
this pull request
Jul 6, 2026
Address the PR #82 review comments on the AppFoundation shell: - Breadcrumb is now defined per page, not by a central route→label map. Add a cascading BreadcrumbState (owned by the shell layout) and an optional Breadcrumb parameter on IdentityPageTitle; each shell page declares its own crumb. Drops the 15-entry dictionary + Breadcrumb()/Humanize() from MainLayout. EnableAuthenticator gains a document title it was missing. - Theme-toggle SVGs move out of ThemeToggle into a reusable AppIcon component (<AppIcon Name="sun" />); adding a glyph is one dictionary entry. - Fonts are self-hosted: vendor Manrope / Space Grotesk / JetBrains Mono (latin + latin-ext variable woff2) into the RCL wwwroot with a generated fonts.css, and load that instead of fonts.googleapis.com. Nothing is fetched from Google at runtime (GDPR / offline / reliability). Regenerate via scripts/fetch-fonts.py. DESIGN.md documents all three.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Imports the AppFoundation Screens Claude Design project and applies it as the target design across the Blazor Identity UI and the Aspire sample host. Because the app is built on Radzen, the theme is applied by remapping Radzen's
--rz-*variables onto the AppFoundation emerald palette rather than rewriting each component; distinctive screens get bespoke markup.What's included
Theme foundation
wwwroot/css/appfoundation.css— light + dark tokens, Radzen variable remap, Manrope / Space Grotesk / JetBrains Mono fonts, plus shell/login/control classes.wwwroot/js/appfoundation-theme.js— no-flash auto/light/dark switch persisted tolocalStorage.App shell (Aspire sample)
ACCOUNTnav, role-gatedADMINISTRATIONnav, topbar with theme toggle and user chip.Auth screens (login card)
LoginLayoutrebuilt as the centered login card.Account & admin forms
RadzenFormField(the watermark that jumps to the top line) with a staticRadzenLabelabove each field, and unwrappedRadzenFieldsetgroupings, so Profile, Manage Email, Change Password, Set Password, Enable Authenticator, Two-Factor, Rename Passkey, Delete Personal Data, and User Cleanup match the flat card design.Verification
Notes
mainafter the Aspire sample (feat: add .NET Aspire sample hosting the Marten Identity stack #81) and feature flags (feat: feature flags for registration, 2FA and passkeys (#66) #79) merged.ResetPasswordstill renders in the app shell rather than the login card; moving it ontoLoginLayoutfor consistency can be a follow-up.🤖 Generated with Claude Code