Skip to content

feat(ui): redesign login page with brand identity#115

Merged
appleboy merged 4 commits intomainfrom
feat/login-ui-redesign
Mar 21, 2026
Merged

feat(ui): redesign login page with brand identity#115
appleboy merged 4 commits intomainfrom
feat/login-ui-redesign

Conversation

@appleboy
Copy link
Copy Markdown
Member

Summary

  • Replace generic "Welcome Back" / "Sign in to your account" copy with AuthGate brand identity: shield-with-lock SVG icon, product name as title, "Sign in to continue" subtitle, and "Secure Authentication" monospace badge
  • Restyle login title in brand blue at refined font size to match navbar brand treatment
  • Add dark mode overrides for new elements (brand icon gradient, security label border/bg, card shadow glow)
  • Add responsive sizing (60px icon on mobile) and reduced-motion accessibility support

Test plan

  • Run make generate && make lint && make test — all pass
  • Visual check login page in light mode — shield icon, brand title, security badge render correctly
  • Visual check login page in dark mode — icon gradient, label border, and card shadow adapt properly
  • Test on mobile viewport (≤640px) — icon scales down, title uses smaller font
  • Verify prefers-reduced-motion disables icon animation
  • Verify OAuth provider buttons and form functionality unchanged

🤖 Generated with Claude Code

- Replace generic "Welcome Back" with AuthGate brand name and shield icon
- Add "Secure Authentication" monospace badge to reinforce security identity
- Style title in brand blue and refine font sizing for professional tone
- Add dark mode overrides for brand icon, security label, and card shadow
- Add responsive and reduced-motion support for new elements

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Copilot AI review requested due to automatic review settings March 21, 2026 02:08
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Redesigns the login page header to match AuthGate’s brand identity (icon, title, subtitle, security badge) while updating responsive behavior and dark-mode styling to keep the new elements visually consistent across themes.

Changes:

  • Update login header markup to use a brand icon, “AuthGate” title, “Sign in to continue” subtitle, and a “Secure Authentication” label.
  • Adjust login page CSS for the new header elements, including responsive sizing and reduced-motion handling.
  • Add dark-mode overrides for the new brand icon, security label, and login card shadow.

Reviewed changes

Copilot reviewed 3 out of 3 changed files in this pull request and generated 3 comments.

