dark mode supoport

This commit is contained in:
Mark Gregory
2026-08-26 17:12:53 +01:00
parent fd06211c72
commit a3ef18384b
5 changed files with 151 additions and 13 deletions
+1 -1
View File
@@ -12,7 +12,7 @@ return Application::configure(basePath: dirname(__DIR__))
health: '/up',
)
->withMiddleware(function (Middleware $middleware): void {
//
$middleware->redirectGuestsTo(fn (Request $request) => route('login'));
})
->withExceptions(function (Exceptions $exceptions): void {
$exceptions->shouldRenderJsonWhen(
@@ -1803,3 +1803,135 @@ html:not(.dark) [class*="bg-amber-"],
html:not(.dark) [class*="bg-violet-"] {
/* their own utility/button colour remains authoritative */
}
/* ============================================================
Account appearance spacing + authentication control polish
============================================================ */
/* Flux segmented control keeps working, but the options no longer touch. */
.hd-account-settings .hd-appearance-group {
display: flex !important;
gap: 0.75rem !important;
padding: 0 !important;
background: transparent !important;
}
.hd-account-settings .hd-appearance-group > * {
flex: 1 1 0 !important;
min-width: 0;
overflow: hidden;
border-radius: 0.85rem !important;
}
/* Dark authentication actions: never allow Flux's light button surface here. */
html.dark .hd-auth-surface .hd-auth-primary,
html.dark .hd-auth-surface form .hd-auth-primary,
html.dark .hd-auth-surface .hd-auth-passkey button,
html.dark .hd-auth-surface .hd-auth-passkey [role="button"] {
background: linear-gradient(180deg, #3172f5 0%, #2563eb 100%) !important;
background-color: #2563eb !important;
border: 1px solid #4380f5 !important;
color: #ffffff !important;
-webkit-text-fill-color: #ffffff !important;
box-shadow:
inset 0 1px 0 rgba(255,255,255,.16),
0 8px 18px rgba(37,99,235,.18) !important;
}
html.dark .hd-auth-surface .hd-auth-primary:hover,
html.dark .hd-auth-surface .hd-auth-primary:focus-visible,
html.dark .hd-auth-surface .hd-auth-passkey button:hover,
html.dark .hd-auth-surface .hd-auth-passkey button:focus-visible,
html.dark .hd-auth-surface .hd-auth-passkey [role="button"]:hover,
html.dark .hd-auth-surface .hd-auth-passkey [role="button"]:focus-visible {
background: linear-gradient(180deg, #3b82f6 0%, #2563eb 100%) !important;
border-color: #60a5fa !important;
color: #ffffff !important;
outline: none !important;
}
/* Keep the passkey separator itself neutral/dark. */
html.dark .hd-auth-surface .hd-auth-passkey {
color: #a1a1aa;
}
html.dark .hd-auth-surface .hd-auth-passkey hr {
border-color: #3f4652 !important;
}
/* Remember-me checkbox: dark surface with a blue checked state. */
html.dark .hd-auth-surface .hd-auth-checkbox input[type="checkbox"] {
appearance: none !important;
-webkit-appearance: none !important;
width: 1.05rem !important;
height: 1.05rem !important;
display: inline-grid !important;
place-content: center !important;
border: 1px solid #596273 !important;
border-radius: 0.28rem !important;
background: #252a31 !important;
box-shadow: inset 0 1px 0 rgba(255,255,255,.035) !important;
cursor: pointer;
}
html.dark .hd-auth-surface .hd-auth-checkbox input[type="checkbox"]::before {
content: "";
width: 0.52rem;
height: 0.3rem;
border-left: 2px solid #fff;
border-bottom: 2px solid #fff;
transform: rotate(-45deg) scale(0);
transform-origin: center;
transition: transform .1s ease;
}
html.dark .hd-auth-surface .hd-auth-checkbox input[type="checkbox"]:checked {
background: #2563eb !important;
border-color: #60a5fa !important;
}
html.dark .hd-auth-surface .hd-auth-checkbox input[type="checkbox"]:checked::before {
transform: rotate(-45deg) scale(1);
}
html.dark .hd-auth-surface .hd-auth-checkbox label,
html.dark .hd-auth-surface .hd-auth-checkbox span {
color: #e5e7eb !important;
}
/* Light appearance gets deliberate white controls with readable dark text. */
html:not(.dark) .hd-auth-surface .hd-auth-primary,
html:not(.dark) .hd-auth-surface form .hd-auth-primary,
html:not(.dark) .hd-auth-surface .hd-auth-passkey button,
html:not(.dark) .hd-auth-surface .hd-auth-passkey [role="button"] {
background: linear-gradient(180deg, #3172f5 0%, #2563eb 100%) !important;
background-color: #2563eb !important;
border-color: #2563eb !important;
color: #ffffff !important;
-webkit-text-fill-color: #ffffff !important;
}
html:not(.dark) .hd-auth-surface .hd-auth-checkbox input[type="checkbox"] {
accent-color: #2563eb;
}
/* Make auth form labels/links readable in dark mode too. */
html.dark .hd-auth-surface label,
html.dark .hd-auth-surface [data-flux-label] {
color: #f4f4f5 !important;
}
html.dark .hd-auth-surface a {
color: #bfdbfe;
}
html.dark .hd-auth-surface a:hover {
color: #dbeafe;
}
@media (max-width: 640px) {
.hd-account-settings .hd-appearance-group {
flex-direction: column !important;
}
}
@@ -7,13 +7,15 @@
<x-auth-session-status class="text-center" :status="session('status')" />
<x-passkey-verify
options-route="passkey.confirm-options"
submit-route="passkey.confirm"
:label="__('Confirm with passkey')"
:loading-label="__('Confirming...')"
:separator="__('Or confirm with password')"
/>
<div class="hd-auth-passkey">
<x-passkey-verify
options-route="passkey.confirm-options"
submit-route="passkey.confirm"
:label="__('Confirm with passkey')"
:loading-label="__('Confirming...')"
:separator="__('Or confirm with password')"
/>
</div>
<form method="POST" action="{{ route('password.confirm.store') }}" class="flex flex-col gap-6">
@csrf
@@ -28,7 +30,7 @@
viewable
/>
<flux:button variant="primary" type="submit" class="w-full" data-test="confirm-password-button">
<flux:button variant="primary" type="submit" class="hd-auth-primary w-full" data-test="confirm-password-button">
{{ __('Confirm') }}
</flux:button>
</form>
@@ -5,7 +5,9 @@
<!-- Session Status -->
<x-auth-session-status class="text-center" :status="session('status')" />
<x-passkey-verify />
<div class="hd-auth-passkey">
<x-passkey-verify />
</div>
<form method="POST" action="{{ route('login.store') }}" class="flex flex-col gap-6">
@csrf
@@ -42,10 +44,12 @@
</div>
<!-- Remember Me -->
<flux:checkbox name="remember" :label="__('Remember me')" :checked="old('remember')" />
<div class="hd-auth-checkbox">
<flux:checkbox name="remember" :label="__('Remember me')" :checked="old('remember')" />
</div>
<div class="flex items-center justify-end">
<flux:button variant="primary" type="submit" class="w-full" data-test="login-button">
<flux:button variant="primary" type="submit" class="hd-auth-primary w-full" data-test="login-button">
{{ __('Log in') }}
</flux:button>
</div>
@@ -4,7 +4,7 @@
<flux:heading class="sr-only">{{ __('Appearance settings') }}</flux:heading>
<x-settings.layout :heading="__('Appearance')" :subheading=" __('Update the appearance settings for your account')">
<flux:radio.group x-data variant="segmented" x-model="$flux.appearance">
<flux:radio.group x-data variant="segmented" x-model="$flux.appearance" class="hd-appearance-group">
<flux:radio value="light" icon="sun">{{ __('Light') }}</flux:radio>
<flux:radio value="dark" icon="moon">{{ __('Dark') }}</flux:radio>
<flux:radio value="system" icon="computer-desktop">{{ __('System') }}</flux:radio>