diff --git a/CLAUDE.md b/CLAUDE.md index eb0827d..467bf8e 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -116,7 +116,7 @@ php artisan make:model ModelName -mf - `app/Enums/` - UserType, UserStatus, ConsultationType, ConsultationStatus, PaymentStatus, TimelineStatus, PostStatus - `docs/prd.md` - Full product requirements document - `docs/architecture.md` - Complete architecture document -- `docs/ux-design.md` - Design system reference (colors, typography, layout, components — retrospective, written 2026-09-27) +- `docs/ux-design.md` - Design spec. **Part A** = the public-site redesign (approved by the client 2026-10-31, mockup `docs/ux-mockup.html`); **Part B** = the pre-redesign system, which still governs the dashboards, emails and the Nablus form - `docs/tasks/` - **Current task/status tracker** (`statuses.md` is the status source of truth). One row per epic (parent) and per story (subtask), e.g. `3.md` / `3-4.md`. - `docs/stories/`, `docs/epics/`, `docs/qa/gates/` - **Legacy.** Original BMAD-agent build records (98→102 stories across 16 epics). Kept for implementation history and traceability, no longer the status source — `docs/tasks/statuses.md` superseded them 2026-09-27. `.bmad-core/` and `.claude/commands/BMad/` are the retired BMAD toolchain, also kept but unused. @@ -246,7 +246,25 @@ Located in `app/Notifications/`: - **Cascade deletes:** User deletion cascades to consultations, timelines, notifications - **Bilingual required:** All user-facing text needs Arabic and English +## Public-site redesign (PRD 1.4, tasks 24-x) + +The public pages (home, about, posts, booking, legal) and the auth pages' type/controls follow +`docs/ux-design.md` Part A; the map is `docs/architecture.md` §6.2. Boundaries that keep the +dashboards safe: +- Redesign styles live in `resources/css/public.css`, every selector under `body.site` (auth: + `body.site-auth`); its script is `resources/js/public.js` + `resources/js/site/*`, initialised on + `livewire:navigated`. Both load only from the public (and, CSS only, auth) layouts. +- Never edit `resources/css/app.css` `@theme`/`.btn-*`, `components/language-toggle.blade.php`, + or `lang/*/navigation.php` for the redesign — the dashboards share them. New public copy goes in + `lang/{ar,en}/site.php`. +- `availability-calendar` defaults to `variant="month"` (the client dashboard uses it); the home + page uses `variant="strip"`. `pages.booking` takes `compact` for the home card; booking rules are + shared and unchanged. + ## Design Requirements (from PRD) + +Below: the dashboards' palette and rules. Public pages: Part A of `docs/ux-design.md`. + - **Color scheme:** - Dark Forest Green (#2D3624) - Header/Footer backgrounds - Warm Gold (#A68966) - CTA buttons, links, accents diff --git a/docs/architecture.md b/docs/architecture.md index 2b38280..929c9a1 100644 --- a/docs/architecture.md +++ b/docs/architecture.md @@ -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 ``, which embeds + ``. 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 diff --git a/docs/prd.md b/docs/prd.md index 7cf0ead..e4bb992 100644 --- a/docs/prd.md +++ b/docs/prd.md @@ -1,7 +1,7 @@ # Product Requirements Document (PRD) ## Libra Law Firm Website -**Version:** 1.2 +**Version:** 1.4 **Date:** January 3, 2026 **Domain:** libra.ps **Prepared for:** Development Team & Client Review @@ -1106,6 +1106,7 @@ All emails in both Arabic and English based on user preference: | 1.1 | Dec 20, 2025 | Added brand identity section, clarified booking rules (1/day, 45min), multiple timelines, account management (deactivate/delete), exports, analytics, Terms/Privacy pages | Development Team | | 1.2 | Jan 3, 2026 | Added guest booking functionality: public booking form at /booking, custom captcha, 1-per-day limit, guest email notifications, admin guest booking management | Development Team | | 1.3 | Sep 27, 2026 | Added standalone Nablus workshop registration form (unlinked page at /forms/nablus-workshop) — see Update below | Development Team | +| 1.4 | Oct 31, 2026 | Public-site redesign approved by the client (mockup v3): new visual system for the public pages, compact booking card on the home page — see Update below | Development Team | --- @@ -1145,4 +1146,59 @@ None outstanding — all decisions confirmed directly with Naser in the same ses --- +## Update — Version 1.4 +**Date:** 2026-10-31 + +### New Features Added + +**Public-site redesign.** ElenosLabs proposed a redesign of Libra's public website (mockup v3, +`docs/ux-mockup.html`); the client approved it on 2026-10-31. Scope answers given by Naser on +2026-10-31: scope "Public site" (home, about, posts, booking, auth); brand "Keep logo, evolve +rest" (the logo and the forest/gold/cream palette stay; type, layout and motion change); driver +"Our pitch". Naser's constraint on content: "we dont need to promice smth we wont deliver" — every +claim on the new pages is backed by existing behaviour. The full visual specification is +`docs/ux-design.md` Part A. + +- **New visual system on every public page** — `/`, `/about`, `/posts`, `/posts/{post}`, + `/booking`, `/booking/success`, `/page/{slug}`: Markazi Text (display) and IBM Plex Sans Arabic + (body); the brand palette used in full-bleed forest bands, gold rules and a linen cream ground; + sections numbered as articles; a sticky translucent navigation with a reading-progress rule; a + four-column forest footer. +- **Signature balance** — an engraved-gold scales-of-justice graphic over olive-tree photography in + the home hero, settling into balance on load and responding to the pointer; a second balance in + the booking card comes level as the reader arrives. All motion respects + `prefers-reduced-motion`. +- **Redesigned home page** — hero, pillars (Justice, Dignity, Advocacy), founder, services docket, + vision with photography, values, latest three articles (text-only cards), and an embedded + booking card. +- **Compact booking on the home page** — the home page embeds the existing guest-booking form as + one screen (name, phone, email, a 14-day strip of days with free slots, slot buttons, case + summary, captcha), with the same rules as `/booking` (required fields, 20-character minimum + summary, captcha, one booking per email per day, slots from the availability settings, the + confirm step, the success page). This realises §5.1's "Embedded simplified booking form". +- **Auth pages** — the new type and form controls; the split layout is unchanged. +- **Production photography** — four licensed Unsplash photographs (olive tree, embroidery hoop, + olives, hills) and the founder's existing portrait. + +### Scope Changes + +- §5.1 and §7 (Design Requirements) are superseded for the public pages by `docs/ux-design.md` + Part A. §7's typography (Cairo/Montserrat), button radius and card specs continue to apply to + the admin and client dashboards, which are unchanged. +- §5.2 navigation gains a "Services" link (to the home page's services section); the menu labels + on the public site read Home, About, Services, Articles, Booking. +- Out of scope: admin and client dashboards, emails, PDF exports, `/forms/nablus-workshop`, any + backend or database change, post images or categories, new content beyond the redesign's + section labels and short lines approved in the mockup. + +### Open Questions + +None blocking. Rulings recorded in the project ledger (2026-10-31): the mockup's Unsplash photos +ship to production (replaceable by the client's own later); the home day strip covers the next 14 +days with free slots; pages not shown in the mockup are composed from its components with their +existing content; auth pages change type and controls only. The build price is not yet set (a +commercial matter, not a product requirement). + +--- + **END OF DOCUMENT** diff --git a/docs/tasks/24-1.md b/docs/tasks/24-1.md new file mode 100644 index 0000000..3fdee7a --- /dev/null +++ b/docs/tasks/24-1.md @@ -0,0 +1,147 @@ +--- +id: 24-1 +title: 24-1 Public Design Foundation (Stylesheet, Script, Fonts, Layout) +status: Ready for Dev +date: 2026-10-31 +parent: 24 +--- + +## Description + +Create the shared foundation every later redesign subtask builds on. It must be loaded only by +the public layout (and, for the stylesheet only, by the auth layouts in task 24-9), and every rule +must be scoped under `body.site` so the admin and client dashboards are unaffected. + +The approved visual reference is the mockup file `docs/ux-mockup.html` (committed in `caec396`). +Where this task says "port lines X–Y", copy those CSS rules from that file and prefix every +selector with `body.site ` (for example `.btn-gold` → `body.site .btn-gold`; `:root{…}` → +`body.site{…}`; `body{…}` → `body.site{…}`; `html[dir=ltr] .x` → `html[dir=ltr] body.site .x`; +`html[lang=en] .x` → `html[lang=en] body.site .x`). The mockup's lines contain no images, so line +numbers are exact. + +### Files to create + +1. **`resources/css/public.css`** — contains, in this order: + - Tokens on `body.site` (from mockup lines 12–29): + `--forest:#2D3624; --forest-2:#232A1C; --gold:#A68966; --gold-ink:#8A7555; --gold-lt:#C4A882; + --cream:#F4F1EA; --olive:#4A5D23; --ink:#1E2219; --muted:#5B6152; --line:rgba(45,54,36,.14); + --display:"Markazi Text","Times New Roman",serif; --body:"IBM Plex Sans Arabic",system-ui,sans-serif; + --r:10px; --ease:cubic-bezier(.2,.7,.2,1); + --shadow-1:0 1px 2px rgba(30,34,25,.06),0 4px 14px rgba(30,34,25,.06); + --shadow-2:0 2px 4px rgba(30,34,25,.08),0 18px 40px -12px rgba(30,34,25,.28);` + - Page ground and type on `body.site` (port lines 32–39): `font-family:var(--body); + color:var(--ink); font-size:17px; line-height:1.75; background-color:var(--cream)` plus the + linen weave `background-image: repeating-linear-gradient(0deg, rgba(45,54,36,.025) 0 1px, + transparent 1px 3px), repeating-linear-gradient(90deg, rgba(45,54,36,.022) 0 1px, transparent + 1px 4px)`. This overrides the inline `style="font-family: var(--font-…)"` on the body, so the + layout's inline style is removed (see layout changes below). + - Port lines 40–50 (img, links, `.wrap`, skip link, focus-visible, h1–h3, `.eyebrow`, + `.art-no`). `.wrap` = `max-width:1200px; margin-inline:auto; padding-inline:28px`. + Focus = `outline:2px solid var(--gold); outline-offset:3px; border-radius:4px`. + - Buttons: port lines 52–68 (`.btn`, `.btn-gold` with shimmer `::after`, `.btn-ghost`, + `.on-dark .btn-ghost`, `.btn .arr` and LTR mirroring). Class names `.btn`, `.btn-gold`, + `.btn-ghost` do not exist in `resources/css/app.css` (which uses `.btn-primary`, + `.btn-secondary`), and they are scoped under `body.site`, so there is no collision. + - Progress rule: port lines 70–73 (`#hem` → rename to `.site-progress`; fixed, top 0, z 60, + height 2px, gradient `linear-gradient(90deg,#8A7555,#E2CDA4,#A68966)`, `transform:scaleX(0)`, + origin right; `html[dir=ltr]` origin left). + - Sections: port lines 139–144 (`section{position:relative}`, `.sec{padding:120px 0}`, + `.sec-head`, `.sec-head h2`, `.sec-head p`). + - Reveal: port lines 286–290, changed so content is 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}`, + and the `data-d` 1–5 delays (.08s, .16s, .24s, .32s, .4s). + - Responsive base: at `max-width:760px`: `body.site{font-size:16px}`, + `body.site .wrap{padding-inline:18px}`, `body.site .sec{padding:80px 0}`. + - Reduced motion (port lines 324–327): under `@media (prefers-reduced-motion:reduce)`, + `body.site *, body.site *::before, body.site *::after{animation:none!important; + transition:none!important; scroll-behavior:auto!important}` and + `body.site [data-reveal]{opacity:1;transform:none}`. + - `html:has(body.site){scroll-behavior:smooth}`. +2. **`resources/js/public.js`** — imports `./site/reveal.js` and `./site/progress.js`, and calls + each module's `init()` on the `livewire:navigated` document event (Livewire 3 dispatches it on + the first page load and after every `wire:navigate`), and each module's `destroy()` on + `livewire:navigating`. On init it adds the class `js` to `document.body`. +3. **`resources/js/site/reveal.js`** — exports `init()`/`destroy()`. If + `matchMedia('(prefers-reduced-motion: reduce)').matches`, add class `in` to every + `[data-reveal]` and return. Otherwise create one `IntersectionObserver` with + `rootMargin: '0px 0px -8% 0px'`; when an observed element intersects, add class `in` and + unobserve it. `destroy()` disconnects the observer. +4. **`resources/js/site/progress.js`** — exports `init()`/`destroy()`. Adds a passive `scroll` + listener on `window` that sets `.site-progress` `style.transform = scaleX(p)` where + `p = max > 0 ? scrollY / max : 1` and `max = document.documentElement.scrollHeight - innerHeight`, + and toggles class `scrolled` on `#site-nav` when `scrollY > 8` (if that element exists; it is + added in task 24-2). Runs once on init. `destroy()` removes the listener. +5. **`resources/views/partials/site-fonts.blade.php`** — exactly: + ```html + + + + ``` +6. **`lang/ar/site.php`** and **`lang/en/site.php`** — each `` becomes `` (remove `bg-background` + and the inline `style="font-family: …"`). + - Immediately after the skip link add + ``. + - Remove the spacer `
` (the navigation becomes sticky in 24-2; until + then the existing fixed navigation may overlap the first 64px — acceptable only between + 24-1 and 24-2). + - `
` keeps `id="main-content" role="main" class="flex-1" tabindex="-1"` but its child + `
` is removed, so + `{{ $slot }}` is rendered directly inside `
`. +9. Because the wrapper is gone, wrap the root content of each existing public page that is not + yet redesigned in `
…
` so these pages keep a contained width until + their own subtask restyles them: + - `resources/views/livewire/pages/home.blade.php` + - `resources/views/livewire/pages/about.blade.php` (also remove the negative margins + `-mx-4 sm:-mx-6 lg:-mx-8 -mt-6 sm:-mt-8` from its first `
`) + - `resources/views/livewire/pages/booking.blade.php` + - `resources/views/livewire/pages/booking-success.blade.php` + - `resources/views/livewire/pages/posts/index.blade.php` + - `resources/views/livewire/pages/posts/show.blade.php` + - `resources/views/pages/legal.blade.php` + - `resources/views/pages/terms.blade.php` + - `resources/views/pages/privacy.blade.php` + (`resources/views/pages/booking.blade.php` is a dead placeholder — `/booking` is served by the + Volt page — and is left untouched.) + For a Volt page whose root is a single element, put the wrapper inside the root element so the + component keeps one root. +10. **`resources/views/partials/head.blade.php`** — change + `` to ``. + Change nothing else in this file (the dashboards share it). + +Do not modify `resources/css/app.css` or any file under `resources/views/livewire/admin/`, +`resources/views/livewire/client/`, `resources/views/components/layouts/app*`. + +## Acceptance Criteria + +- [ ] `npm run build` succeeds and `public/build/manifest.json` contains entries for + `resources/css/public.css` and `resources/js/public.js`. +- [ ] Every selector in `resources/css/public.css` is scoped under `body.site` (or + `html[...] body.site`, or `html:has(body.site)`), verify: + `grep -nE '^[^@/ }].*\{' resources/css/public.css | grep -v 'body.site'` returns nothing. +- [ ] The HTML of `/` contains ``, every `` has a non-empty `alt`, and every + interactive element in the navigation, footer and booking card is reachable by Tab with a + visible gold focus ring. +- [ ] Both bookings in item 2 succeed and appear in `/admin/bookings/pending`. +- [ ] The pages in item 3 contain no `public.css`, `public.js`, `class="site` or `site-auth`, and + `git diff BASE -- resources/css/app.css resources/views/livewire/admin resources/views/livewire/client resources/views/components/layouts/app.blade.php resources/views/components/layouts/app resources/views/livewire/pages/forms` + (BASE = the commit recorded before task 24-1) is empty. +- [ ] With reduced motion emulated, all `[data-reveal]` content is visible on load and every + balance is level; without it, the hero balance settles and the finale levels on scroll. +- [ ] After five `wire:navigate` hops ending on `/`, the hero balance and reveal still work and the + finale still levels. +- [ ] Contrast: body text on cream, `--gold-lt` text on forest, and the gold button text meet + WCAG AA (4.5:1 for body text, 3:1 for large text) — measured, values noted in the task's QA + record. +- [ ] No page contains the text "Unsplash" or "mockup". + +## Sub-tasks + +None. diff --git a/docs/tasks/24-2.md b/docs/tasks/24-2.md new file mode 100644 index 0000000..867bc10 --- /dev/null +++ b/docs/tasks/24-2.md @@ -0,0 +1,146 @@ +--- +id: 24-2 +title: 24-2 Navigation and Footer +status: Ready for Dev +date: 2026-10-31 +parent: 24 +--- + +## Description + +Restyle the public navigation and footer to the approved redesign. Both components are used only +by `resources/views/components/layouts/public.blade.php`, so they are restyled in place. Keep all +existing behaviour: the Alpine `x-data="{ mobileMenuOpen: false }"` menu with its +`x-trap.inert.noscroll`, `@click.away` and `@keydown.escape.window` handling, the `@auth` branch +(Dashboard link to `route('admin.dashboard')` or `route('client.dashboard')` by +`auth()->user()->isAdmin()`, and the logout `
`), +the language toggle's `/language/{locale}` links, and `wire:navigate` on internal links. + +All CSS goes in `resources/css/public.css` (created in 24-1), every selector prefixed with +`body.site `. Port the CSS from `docs/ux-mockup.html`: navigation lines 75–98, footer lines +273–284, and the responsive nav/footer rules inside lines 293–323 (`.links` hidden and +`.menu-btn` shown at ≤1100px; `.nav .btn` and `.login` hidden at ≤760px; footer grid 2 columns at +≤1100px and 1 column at ≤760px). + +### Navigation — `resources/views/components/navigation.blade.php` + +- Root: `