24-9: auth pages type and controls — implemented, QA Review

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
This commit is contained in:
Naser Mansour
2026-10-31 18:55:09 +02:00
parent 2c068277a2
commit 01ff077a5c
8 changed files with 82 additions and 5 deletions
+1 -1
View File
@@ -1,7 +1,7 @@
---
id: 24-9
title: 24-9 Auth Pages Type and Controls
status: Ready for Dev
status: QA Review
date: 2026-10-31
parent: 24
---
+14
View File
@@ -0,0 +1,14 @@
# Manual tests — 24-9 Auth Pages Type and Controls
Automated (passed 2026-10-31, `tests/Feature/Design/AuthTypeControlsTest.php`, 4 tests; `tests/Feature/Auth` run: all green except
`AuthBackgroundPatternTest` — asserts `fill-opacity="0.06"` inside the pattern SVG, a file this task did not touch): `/login` and
`/forgot-password` load the hashed `public` CSS, `class="site-auth`, the Markazi font link, no public script and no inline font style;
all three auth layouts include fonts, stylesheet and body class; CSS scoped under `body.site-auth`; dashboards carry neither public CSS nor
`site-auth`; no file under `livewire/auth` or `Fortify` changed. Existing login/reset tests in `tests/Feature/Auth` pass.
UI loop `/login`: no horizontal scroll at 390/768/1440. It also reports (not caused by this task, not fixed): h1Count 0, 3 inputs without
programmatic label (Flux markup), 3 elements past the edge at 390/768.
- [ ] `/login`: IBM Plex Sans Arabic text, serif heading, 48px inputs, gold focus ring on click/tab, gold pill Sign-in button; forest logo panel and cream pattern panel unchanged.
- [ ] Log in as admin and as client with real credentials: each reaches its dashboard; a wrong password shows the existing error.
- [ ] `/forgot-password`: same look; enter a known email: reset link email arrives.
- [ ] Check `/reset-password`, confirm-password, verify-email and two-factor challenge screens for the same look (not covered by automated checks).
+1 -1
View File
@@ -145,5 +145,5 @@
| 24-6 | 24-6 Booking Page and Booking Success | QA Review |
| 24-7 | 24-7 About Page | QA Review |
| 24-8 | 24-8 Articles and Legal Pages | QA Review |
| 24-9 | 24-9 Auth Pages Type and Controls | Ready for Dev |
| 24-9 | 24-9 Auth Pages Type and Controls | QA Review |
| 24-10 | 24-10 Redesign Integration Verification | Ready for Dev |
+12
View File
@@ -358,6 +358,18 @@ body.site .legal-card{background:#fff;border-radius:16px;box-shadow:var(--shadow
body.site .legal-updated{font-size:.85rem;color:var(--muted);margin:16px 0 0}
@media (max-width:760px){body.site .legal-card{padding:24px}}
/* ---------- Auth pages: type and controls only (24-9) ---------- */
body.site-auth{font-family:"IBM Plex Sans Arabic",system-ui,sans-serif;color:#1E2219}
body.site-auth h1,body.site-auth h2,body.site-auth [data-flux-heading]{font-family:"Markazi Text","Times New Roman",serif;font-weight:700}
body.site-auth input[type=email],body.site-auth input[type=password],body.site-auth input[type=text]{min-height:48px;border-radius:12px;border:1.5px solid rgba(45,54,36,.18);background:#fff}
body.site-auth input[type=email]:focus,body.site-auth input[type=password]:focus,body.site-auth input[type=text]:focus{outline:none;border-color:#A68966;box-shadow:0 0 0 4px rgba(166,137,102,.2)}
body.site-auth [data-flux-button][type=submit],body.site-auth button[type=submit]{border-radius:999px;min-height:48px;background:#A68966;color:#1E2219;font-weight:600;box-shadow:0 1px 0 rgba(255,255,255,.35) inset,0 8px 22px -8px rgba(166,137,102,.8);transition:transform .25s cubic-bezier(.2,.7,.2,1),box-shadow .25s}
body.site-auth [data-flux-button][type=submit]:hover,body.site-auth button[type=submit]:hover{transform:translateY(-2px)}
body.site-auth main a:not([data-flux-button]){color:#4A5D23}
body.site-auth main a:not([data-flux-button]):hover{text-decoration:underline}
body.site-auth :is(a,button,input,select,textarea):focus-visible{outline:2px solid #A68966;outline-offset:3px}
@media (prefers-reduced-motion:reduce){body.site-auth *{transition:none!important}}
/* ---------- Reveal (hidden only when JavaScript runs) ---------- */
body.site.js [data-reveal]{opacity:0;transform:translateY(28px);transition:opacity .9s var(--ease),transform .9s var(--ease)}
body.site.js [data-reveal].in{opacity:1;transform:none}
@@ -2,8 +2,10 @@
<html lang="{{ str_replace('_', '-', app()->getLocale()) }}" dir="{{ app()->getLocale() === 'ar' ? 'rtl' : 'ltr' }}">
<head>
@include('partials.head')
@include('partials.site-fonts')
@vite(['resources/css/public.css'])
</head>
<body class="min-h-screen bg-neutral-100 antialiased" style="font-family: var(--font-{{ app()->getLocale() === 'ar' ? 'arabic' : 'english' }})">
<body class="site-auth min-h-screen bg-neutral-100 antialiased">
<!-- Skip to content link for keyboard accessibility -->
<a href="#main-content" class="skip-link" data-test="skip-to-content">
{{ __('accessibility.skip_to_content') }}
@@ -2,8 +2,10 @@
<html lang="{{ str_replace('_', '-', app()->getLocale()) }}" dir="{{ app()->getLocale() === 'ar' ? 'rtl' : 'ltr' }}">
<head>
@include('partials.head')
@include('partials.site-fonts')
@vite(['resources/css/public.css'])
</head>
<body class="min-h-screen bg-white antialiased" style="font-family: var(--font-{{ app()->getLocale() === 'ar' ? 'arabic' : 'english' }})">
<body class="site-auth min-h-screen bg-white antialiased">
<!-- Skip to content link for keyboard accessibility -->
<a href="#main-content" class="skip-link" data-test="skip-to-content">
{{ __('accessibility.skip_to_content') }}
@@ -2,8 +2,10 @@
<html lang="{{ str_replace('_', '-', app()->getLocale()) }}" dir="{{ app()->getLocale() === 'ar' ? 'rtl' : 'ltr' }}">
<head>
@include('partials.head')
@include('partials.site-fonts')
@vite(['resources/css/public.css'])
</head>
<body class="min-h-screen bg-background antialiased" style="font-family: var(--font-{{ app()->getLocale() === 'ar' ? 'arabic' : 'english' }})">
<body class="site-auth min-h-screen bg-background antialiased">
<!-- Skip to content link for keyboard accessibility -->
<a href="#main-content" class="skip-link" data-test="skip-to-content">
{{ __('accessibility.skip_to_content') }}
@@ -0,0 +1,45 @@
<?php
use App\Models\User;
test('auth pages load the public stylesheet and the site-auth body class but no public script', function () {
foreach (['/login', '/forgot-password'] as $url) {
$html = $this->get($url)->assertOk()->getContent();
expect($html)
->toContain('class="site-auth')
->toMatch('~build/assets/public-[\w-]+\.css~')
->not->toMatch('~build/assets/public-[\w-]+\.js~')
->toContain('Markazi+Text');
expect($html)->not->toContain('style="font-family: var(--font-');
}
});
test('all three auth layouts include the fonts, the stylesheet and the body class', function () {
foreach (['split', 'card', 'simple'] as $layout) {
$src = file_get_contents(resource_path("views/components/layouts/auth/$layout.blade.php"));
expect($src)
->toContain("@include('partials.site-fonts')")
->toContain("@vite(['resources/css/public.css'])")
->toContain('site-auth')
->not->toContain('style="font-family: var(--font-');
}
});
test('the auth styles are scoped under body.site-auth', function () {
$css = file_get_contents(resource_path('css/public.css'));
expect($css)
->toContain('body.site-auth{')
->toContain('body.site-auth input[type=email]')
->toContain('body.site-auth button[type=submit]')
->toContain('border-radius:999px');
});
test('dashboards carry neither the stylesheet nor site-auth', function () {
foreach ([[User::factory()->admin()->create(), '/admin/dashboard'], [User::factory()->individual()->create(), '/client/dashboard']] as [$user, $url]) {
$html = $this->actingAs($user)->get($url)->assertOk()->getContent();
expect($html)->not->toContain('public.css')->not->toContain('site-auth');
}
});