File Description
internal/templates/static/css/pages/login.css Adds styles for the new brand icon and security label; tweaks title sizing/color; updates responsive and reduced-motion rules.
internal/templates/static/css/components/dark-mode.css Adds dark-mode overrides for the new login header elements and card shadow.
internal/templates/login_page.templ Updates login header markup and copy to the new branded layout.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment on lines +95 to +107
.login-brand-icon {
display: flex;
align-items: center;
justify-content: center;
width: 72px;
height: 72px;
margin: 0 auto var(--space-5);
border-radius: var(--radius-xl);
background: linear-gradient(135deg, var(--color-primary-pale), #dbeafe);
border: 1px solid rgba(0, 114, 255, 0.15);
color: var(--color-primary);
animation: scaleIn 0.6s cubic-bezier(0.34, 1.56, 0.64, 1) 0.3s both;
}
Copy link

Copilot AI Mar 21, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

.login-brand-icon uses animation: scaleIn ..., but @keyframes scaleIn is not defined in this stylesheet. It currently works only because main.css happens to import components/alerts.css (which defines scaleIn) before pages/login.css, creating a hidden cross-file dependency. Consider defining @keyframes scaleIn in login.css (or moving it to a shared/global animations stylesheet) so this page doesn't rely on unrelated component CSS for its animation keyframes.

Copilot uses AI. Check for mistakes.
Comment on lines 506 to 517
@media (prefers-reduced-motion: reduce) {
.login-card,
.login-header,
.login-oauth-section,
.login-divider,
.login-form,
.login-oauth-btn,
.login-submit-btn {
.login-submit-btn,
.login-brand-icon {
animation: none !important;
transition: none !important;
}
Copy link

Copilot AI Mar 21, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The prefers-reduced-motion block disables animations/transitions on several elements, but animations/transitions declared on pseudo-elements (e.g., .login-card::before/::after animations and .login-oauth-btn::before transition) will still run because these properties do not inherit. If the goal is to respect reduced-motion settings, explicitly disable animations/transitions on the relevant pseudo-elements as well.

Copilot uses AI. Check for mistakes.
Comment on lines +14 to +21
<div class="login-brand-icon" aria-hidden="true">
<svg width="48" height="48" viewBox="0 0 48 48" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M24 4L6 12V22C6 33.1 13.68 43.38 24 46C34.32 43.38 42 33.1 42 22V12L24 4Z" stroke="currentColor" stroke-width="2.5" fill="none"></path>
<rect x="20" y="19" width="8" height="10" rx="1.5" stroke="currentColor" stroke-width="2"></rect>
<path d="M18 19V16C18 12.69 20.69 10 24 10C27.31 10 30 12.69 30 16V19" stroke="currentColor" stroke-width="2" stroke-linecap="round"></path>
<circle cx="24" cy="24" r="1.5" fill="currentColor"></circle>
<line x1="24" y1="25.5" x2="24" y2="27.5" stroke="currentColor" stroke-width="1.5" stroke-linecap="round"></line>
</svg>
Copy link

Copilot AI Mar 21, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The decorative inline SVG inside .login-brand-icon is wrapped in an aria-hidden="true" container, but the <svg> itself is missing focusable="false". In some browsers this can still create an unexpected keyboard tab stop. Consider adding focusable="false" (and optionally aria-hidden="true") directly on the <svg> to ensure it is fully non-interactive.

Copilot uses AI. Check for mistakes.
- Add focusable="false" and aria-hidden="true" to SVG to prevent keyboard tab stop
- Define loginScaleIn keyframe locally to avoid hidden cross-file dependency on alerts.css
- Disable animations/transitions on pseudo-elements in prefers-reduced-motion

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 3 out of 3 changed files in this pull request and generated 3 comments.


💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment on lines +346 to +362
/* Login brand icon — hardcoded #dbeafe and rgba(0,114,255) won't adapt in dark mode */
[data-theme="dark"] .login-brand-icon {
background: linear-gradient(135deg, var(--color-primary-pale), rgba(88, 166, 255, 0.12));
border-color: rgba(88, 166, 255, 0.2);
}

/* Login security label — hardcoded rgba(0,114,255) border/bg won't adapt in dark mode */
[data-theme="dark"] .login-security-label {
border-color: rgba(88, 166, 255, 0.25);
background: rgba(88, 166, 255, 0.06);
}

/* Login card shadow — hardcoded rgba(0,114,255) glow is too bright on dark backgrounds */
[data-theme="dark"] .login-card {
box-shadow:
0 20px 50px -12px rgba(88, 166, 255, 0.08),
0 0 0 1px rgba(88, 166, 255, 0.1);
Copy link

Copilot AI Mar 21, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Same issue here: the label uses hard-coded rgba(88, 166, 255, …) values that duplicate the theme’s --color-primary for dark mode. Consider using a shared variable for the RGB value (or another theme token) to avoid future drift if the brand color is updated.

Suggested change
/* Login brand icon — hardcoded #dbeafe and rgba(0,114,255) won't adapt in dark mode */
[data-theme="dark"] .login-brand-icon {
background: linear-gradient(135deg, var(--color-primary-pale), rgba(88, 166, 255, 0.12));
border-color: rgba(88, 166, 255, 0.2);
}
/* Login security label — hardcoded rgba(0,114,255) border/bg won't adapt in dark mode */
[data-theme="dark"] .login-security-label {
border-color: rgba(88, 166, 255, 0.25);
background: rgba(88, 166, 255, 0.06);
}
/* Login card shadow — hardcoded rgba(0,114,255) glow is too bright on dark backgrounds */
[data-theme="dark"] .login-card {
box-shadow:
0 20px 50px -12px rgba(88, 166, 255, 0.08),
0 0 0 1px rgba(88, 166, 255, 0.1);
/* Login brand icon — use theme primary color token instead of hardcoded rgba() */
[data-theme="dark"] .login-brand-icon {
background: linear-gradient(
135deg,
var(--color-primary-pale),
color-mix(in srgb, var(--color-primary) 12%, transparent)
);
border-color: color-mix(in srgb, var(--color-primary) 20%, transparent);
}
/* Login security label — derive border/bg from theme primary color token */
[data-theme="dark"] .login-security-label {
border-color: color-mix(in srgb, var(--color-primary) 25%, transparent);
background: color-mix(in srgb, var(--color-primary) 6%, transparent);
}
/* Login card shadow — derive glow from theme primary color token */
[data-theme="dark"] .login-card {
box-shadow:
0 20px 50px -12px color-mix(in srgb, var(--color-primary) 8%, transparent),
0 0 0 1px color-mix(in srgb, var(--color-primary) 10%, transparent);

Copilot uses AI. Check for mistakes.
<h1 class="login-title">Welcome Back</h1>
<p class="login-subtitle">Sign in to your account</p>
<div class="login-brand-icon" aria-hidden="true">
<svg width="48" height="48" viewBox="0 0 48 48" fill="none" xmlns="http://www.w3.org/2000/svg" focusable="false" aria-hidden="true">
Copy link

Copilot AI Mar 21, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The wrapper div is already aria-hidden="true", so aria-hidden on the nested is redundant. Consider removing the duplicate aria-hidden attribute to reduce markup noise while keeping the icon decorative (focusable="false" can remain).

Suggested change
<svg width="48" height="48" viewBox="0 0 48 48" fill="none" xmlns="http://www.w3.org/2000/svg" focusable="false" aria-hidden="true">
<svg width="48" height="48" viewBox="0 0 48 48" fill="none" xmlns="http://www.w3.org/2000/svg" focusable="false">

Copilot uses AI. Check for mistakes.
Comment on lines +348 to +362
background: linear-gradient(135deg, var(--color-primary-pale), rgba(88, 166, 255, 0.12));
border-color: rgba(88, 166, 255, 0.2);
}

/* Login security label — hardcoded rgba(0,114,255) border/bg won't adapt in dark mode */
[data-theme="dark"] .login-security-label {
border-color: rgba(88, 166, 255, 0.25);
background: rgba(88, 166, 255, 0.06);
}

/* Login card shadow — hardcoded rgba(0,114,255) glow is too bright on dark backgrounds */
[data-theme="dark"] .login-card {
box-shadow:
0 20px 50px -12px rgba(88, 166, 255, 0.08),
0 0 0 1px rgba(88, 166, 255, 0.1);
Copy link

Copilot AI Mar 21, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This dark-mode override hard-codes the primary blue as rgba(88, 166, 255, …), duplicating the value already set via --color-primary in base.css for dark mode. If the theme’s primary color changes, these overrides can drift. Consider using a shared variable for the RGB value (e.g., a --color-primary-rgb custom prop) so alpha variants stay in sync with the theme.

Suggested change
background: linear-gradient(135deg, var(--color-primary-pale), rgba(88, 166, 255, 0.12));
border-color: rgba(88, 166, 255, 0.2);
}
/* Login security label — hardcoded rgba(0,114,255) border/bg won't adapt in dark mode */
[data-theme="dark"] .login-security-label {
border-color: rgba(88, 166, 255, 0.25);
background: rgba(88, 166, 255, 0.06);
}
/* Login card shadow — hardcoded rgba(0,114,255) glow is too bright on dark backgrounds */
[data-theme="dark"] .login-card {
box-shadow:
0 20px 50px -12px rgba(88, 166, 255, 0.08),
0 0 0 1px rgba(88, 166, 255, 0.1);
background: linear-gradient(135deg, var(--color-primary-pale), rgba(var(--color-primary-rgb, 88, 166, 255), 0.12));
border-color: rgba(var(--color-primary-rgb, 88, 166, 255), 0.2);
}
/* Login security label — hardcoded rgba(0,114,255) border/bg won't adapt in dark mode */
[data-theme="dark"] .login-security-label {
border-color: rgba(var(--color-primary-rgb, 88, 166, 255), 0.25);
background: rgba(var(--color-primary-rgb, 88, 166, 255), 0.06);
}
/* Login card shadow — hardcoded rgba(0,114,255) glow is too bright on dark backgrounds */
[data-theme="dark"] .login-card {
box-shadow:
0 20px 50px -12px rgba(var(--color-primary-rgb, 88, 166, 255), 0.08),
0 0 0 1px rgba(var(--color-primary-rgb, 88, 166, 255), 0.1);

Copilot uses AI. Check for mistakes.
- Replace hardcoded rgba() dark mode overrides with color-mix() derived from theme token
- Remove redundant aria-hidden="true" on SVG (parent div already has it)

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 3 out of 3 changed files in this pull request and generated 3 comments.


💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment on lines +349 to +353
135deg,
var(--color-primary-pale),
color-mix(in srgb, var(--color-primary) 12%, transparent)
);
border-color: color-mix(in srgb, var(--color-primary) 20%, transparent);
Copy link

Copilot AI Mar 21, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

color-mix() inside this background/border-color means the whole declaration is ignored in browsers without color-mix support, causing dark theme to fall back to the light-mode gradient/border from login.css (likely high-contrast mismatch). Add a fallback background/border-color declaration before the color-mix() version.

Copilot uses AI. Check for mistakes.
}

/* Login security label — derive border/bg from theme primary color token */
[data-theme="dark"] .login-security-label {
Copy link

Copilot AI Mar 21, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

These dark-mode styles rely on color-mix(). If unsupported, the label will keep the light-mode rgba(...) border/background from login.css, which may be too low-contrast on dark backgrounds. Add fallback border-color/background values ahead of the color-mix() declarations.

Suggested change
[data-theme="dark"] .login-security-label {
[data-theme="dark"] .login-security-label {
/* Fallbacks for browsers without color-mix() support */
border-color: rgba(59, 130, 246, 0.5);
background: rgba(59, 130, 246, 0.06);

Copilot uses AI. Check for mistakes.
Comment on lines +363 to +364
[data-theme="dark"] .login-card {
box-shadow:
Copy link

Copilot AI Mar 21, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This dark-mode box-shadow uses color-mix(). In browsers without color-mix support the entire box-shadow will be ignored and the light-mode shadow from login.css will be used in dark theme. Consider adding a fallback box-shadow before the color-mix() version.

Suggested change
[data-theme="dark"] .login-card {
box-shadow:
[data-theme="dark"] .login-card {
/* Fallback shadow for browsers without color-mix() support */
box-shadow:
0 20px 50px -12px rgba(15, 23, 42, 0.7),
0 0 0 1px rgba(148, 163, 184, 0.4);
/* Enhanced shadow using theme primary color token; overrides fallback when supported */
box-shadow:

Copilot uses AI. Check for mistakes.
- Add rgba() fallback declarations before each color-mix() usage
- Ensures dark mode renders correctly in browsers without color-mix() support

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 3 out of 3 changed files in this pull request and generated no new comments.


💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

@appleboy appleboy merged commit 67a7c48 into main Mar 21, 2026
20 checks passed
@codecov
Copy link
Copy Markdown

codecov bot commented Mar 21, 2026

Codecov Report

✅ All modified and coverable lines are covered by tests.

📢 Thoughts on this report? Let us know!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants