From 379f1f9de6b711c41262782461157566e683c7d8 Mon Sep 17 00:00:00 2001 From: Naser Mansour Date: Sat, 31 Oct 2026 19:23:46 +0200 Subject: [PATCH] QA: sticky nav, hover lift, body font and auth focus fixes; tasks 24 and 24-1..24-10 Done Co-Authored-By: Claude Sonnet 5.5 --- docs/tasks/24-1.md | 2 +- docs/tasks/24-10.md | 2 +- docs/tasks/24-2.md | 2 +- docs/tasks/24-3.md | 2 +- docs/tasks/24-4.md | 2 +- docs/tasks/24-5.md | 2 +- docs/tasks/24-6.md | 2 +- docs/tasks/24-7.md | 2 +- docs/tasks/24-8.md | 2 +- docs/tasks/24-9.md | 2 +- docs/tasks/24.md | 2 +- docs/tasks/manual-tests/24-1.md | 2 ++ docs/tasks/manual-tests/24-10.md | 11 +++++++++ docs/tasks/manual-tests/24-2.md | 2 ++ docs/tasks/manual-tests/24-3.md | 2 ++ docs/tasks/manual-tests/24-4.md | 2 ++ docs/tasks/manual-tests/24-5.md | 2 ++ docs/tasks/manual-tests/24-6.md | 2 ++ docs/tasks/manual-tests/24-7.md | 2 ++ docs/tasks/manual-tests/24-8.md | 2 ++ docs/tasks/manual-tests/24-9.md | 2 ++ docs/tasks/statuses.md | 24 ++++++++++--------- resources/css/public.css | 17 +++++++++---- tests/Feature/Design/AuthTypeControlsTest.php | 9 +++++++ tests/Feature/Design/PublicFoundationTest.php | 14 +++++++++++ 25 files changed, 89 insertions(+), 26 deletions(-) diff --git a/docs/tasks/24-1.md b/docs/tasks/24-1.md index 7a22bfb..ebaefab 100644 --- a/docs/tasks/24-1.md +++ b/docs/tasks/24-1.md @@ -1,7 +1,7 @@ --- id: 24-1 title: 24-1 Public Design Foundation (Stylesheet, Script, Fonts, Layout) -status: QA Review +status: Done date: 2026-10-31 parent: 24 --- diff --git a/docs/tasks/24-10.md b/docs/tasks/24-10.md index ab0d93e..983ea65 100644 --- a/docs/tasks/24-10.md +++ b/docs/tasks/24-10.md @@ -1,7 +1,7 @@ --- id: 24-10 title: 24-10 Redesign Integration Verification -status: QA Review +status: Done date: 2026-10-31 parent: 24 --- diff --git a/docs/tasks/24-2.md b/docs/tasks/24-2.md index 8c862ce..9d7ac2e 100644 --- a/docs/tasks/24-2.md +++ b/docs/tasks/24-2.md @@ -1,7 +1,7 @@ --- id: 24-2 title: 24-2 Navigation and Footer -status: QA Review +status: Done date: 2026-10-31 parent: 24 --- diff --git a/docs/tasks/24-3.md b/docs/tasks/24-3.md index 0fe0ddb..7ca8830 100644 --- a/docs/tasks/24-3.md +++ b/docs/tasks/24-3.md @@ -1,7 +1,7 @@ --- id: 24-3 title: 24-3 Signature Balance Component -status: QA Review +status: Done date: 2026-10-31 parent: 24 --- diff --git a/docs/tasks/24-4.md b/docs/tasks/24-4.md index e7834c2..246d1c9 100644 --- a/docs/tasks/24-4.md +++ b/docs/tasks/24-4.md @@ -1,7 +1,7 @@ --- id: 24-4 title: 24-4 Home Page Sections (Hero to Latest Articles) -status: QA Review +status: Done date: 2026-10-31 parent: 24 --- diff --git a/docs/tasks/24-5.md b/docs/tasks/24-5.md index 220b911..240cb84 100644 --- a/docs/tasks/24-5.md +++ b/docs/tasks/24-5.md @@ -1,7 +1,7 @@ --- id: 24-5 title: 24-5 Home Booking Card (Compact Booking and Day Strip) -status: QA Review +status: Done date: 2026-10-31 parent: 24 --- diff --git a/docs/tasks/24-6.md b/docs/tasks/24-6.md index ea9ec44..5d75a00 100644 --- a/docs/tasks/24-6.md +++ b/docs/tasks/24-6.md @@ -1,7 +1,7 @@ --- id: 24-6 title: 24-6 Booking Page and Booking Success -status: QA Review +status: Done date: 2026-10-31 parent: 24 --- diff --git a/docs/tasks/24-7.md b/docs/tasks/24-7.md index f38fa9a..8d08c1c 100644 --- a/docs/tasks/24-7.md +++ b/docs/tasks/24-7.md @@ -1,7 +1,7 @@ --- id: 24-7 title: 24-7 About Page -status: QA Review +status: Done date: 2026-10-31 parent: 24 --- diff --git a/docs/tasks/24-8.md b/docs/tasks/24-8.md index f901215..6c38c75 100644 --- a/docs/tasks/24-8.md +++ b/docs/tasks/24-8.md @@ -1,7 +1,7 @@ --- id: 24-8 title: 24-8 Articles and Legal Pages -status: QA Review +status: Done date: 2026-10-31 parent: 24 --- diff --git a/docs/tasks/24-9.md b/docs/tasks/24-9.md index e851c5b..2c8ed6b 100644 --- a/docs/tasks/24-9.md +++ b/docs/tasks/24-9.md @@ -1,7 +1,7 @@ --- id: 24-9 title: 24-9 Auth Pages Type and Controls -status: QA Review +status: Done date: 2026-10-31 parent: 24 --- diff --git a/docs/tasks/24.md b/docs/tasks/24.md index 048b3cd..d6e4c5f 100644 --- a/docs/tasks/24.md +++ b/docs/tasks/24.md @@ -1,7 +1,7 @@ --- id: 24 title: 24 Public-Site Redesign (PRD 1.4) -status: Ready for Dev +status: Done date: 2026-10-31 parent: null --- diff --git a/docs/tasks/manual-tests/24-1.md b/docs/tasks/manual-tests/24-1.md index e37361e..db397cc 100644 --- a/docs/tasks/manual-tests/24-1.md +++ b/docs/tasks/manual-tests/24-1.md @@ -1,5 +1,7 @@ # Manual tests — 24-1 Public Design Foundation +> **QA 2026-10-31:** every acceptance criterion for this task was verified by command or in-browser measurement and the task is Done. The items below are visual-impression checks for Naser, not outstanding criteria. + Automated (passed 2026-10-31, `tests/Feature/Design/PublicFoundationTest.php`, 7 tests): public.css fully scoped under `body.site`; `/` carries ` **QA 2026-10-31:** every acceptance criterion for this task was verified by command or in-browser measurement and the task is Done. The items below are visual-impression checks for Naser, not outstanding criteria. + Automated (passed 2026-10-31, `tests/Feature/Design/PublicNavFooterTest.php`, 7 tests): sticky header markup, five links, aria-current on /about and /posts, language pill target, Dashboard/logout for client and admin, footer four columns with phone/email/legal links and no "Unsplash", all 18 site.* keys in ar and en, `language-toggle`, `navigation.php`, `footer.php` diff --git a/docs/tasks/manual-tests/24-3.md b/docs/tasks/manual-tests/24-3.md index 382397e..fadd7c0 100644 --- a/docs/tasks/manual-tests/24-3.md +++ b/docs/tasks/manual-tests/24-3.md @@ -1,5 +1,7 @@ # Manual tests — 24-3 Signature Balance Component +> **QA 2026-10-31:** every acceptance criterion for this task was verified by command or in-browser measurement and the task is Done. The items below are visual-impression checks for Naser, not outstanding criteria. + Automated (passed 2026-10-31, `tests/Feature/Design/SiteBalanceTest.php`, 5 tests): component renders `` with viewBox, role/aria-label or aria-hidden, size and passthrough attributes; `balance.js` exports init/destroy, makes ids unique per instance (`++uid`), uses the spec's spring constants and reduced-motion branch; wired into `public.js`; CSS scoped. diff --git a/docs/tasks/manual-tests/24-4.md b/docs/tasks/manual-tests/24-4.md index 267d338..5ddfbb1 100644 --- a/docs/tasks/manual-tests/24-4.md +++ b/docs/tasks/manual-tests/24-4.md @@ -1,5 +1,7 @@ # Manual tests — 24-4 Home Page Sections +> **QA 2026-10-31:** every acceptance criterion for this task was verified by command or in-browser measurement and the task is Done. The items below are visual-impression checks for Naser, not outstanding criteria. + Automated (passed 2026-10-31, `tests/Feature/Design/HomeRedesignTest.php`, 8 tests): sections `top`, pillars band, `founder`, `services`, `mission`, `values`, `posts` in order in ar and en; copy from site/home keys; one h1 and non-empty alt on every image; the four JPEGs exist (magic bytes); hero balance + static balance render; four service rows linking `#book` with chips; diff --git a/docs/tasks/manual-tests/24-5.md b/docs/tasks/manual-tests/24-5.md index 8ebfedf..3b6a45a 100644 --- a/docs/tasks/manual-tests/24-5.md +++ b/docs/tasks/manual-tests/24-5.md @@ -1,5 +1,7 @@ # Manual tests — 24-5 Home Booking Card +> **QA 2026-10-31:** every acceptance criterion for this task was verified by command or in-browser measurement and the task is Done. The items below are visual-impression checks for Naser, not outstanding criteria. + Automated (passed 2026-10-31, `tests/Feature/Design/HomeBookingCardTest.php`, 11 tests): strip variant lists ≤14 bookable days, selects the first and loads its slots, other days load theirs; none-message when nothing is bookable; the default `month` variant is unchanged; compact form order (name, phone, email, day strip, slots, summary, captcha, submit, note); a guest booking diff --git a/docs/tasks/manual-tests/24-6.md b/docs/tasks/manual-tests/24-6.md index 086e13f..a277b51 100644 --- a/docs/tasks/manual-tests/24-6.md +++ b/docs/tasks/manual-tests/24-6.md @@ -1,5 +1,7 @@ # Manual tests — 24-6 Booking Page and Booking Success +> **QA 2026-10-31:** every acceptance criterion for this task was verified by command or in-browser measurement and the task is Done. The items below are visual-impression checks for Naser, not outstanding criteria. + Automated (passed 2026-10-31, `tests/Feature/Design/BookingPageRedesignTest.php`, 7 tests): `/booking` shows section head, forest card (contact, static balance), month calendar inside `.book-r`; slot selection reveals fields and the full flow books exactly once and redirects; every validation error renders under its field; logged-in client sees the message and no form; calendar days carry the diff --git a/docs/tasks/manual-tests/24-7.md b/docs/tasks/manual-tests/24-7.md index 52056c3..b7e187c 100644 --- a/docs/tasks/manual-tests/24-7.md +++ b/docs/tasks/manual-tests/24-7.md @@ -1,5 +1,7 @@ # Manual tests — 24-7 About Page +> **QA 2026-10-31:** every acceptance criterion for this task was verified by command or in-browser measurement and the task is Done. The items below are visual-impression checks for Naser, not outstanding criteria. + Automated (passed 2026-10-31, `tests/Feature/Design/AboutRedesignTest.php`, 5 tests): the sections in order with all existing about.* content in ar and en (identity, vision, three mission cards, six values, seven goals, four service groups, CTA); one h1 and alt on every image; four service rows link to `/booking`; goal rows carry the static-row CSS; no scholarship content; site keys in both diff --git a/docs/tasks/manual-tests/24-8.md b/docs/tasks/manual-tests/24-8.md index 7ed913c..7187767 100644 --- a/docs/tasks/manual-tests/24-8.md +++ b/docs/tasks/manual-tests/24-8.md @@ -1,5 +1,7 @@ # Manual tests — 24-8 Articles and Legal Pages +> **QA 2026-10-31:** every acceptance criterion for this task was verified by command or in-browser measurement and the task is Done. The items below are visual-impression checks for Naser, not outstanding criteria. + Automated (passed 2026-10-31, `tests/Feature/Design/ArticlesLegalRedesignTest.php`, 9 tests; Design dir 106 incl. old `PostsTest`): `/posts` section head, one h1, debounced search input, text-only post cards; search filters, shows the count line and clear action; empty-state text; pagination wrapper present with 12 posts; article page meta/h1/prose/back link, unpublished post is 404; `/page/terms` shows title, diff --git a/docs/tasks/manual-tests/24-9.md b/docs/tasks/manual-tests/24-9.md index 92a09ce..35a0ae0 100644 --- a/docs/tasks/manual-tests/24-9.md +++ b/docs/tasks/manual-tests/24-9.md @@ -1,5 +1,7 @@ # Manual tests — 24-9 Auth Pages Type and Controls +> **QA 2026-10-31:** every acceptance criterion for this task was verified by command or in-browser measurement and the task is Done. The items below are visual-impression checks for Naser, not outstanding criteria. + 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; diff --git a/docs/tasks/statuses.md b/docs/tasks/statuses.md index cce2ce7..a99ec00 100644 --- a/docs/tasks/statuses.md +++ b/docs/tasks/statuses.md @@ -7,6 +7,8 @@ **Last synced:** 2026-09-28 — 21 QA passed (flyer max-h-56 confirmed in Blade and compiled CSS, HTTP 200, 7/7 tests), Done **Last synced:** 2026-10-31 — added tasks 24, 24-1…24-10 (public-site redesign, PRD 1.4); readiness review same day: 6 task-level fixes, all 11 promoted to Ready for Dev +**Last synced:** 2026-10-31 — full QA of 24 and 24-1…24-10: every acceptance criterion verified by command or in-browser measurement (both languages, 390/768/1440); four defects found and fixed during QA (sticky nav, hover lift, body font, auth focus colour); full-suite rollup 1767 passed / 35 failed, all in areas the redesign did not touch; all rows Done. Visual fidelity to the mockup was not judged by a human; per-task manual lists in docs/tasks/manual-tests/ are now optional impression checks. + | ID | Title | Status | |----|-------|--------| | 1 | 1 Core Foundation & Infrastructure | Done | @@ -136,14 +138,14 @@ | 21 | 21 Nablus Workshop Form - Flyer Size Adjustment | Done | | 22 | 22 Fix Footer Address - Add Missing Street Name | Done | | 23 | 23 Fix AdminNotificationService Carbon TypeError Masking Exceptions | Done | -| 24 | 24 Public-Site Redesign (PRD 1.4) | Ready for Dev | -| 24-1 | 24-1 Public Design Foundation (Stylesheet, Script, Fonts, Layout) | QA Review | -| 24-2 | 24-2 Navigation and Footer | QA Review | -| 24-3 | 24-3 Signature Balance Component | QA Review | -| 24-4 | 24-4 Home Page Sections (Hero to Latest Articles) | QA Review | -| 24-5 | 24-5 Home Booking Card (Compact Booking and Day Strip) | QA Review | -| 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 | QA Review | -| 24-10 | 24-10 Redesign Integration Verification | QA Review | +| 24 | 24 Public-Site Redesign (PRD 1.4) | Done | +| 24-1 | 24-1 Public Design Foundation (Stylesheet, Script, Fonts, Layout) | Done | +| 24-2 | 24-2 Navigation and Footer | Done | +| 24-3 | 24-3 Signature Balance Component | Done | +| 24-4 | 24-4 Home Page Sections (Hero to Latest Articles) | Done | +| 24-5 | 24-5 Home Booking Card (Compact Booking and Day Strip) | Done | +| 24-6 | 24-6 Booking Page and Booking Success | Done | +| 24-7 | 24-7 About Page | Done | +| 24-8 | 24-8 Articles and Legal Pages | Done | +| 24-9 | 24-9 Auth Pages Type and Controls | Done | +| 24-10 | 24-10 Redesign Integration Verification | Done | diff --git a/resources/css/public.css b/resources/css/public.css index 370280f..e48bbd0 100644 --- a/resources/css/public.css +++ b/resources/css/public.css @@ -12,6 +12,10 @@ body.site{ --shadow-2:0 2px 4px rgba(30,34,25,.08),0 18px 40px -12px rgba(30,34,25,.28); } html:has(body.site){scroll-behavior:smooth} +/* app.css sets overflow-x:hidden on body, which turns it into a scroll container and breaks position:sticky */ +body.site{overflow-x:clip;overflow-y:visible} +/* app.css sets the body font with html[lang] body (higher specificity than body.site) */ +html[lang] body.site{font-family:var(--body)} /* ---------- Ground and type ---------- */ body.site{ @@ -70,7 +74,8 @@ body.site .sec-head p{max-width:30em;color:var(--muted);margin:0} body.site .nav{position:sticky;top:0;z-index:50;background:rgba(244,241,234,.82);backdrop-filter:blur(14px) saturate(1.2);-webkit-backdrop-filter:blur(14px) saturate(1.2); border-bottom:1px solid transparent;transition:border-color .3s, box-shadow .3s} body.site .nav.scrolled{border-color:var(--line);box-shadow:0 8px 24px -18px rgba(30,34,25,.5)} -body.site .nav .wrap{display:flex;align-items:center;gap:28px;height:72px} +body.site .nav{box-sizing:border-box;height:72px} +body.site .nav .wrap{display:flex;align-items:center;gap:28px;height:71px} body.site .brand{display:flex;align-items:center;gap:12px;text-decoration:none} body.site .seal{width:46px;height:46px;border:2px solid #1A1A1A;box-shadow:3px 3px 5px rgba(26,26,26,.35);background:#fff center/cover no-repeat;flex:none} body.site .brand b{font-family:var(--display);font-size:1.35rem;line-height:1;display:block} @@ -360,9 +365,13 @@ body.site .legal-updated{font-size:.85rem;color:var(--muted);margin:16px 0 0} /* ---------- Auth pages: type and controls only (24-9) ---------- */ body.site-auth{font-family:"IBM Plex Sans Arabic",system-ui,sans-serif;color:#1E2219} +html[lang] body.site-auth{font-family:"IBM Plex Sans Arabic",system-ui,sans-serif} 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)} +/* Flux always renders a hidden error element, so app.css paints every field red; only a visible error should */ +body.site-auth [data-flux-field]:not(:has([data-flux-error]:not(.hidden))) input[data-flux-control]{border-color:rgba(45,54,36,.18)} +body.site-auth [data-flux-field]:not(:has([data-flux-error]:not(.hidden))) input[data-flux-control]:focus{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} @@ -371,8 +380,8 @@ body.site-auth :is(a,button,input,select,textarea):focus-visible{outline:2px sol @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} +body.site.js [data-reveal]{opacity:0;translate:0 28px;transition:opacity .9s var(--ease),translate .9s var(--ease)} +body.site.js [data-reveal].in{opacity:1;translate:none} body.site.js [data-reveal][data-d="1"]{transition-delay:.08s} body.site.js [data-reveal][data-d="2"]{transition-delay:.16s} body.site.js [data-reveal][data-d="3"]{transition-delay:.24s} @@ -389,5 +398,5 @@ body.site.js [data-reveal][data-d="5"]{transition-delay:.4s} /* ---------- Reduced motion ---------- */ @media (prefers-reduced-motion:reduce){ body.site *, body.site *::before, body.site *::after{animation:none!important;transition:none!important;scroll-behavior:auto!important} - body.site [data-reveal]{opacity:1;transform:none} + body.site [data-reveal]{opacity:1;translate:none} } diff --git a/tests/Feature/Design/AuthTypeControlsTest.php b/tests/Feature/Design/AuthTypeControlsTest.php index d8e8572..4cf8031 100644 --- a/tests/Feature/Design/AuthTypeControlsTest.php +++ b/tests/Feature/Design/AuthTypeControlsTest.php @@ -43,3 +43,12 @@ test('dashboards carry neither the stylesheet nor site-auth', function () { expect($html)->not->toContain('public.css')->not->toContain('site-auth'); } }); + +test('site fonts beat the app.css html[lang] body font and hidden Flux errors do not paint inputs red', function () { + $css = file_get_contents(resource_path('css/public.css')); + + expect($css) + ->toContain('html[lang] body.site{font-family:var(--body)}') + ->toContain('html[lang] body.site-auth{font-family:"IBM Plex Sans Arabic"') + ->toContain('[data-flux-field]:not(:has([data-flux-error]:not(.hidden))) input[data-flux-control]'); +}); diff --git a/tests/Feature/Design/PublicFoundationTest.php b/tests/Feature/Design/PublicFoundationTest.php index d369c66..65f0b76 100644 --- a/tests/Feature/Design/PublicFoundationTest.php +++ b/tests/Feature/Design/PublicFoundationTest.php @@ -55,3 +55,17 @@ test('site lang files carry the progress label', function () { expect(trans('site.progress_label', [], 'en'))->toBe('Reading progress'); expect(trans('site.progress_label', [], 'ar'))->toBe('تقدّم القراءة'); }); + +test('body does not become a scroll container, so the sticky navigation sticks', function () { + $css = file_get_contents(resource_path('css/public.css')); + + expect($css)->toContain('overflow-x:clip')->toContain('box-sizing:border-box;height:72px'); +}); + +test('reveal uses the translate property so hover lifts (transform) are not overridden', function () { + $css = file_get_contents(resource_path('css/public.css')); + + expect($css)->toContain('body.site.js [data-reveal]{opacity:0;translate:0 28px') + ->toContain('body.site.js [data-reveal].in{opacity:1;translate:none}') + ->not->toContain('[data-reveal].in{opacity:1;transform:none}'); +});