Logo
Neura UI
Loading…
Blocks

Auth

Sign-in variants, invites, magic links and two-factor setup.
2FA setup auth-2fa-setup
Authenticator setup with verify step.
{{--
    Auth 2FA setup — QR placeholder, backup codes note and OTP verification.
--}}
<section class="border-b border-dashed border-edge">
    <neura::container size="md" class="py-16 lg:py-20">
        <div class="mx-auto max-w-md">
            <div class="mb-8">
                <neura::brand href="#" name="Neura" align="left" />
                <neura::heading level="h1" size="2xl" class="mt-6 tracking-tight">
                    {{ __('Set up two-factor authentication') }}
                </neura::heading>
                <neura::text size="sm" class="mt-2 text-fg-secondary">
                    {{ __('Scan the QR code with your authenticator app, then enter a code to confirm.') }}
                </neura::text>
            </div>

            <neura::card class="p-6 sm:p-8">
                <div
                    class="mx-auto flex aspect-square w-44 items-center justify-center rounded-2xl border border-dashed border-edge bg-surface-inset/50">
                    <div class="text-center">
                        <neura::icon name="qr-code" class="mx-auto size-10 text-fg-muted" />
                        <neura::text size="xs" class="mt-2 font-mono uppercase tracking-[0.14em] text-fg-muted">
                            {{ __('QR code') }}
                        </neura::text>
                    </div>
                </div>

                <neura::text size="xs" align="center" class="mt-4 font-mono text-fg-muted">
                    {{ __('Manual key') }} · ABCD-EFGH-IJKL-MNOP
                </neura::text>

                <div class="mt-6 rounded-xl border border-dashed border-edge bg-surface-inset/40 px-4 py-3">
                    <neura::text size="sm" class="font-medium text-fg">{{ __('Save your backup codes') }}</neura::text>
                    <neura::text size="xs" class="mt-1 text-fg-secondary text-pretty">
                        {{ __('Store these codes somewhere safe. Each one can be used once if you lose access to your authenticator.') }}
                    </neura::text>
                    <ul class="mt-3 grid grid-cols-2 gap-2 font-mono text-xs tabular-nums text-fg-secondary">
                        @foreach (['9F2A-41C8', 'B7E1-03D9', 'C4A0-88F2', 'D1B6-55E0'] as $code)
                            <li class="rounded-lg border border-dashed border-edge px-2 py-1.5 text-center">{{ $code }}</li>
                        @endforeach
                    </ul>
                </div>

                <neura::separator class="my-6" />

                <form class="space-y-5" action="#" method="POST" onsubmit="return false;">
                    <neura::field>
                        <neura::label>{{ __('Verification code') }}</neura::label>
                        <neura::otp name="code" length="6" />
                        <neura::description>{{ __('Enter the 6-digit code from your authenticator app.') }}</neura::description>
                    </neura::field>

                    <neura::button type="submit" variant="primary" class="w-full" size="lg">
                        {{ __('Enable 2FA') }}
                    </neura::button>
                </form>
            </neura::card>
        </div>
    </neura::container>
