docs: client-approved public-site redesign — PRD 1.4, UX spec v2.0, architecture §6.2, tasks 24-x Ready for Dev

Co-Authored-By: Claude Haiku 5.5 <noreply@anthropic.com>
This commit is contained in:
Naser Mansour
2026-10-31 18:23:02 +02:00
parent caec396fa4
commit 3d1fe40be6
17 changed files with 1761 additions and 5 deletions
+64 -2
View File
@@ -1,7 +1,7 @@
# Libra Law Firm - Architecture Document
**Version:** 1.1
**Date:** December 21, 2025
**Version:** 1.2
**Date:** October 31, 2026
**Status:** Approved
**Domain:** libra.ps
@@ -13,6 +13,7 @@
|------|---------|-------------|--------|
| Dec 21, 2025 | 1.0 | Initial architecture document | Winston (Architect) |
| Dec 21, 2025 | 1.1 | Added CI/CD, rollback procedures, monitoring, timezone handling, alternatives analysis | Winston (Architect) |
| Oct 31, 2026 | 1.2 | Added §6.2 Public-site presentation layer (PRD 1.4 redesign, ux-design.md v2.0 Part A) | Jarvis |
---
@@ -1008,6 +1009,67 @@ libra/
└── build/ # Compiled assets
```
> §6.1 is the original (Dec 2025) plan. As built, the public layout is
> `resources/views/components/layouts/public.blade.php` (not `guest.blade.php`) and public pages
> are Volt components under `resources/views/livewire/pages/`. §6.2 is current.
### 6.2 Public-Site Presentation Layer (redesign, PRD 1.4)
**Overview.** The October 2026 redesign (PRD Update 1.4; `docs/ux-design.md` Part A) is a
presentation-only change to the public pages. No route, model, migration, service, mail or job
changes. The redesign is isolated from the admin and client dashboards by loading its stylesheet
and script only from the public and auth layouts, and by scoping every rule under a body class.
**Components**
| Component | Path | Owns |
|---|---|---|
| Public stylesheet | `resources/css/public.css` (new Vite entry) | Part A tokens (`--forest`, `--gold`, …), linen ground, type, buttons, sections, cards, docket rows, booking card, footer, reveal and reduced-motion rules. Every selector is scoped under `body.site`; auth-page rules under `body.site-auth`. |
| Public script | `resources/js/public.js` (new Vite entry) imports `resources/js/site/balance.js`, `reveal.js`, `progress.js` | The balance SVG builder and damped spring, hero pointer response, finale scroll mapping, IntersectionObserver reveal, reading-progress rule, nav scrolled state. Initialises on `livewire:navigated` (fires on first load and after every `wire:navigate`) and tears down listeners on `livewire:navigating`. |
| Font partial | `resources/views/partials/site-fonts.blade.php` (new) | Google Fonts link for Markazi Text (400–700) and IBM Plex Sans Arabic (300–600), `display=swap`. |
| Public layout | `resources/views/components/layouts/public.blade.php` (changed) | Body class `site`; includes the font partial and `@vite(['resources/css/public.css','resources/js/public.js'])` after `partials.head`; drops the 1200px content wrapper and the 64px fixed-nav spacer (nav becomes sticky); adds the progress rule element. |
| Auth layouts | `resources/views/components/layouts/auth/split.blade.php`, `card.blade.php`, `simple.blade.php` (changed) | Body class `site-auth`; font partial; `public.css` only (no public script). Composition unchanged. |
| Navigation / footer | `resources/views/components/navigation.blade.php`, `footer.blade.php` (restyled in place; used only by the public layout) | Part A nav and footer. Keeps the existing Alpine mobile menu, auth-aware links and language toggle. |
| Site Blade components | `resources/views/components/site/` (new): `balance.blade.php` (SVG mount point; props `id`, `size`, `mode` = `hero` / `finale` / `static`), `section-head.blade.php` (article label + h2 + lede), `post-card.blade.php` (text-only post card) | Shared markup for the public pages. |
| Redesign copy | `lang/ar/site.php`, `lang/en/site.php` (new) | Strings introduced by the redesign only (hero line, trust strip, pillars, article labels, card titles, booking lede, nav and footer labels). Existing keys in `home.php`, `about.php`, `booking.php`, `footer.php`, `navigation.php` are reused, never duplicated or edited. `navigation.php` keys used by the dashboards are untouched. |
| Photography | `public/images/site/olive-tree.jpg`, `embroidery-hoop.jpg`, `olives.jpg`, `hills.jpg` (new; extracted from the data URIs in `docs/ux-mockup.html`) | Production images (Unsplash licence). Portrait stays `public/images/huda-armouche.jpg`; seal uses `public/images/logo.png`. |
| Guest booking | `resources/views/livewire/pages/booking.blade.php` (changed) | Gains `public bool $compact = false` (mount parameter). `compact` renders the one-screen home layout; default renders the `/booking` page layout. Validation, captcha, one-per-day rule, confirm step and redirect to `booking.success` are shared and unchanged. |
| Availability calendar | `resources/views/livewire/availability-calendar.blade.php` (changed) | Gains `public string $variant = 'month'`. `strip` lists the next 14 dates whose `AvailabilityService::getDateStatus()` is available (scanning at most 60 days ahead) and their `getAvailableSlots()`; `month` is the existing grid. Default stays `month`, so the client dashboard's booking page (`resources/views/livewire/client/consultations/book.blade.php`) is unaffected; its public restyle applies only under `body.site`. |
**Data flows**
1. Request to a public route → Volt page with `#[Layout('components.layouts.public')]` → layout
loads `app.css` + `app.js` (unchanged, via `partials.head`), then `public.css` + `public.js`.
2. Home `/` → `Post::published()->latest('published_at')->take(3)` (existing) → `x-site.post-card`;
embeds `<livewire:pages.booking :compact="true" />`, which embeds
`<livewire:availability-calendar variant="strip" />`. Slot choice → `$parent.selectSlot(date,
time)` (existing contract) → submit → existing confirm step → existing `submit()` → redirect
`/booking/success`.
3. `public.js` on `livewire:navigated` → finds `[data-balance]` mounts → builds the SVG → binds
pointer (hero, fine pointers only) and scroll (finale) → spring per `requestAnimationFrame`.
`prefers-reduced-motion: reduce` → every balance drawn level, no listeners bound.
4. Language: unchanged — `/language/{locale}` sets the session locale; layouts set `lang` and
`dir`.
**Module boundaries**
- The redesign owns `public.css`, `public.js`, `resources/js/site/*`, `components/site/*`,
`lang/*/site.php`, `public/images/site/*`, and the restyle of the public views listed above.
- It does not own and must not change: `resources/css/app.css` `@theme` tokens and `.btn-*`
classes, Flux configuration, anything under `resources/views/livewire/admin/` or
`livewire/client/`, `components/layouts/app*`, emails, PDFs,
`resources/views/livewire/pages/forms/nablus-workshop.blade.php`, `layouts/standalone.blade.php`,
routes, models, services (read-only use of `AvailabilityService`), migrations.
- Pages restyled: `livewire/pages/home.blade.php`, `about.blade.php`, `booking.blade.php`,
`booking-success.blade.php`, `posts/index.blade.php`, `posts/show.blade.php`,
`resources/views/pages/legal.blade.php` (and the `terms`/`privacy` wrappers if they render
markup).
- `partials/head.blade.php`: `theme-color` corrected to `#2D3624` (was the superseded
`#4A4A42`); nothing else changes there, because the dashboards share it.
**Open gaps** — none blocking. The four rulings (photography, 14-day strip, unmocked pages, auth
scope) are recorded in `docs/ux-design.md` Part A *Open Questions* and the project ledger.
---
## 7. Authentication & Authorization