</section>
Accept invite auth-invite
Invite acceptance with password setup.
{{--
    Auth invite — accept workspace invitation and set a password.
--}}
<section class="border-b border-dashed border-edge">
    <neura::container size="md" class="py-16 lg:py-20">
        <div class="mx-auto max-w-md">
            <div class="mb-8">
                <neura::brand href="#" name="Neura" align="left" />
                <neura::heading level="h1" size="2xl" class="mt-6 tracking-tight">
                    {{ __('Join Northline') }}
                </neura::heading>
                <neura::text size="sm" class="mt-2 text-fg-secondary">
                    {{ __('You’ve been invited to the Northline workspace. Set a password to continue.') }}
                </neura::text>
            </div>

            <neura::card class="p-6 sm:p-8">
                <div class="mb-6 flex items-center gap-3 rounded-xl border border-dashed border-edge bg-surface-inset/40 px-4 py-3">
                    <neura::avatar name="Northline" color="primary" size="md" />
                    <div class="min-w-0">
                        <neura::text size="sm" class="font-medium text-fg">{{ __('Northline') }}</neura::text>
                        <neura::text size="xs" class="text-fg-muted">{{ __('Workspace invite') }}</neura::text>
                    </div>
                </div>

                <form class="space-y-5" action="#" method="POST" onsubmit="return false;">
                    <neura::field>
                        <neura::label for="invite-email">{{ __('Email') }}</neura::label>
                        <neura::input id="invite-email" type="email" name="email" value="alex@company.com"
                            autocomplete="email" disabled />
                        <neura::description>{{ __('This invite is locked to the email above.') }}</neura::description>
                    </neura::field>

                    <neura::field>
                        <neura::label for="invite-name">{{ __('Full name') }}</neura::label>
                        <neura::input id="invite-name" type="text" name="name" autocomplete="name"
                            placeholder="Alex Martin" />
                    </neura::field>

                    <neura::field>
                        <neura::label for="invite-password">{{ __('Password') }}</neura::label>
                        <neura::input id="invite-password" type="password" name="password"
                            autocomplete="new-password" placeholder="••••••••" />
                        <neura::description>{{ __('At least 8 characters.') }}</neura::description>
                    </neura::field>

                    <neura::field>
                        <neura::label for="invite-password-confirm">{{ __('Confirm password') }}</neura::label>
                        <neura::input id="invite-password-confirm" type="password" name="password_confirmation"
                            autocomplete="new-password" placeholder="••••••••" />
                    </neura::field>

                    <neura::button type="submit" variant="primary" class="w-full" size="lg">
                        {{ __('Accept invite') }}
                    </neura::button>
                </form>
            </neura::card>
        </div>
    </neura::container>
</section>
Social sign-in auth-social
Social providers plus email form.
{{--
    Auth social — sign-in with social providers, email divider and credentials form.
--}}
<section class="border-b border-dashed border-edge">
    <neura::container size="md" class="py-16 lg:py-20">
        <div class="mx-auto max-w-md">
            <div class="mb-8">
                <neura::brand href="#" name="Neura" align="left" />
                <neura::heading level="h1" size="2xl" class="mt-6 tracking-tight">
                    {{ __('Sign in to your account') }}
                </neura::heading>
                <neura::text size="sm" class="mt-2 text-fg-secondary">
                    {{ __('Continue with a provider or use your work email.') }}
                </neura::text>
            </div>

            <neura::card class="p-6 sm:p-8">
                <div class="grid gap-3">
                    <neura::button type="button" variant="outline" class="w-full" size="lg" icon="globe-alt">
                        {{ __('Continue with Google') }}
                    </neura::button>
                    <neura::button type="button" variant="outline" class="w-full" size="lg" icon="code-bracket">
                        {{ __('Continue with GitHub') }}
                    </neura::button>
                </div>

                <div class="my-6 flex items-center gap-3">
                    <neura::separator class="flex-1" />
                    <neura::text size="xs" class="shrink-0 font-mono uppercase tracking-[0.14em] text-fg-muted">
                        {{ __('or email') }}
                    </neura::text>
                    <neura::separator class="flex-1" />
                </div>

                <form class="space-y-5" action="#" method="POST" onsubmit="return false;">
                    <neura::field>
                        <neura::label for="social-email">{{ __('Email') }}</neura::label>
                        <neura::input id="social-email" type="email" name="email" autocomplete="username"
                            placeholder="you@company.com" />
                    </neura::field>

                    <neura::field>
                        <div class="flex items-center justify-between gap-3">
                            <neura::label for="social-password">{{ __('Password') }}</neura::label>
                            <a href="#forgot"
                                class="text-xs text-fg-muted transition-colors hover:text-fg focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-primary-500/50 rounded">
                                {{ __('Forgot password?') }}
                            </a>
                        </div>
                        <neura::input id="social-password" type="password" name="password"
                            autocomplete="current-password" placeholder="••••••••" />
                    </neura::field>

                    <neura::button type="submit" variant="primary" class="w-full" size="lg">
                        {{ __('Sign in') }}
                    </neura::button>
                </form>

                <neura::separator class="my-6" />

                <neura::text size="sm" align="center" class="text-fg-secondary">
                    {{ __('No account yet?') }}
                    <a href="#register"
                        class="font-medium text-fg underline-offset-4 hover:underline focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-primary-500/50 rounded">
                        {{ __('Create one') }}
                    </a>
                </neura::text>
            </neura::card>
        </div>
    </neura::container>
</section>