Files
libra/docs/tasks/24-4.md
T

197 lines
14 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
---
id: 24-4
title: 24-4 Home Page Sections (Hero to Latest Articles)
status: Ready for Dev
date: 2026-10-31
parent: 24
---
## Description
Rebuild `resources/views/livewire/pages/home.blade.php` as the approved redesign, sections 1–7
(hero, pillars, founder, services, vision, values, latest articles). Section 8, the booking card,
is task 24-5; leave a placeholder comment `{{-- booking card: task 24-5 --}}` where it goes. Keep
the component's PHP class as it is (`#[Layout('components.layouts.public')]`, `with()` returning
`latestPosts` = `Post::published()->latest('published_at')->take(3)->get()`). Remove the
temporary `<div class="wrap py-8">` wrapper added in 24-1: each section is full-bleed and holds a
`<div class="wrap">`.
The visual reference is `docs/ux-mockup.html` (commit `caec396`). Port the CSS for each section
from the line ranges below into `resources/css/public.css`, every selector prefixed with
`body.site `, and port the matching responsive rules from lines 293–323. Put `data-reveal` and
`data-d` attributes on the same elements as the mockup (lines 358–506).
### Photography — create `public/images/site/`
Extract these JPEG data URIs from `docs/ux-mockup.html` and save them, decoded, as files (a short
script reading the file and base64-decoding the `src="data:image/jpeg;base64,…"` value on each
line is enough; do not commit the script):
| Mockup line | `<img>` | Save as |
|---|---|---|
| 377 | hero olive tree | `public/images/site/olive-tree.jpg` |
| 447 | embroidery hoop | `public/images/site/embroidery-hoop.jpg` |
| 455 | olives on a branch | `public/images/site/olives.jpg` |
| 459 | hills and road | `public/images/site/hills.jpg` |
The founder portrait uses the existing `public/images/huda-armouche.jpg`. The images are from
Unsplash (licence permits commercial use without attribution); show no credit line.
### Sections (in order, inside the root `<div>`)
1. **Hero** — `<section class="hero" id="top">`; CSS lines 100–125. Two-column grid
(`1fr 1.08fr`, gap 56px; one column ≤1100px). Start column: `.eyebrow` = `site.hero_eyebrow`;
`<h1>` = `{{ __('site.hero_title_a') }}<em>{{ __('site.hero_title_em') }}</em>{{ __('site.hero_title_b') }}`
(the `em` is upright, `--olive`, with `text-decoration: underline dashed var(--gold) .07em;
text-underline-offset:.28em`); `<p class="lede">` = `home.intro`; CTA row: gold button
`home.cta_book` → `#book` with the arrow SVG (mockup line 366), ghost button
`home.cta_services` → `#services`; `.trust` strip with three items, each
`<strong>` + `<span>`: (`site.trust_1_title`, `site.trust_1_text`), (`site.trust_2_title`,
`site.trust_2_text`), (`site.trust_3_title`, `site.trust_3_text`). End column `.hero-art`:
`<figure class="frame">` (aspect 4/4.6, radius `999px 999px 18px 18px`, forest ground,
gradient veil `::before` from `rgba(35,42,28,.35)` to `.9`), containing
`<img src="/images/site/olive-tree.jpg" alt="{{ __('site.alt_olive_tree') }}">` (filter
`saturate(.75) contrast(1.05)`, `scale(1.08)`), `<span class="glow">` (420px radial gold
glow), `<x-site.balance mode="hero" :label="__('site.balance_label')" id="scales" />`
positioned `inset:10% 8% 12%`, and `<figcaption>` = `site.frame_caption` (display italic,
cream .78). Then `<div class="tag">` with `<span class="dot">` (olive, pulsing) and
`site.frame_tag`.
2. **Pillars band** — `<section class="band on-dark" aria-label="{{ __('site.pillars_label') }}">`;
CSS lines 127–137. Three `.pillar` columns: (`site.pillar_justice`, `site.pillar_justice_text`),
(`site.pillar_dignity`, `site.pillar_dignity_text`), (`site.pillar_advocacy`,
`site.pillar_advocacy_text`), each title preceded by `<span class="gem">` (CSS line 210).
3. **Founder** — `<section class="sec" id="founder">`; CSS lines 146–157. Portrait
`/images/huda-armouche.jpg` (alt `home.lawyer_name`) with `.namecard`
(`<b>` `home.lawyer_name`, `<span>` `site.founder_role`). Text column: `.art-no`
`site.art_founder`; `<h2>` `home.about_title`; `<blockquote>` `site.founder_quote`;
paragraphs `home.lawyer_bio` and `home.lawyer_bio_2`; ghost button `site.founder_cta` →
`route('about')`.
4. **Services docket** — `<section class="sec" id="services" style="padding-top:40px">`;
CSS lines 159–174. `x-site.section-head` (see below) with label `site.art_services`, title
`home.services_subtitle`, lede `site.services_lede`. Four `<a class="row" href="#book">` rows:
number `01`–`04` (`.n`), `<h3>` title, `.chips` of the items, `.go` arrow circle. Rows in order:
(`home.service_consultation_title`, `home.service_consultation_items`),
(`home.service_family_title`, `home.service_family_items`),
(`home.service_civil_title`, `home.service_civil_items`),
(`home.service_business_title`, `home.service_business_items`). Items are arrays — render each
as `<span class="chip">`.
5. **Vision** — `<section class="sec fabric" id="mission">`; CSS lines 176–197. Text column:
`.art-no` `site.art_vision`, `<h2>` `site.vision_title`, `<p class="big">` `site.vision_text`;
beside it `.hoop` with `/images/site/embroidery-hoop.jpg` (alt `site.alt_hoop`; filter
`hue-rotate(-140deg) saturate(.55) sepia(.25)`). Below, `.three` grid of `<article class="card">`:
(a) `.ph.motif-ph` containing `<x-site.balance mode="static" />` (150×150px) and label
`site.card_institution_label`, title `site.card_institution_title`, text
`site.card_institution_text`; (b) `.ph` with `/images/site/olives.jpg` (alt `site.alt_olives`),
label `site.card_society_label`, title `site.card_society_title`, text `site.card_society_text`;
(c) `.ph` with `/images/site/hills.jpg` (alt `site.alt_hills`), label
`site.card_diaspora_label`, title `site.card_diaspora_title`, text `site.card_diaspora_text`.
6. **Values** — `<section class="sec" id="values">`; CSS lines 199–212. Section head: label
`site.art_values`, title `home.values_title`, lede `home.values_subtitle`. `.sampler` grid of six
`.val` cards, each `<span class="medal">` with the line icon and `<b>` =
`home.values.<key>.title`, keys in order `integrity`, `justice`, `knowledge`, `empowerment`,
`professionalism`, `innovation`. Icons: the inline SVGs on mockup lines 474–479 in the same
order (24×24 viewBox, `aria-hidden="true"`, stroke `--gold-ink` 1.5, no fill). Replace the
current `flux:icon` usage.
7. **Latest articles** — `<section class="sec" id="posts" style="padding-top:20px">`; CSS lines
214–234. Head: label `site.art_articles`, title `home.posts_title`, and in place of the lede a
ghost button `home.view_all_posts` → `route('posts.index')`. If `$latestPosts` is not empty:
`.posts` grid of `<x-site.post-card :post="$post" />`; otherwise a `<p>` with
`home.posts_empty` (muted, centred).
### Components to create
- **`resources/views/components/site/section-head.blade.php`** — props `label`, `title`,
`lede` (nullable); renders
`<div class="sec-head"><div><span class="art-no" data-reveal>{{ $label }}</span><h2 data-reveal data-d="1">{{ $title }}</h2></div>`
then either `<p data-reveal data-d="2">{{ $lede }}</p>` or the `$slot` (for the button), then
`</div>`.
- **`resources/views/components/site/post-card.blade.php`** — prop `post` (App\Models\Post);
`<a class="post" href="{{ route('posts.show', $post) }}" wire:navigate data-reveal>` →
`<div class="bd">` with `<span class="meta">` = the published date
(`$post->published_at?->translatedFormat('j F Y')`), `<h3>` = `$post->getTitle()`, `<p>` = an
excerpt of `strip_tags($post->getBody())` limited to 140 characters (`Str::limit`), and
`<span class="more">` = `home.read_more`. Text-only: no image element.
### Language keys — add to `lang/ar/site.php` and `lang/en/site.php`
| Key | ar | en |
|---|---|---|
| `hero_eyebrow` | ليبرا للحقوق · فلسطين | Libra for Rights · Palestine |
| `hero_title_a` | العدالة␠ | Justice is a␠ |
| `hero_title_em` | ممارسةٌ يومية | daily practice |
| `hero_title_b` | ، لا مبدأٌ نظري. | , not a theory. |
| `trust_1_title` | أفراد وشركات | Individuals & companies |
| `trust_1_text` | استشارات وتمثيل | Consultations and representation |
| `trust_2_title` | المرأة والأسرة | Women & family |
| `trust_2_text` | دعم قانوني متخصص | Specialised legal support |
| `trust_3_title` | عربي · English | Arabic · English |
| `trust_3_text` | خدمة بلغتين | Bilingual service |
| `alt_olive_tree` | شجرة زيتون معمّرة بين صخور كلسية | An ancient olive tree among limestone rocks |
| `balance_label` | ميزان العدالة | The scales of justice |
| `frame_caption` | لكلّ حقٍّ وزنُه | Every right carries its weight |
| `frame_tag` | استشارات حضورية أو عن بُعد | Consultations in person or remotely |
| `pillars_label` | ركائزنا | Our pillars |
| `pillar_justice` | العدالة | Justice |
| `pillar_justice_text` | الإنصاف، والمساءلة، وسيادة القانون. | Fairness, accountability and the rule of law. |
| `pillar_dignity` | الكرامة | Dignity |
| `pillar_dignity_text` | القيمة الأصيلة لكل إنسان. | The inherent worth of every person. |
| `pillar_advocacy` | الدفاع | Advocacy |
| `pillar_advocacy_text` | انخراطٌ فاعل، وقولُ الحق في وجه السلطة. | Active engagement, and speaking truth to power. |
| `art_founder` | المادة ٠١ — المؤسِّسة | Article 01 — The founder |
| `founder_role` | المؤسِّسة · محامية | Founder · Attorney at Law |
| `founder_quote` | «العدالة ممارسة يومية، وليست مجرد مبدأ نظري.» | “Justice is a daily practice, not merely a theoretical principle.” |
| `founder_cta` | اقرأ قصتنا | Read our story |
| `art_services` | المادة ٠٢ — الخدمات | Article 02 — Services |
| `services_lede` | ممارسة قانونية أصيلة، تقوم على البحث والمعرفة الميدانية. | Traditional legal practice, combined with research-driven insight. |
| `art_vision` | المادة ٠٣ — الرؤية | Article 03 — Vision |
| `vision_title` | منسوجةٌ من نسيج المجتمع | Woven from the fabric of society |
| `vision_text` | ليبرا نسيجٌ أصيل من المجتمع، تتقصّى مشكلاته وتوثّقها وتكشف جذورها، وتقدّم حلولاً عملية لرأب أوجاعه مهما صغرت، عبر العمل التشاركي والبحث الميداني الحقيقي. | Libra investigates society's problems, documents them, uncovers their roots, and offers practical solutions to mend social pains — however small — through collaborative work and genuine field research. |
| `alt_hoop` | تطريز بغرزة الصليب مشدود على طارة خشبية | Cross-stitch embroidery stretched on a wooden hoop |
| `card_institution_label` | لمؤسستنا | For our institution |
| `card_institution_title` | القانون والبحث والميدان | Law, research and fieldwork |
| `card_institution_text` | نلتقط نبض المجتمع ونحوّل تحدياته إلى معرفة وحلول قانونية مبتكرة. | Capturing society's pulse and turning its challenges into knowledge and innovative legal solutions. |
| `alt_olives` | ثمار زيتون على غصن | Olives ripening on a branch |
| `card_society_label` | للمجتمع | For society |
| `card_society_title` | شريكٌ موثوق للقضاء | A trusted partner to the judiciary |
| `card_society_text` | نعيد وصل المجتمع بتاريخه وإرثه القانوني. | Reconnecting society with its history and legal heritage. |
| `alt_hills` | تلال وطريق متعرّج عند الغروب | Hills and a winding road at sunset |
| `card_diaspora_label` | لفلسطينيي الشتات | For Palestinians in the diaspora |
| `card_diaspora_title` | عودةٌ إلى الأرض والعائلة | Back to the land and the family |
| `card_diaspora_text` | نساعد الفلسطينيين في الخارج على البحث في عائلاتهم وتاريخهم وأراضيهم. | Helping Palestinians abroad research their families, their history and their land. |
| `art_values` | المادة ٠٤ — القيم | Article 04 — Values |
| `art_articles` | المادة ٠٥ — المقالات | Article 05 — Articles |
`␠` marks a trailing space that must be kept in the value.
### Files
- Create: `public/images/site/olive-tree.jpg`, `public/images/site/embroidery-hoop.jpg`,
`public/images/site/olives.jpg`, `public/images/site/hills.jpg`,
`resources/views/components/site/section-head.blade.php`,
`resources/views/components/site/post-card.blade.php`.
- Modify: `resources/views/livewire/pages/home.blade.php`, `resources/css/public.css`,
`lang/ar/site.php`, `lang/en/site.php`.
- Do not edit `lang/*/home.php`.
## Acceptance Criteria
- [ ] `/` renders, in order, sections with ids `top`, (the pillars band), `founder`, `services`,
`mission`, `values`, `posts`, each with its content from the keys above in both Arabic and
English (switch with `/language/en`).
- [ ] `/` has exactly one `<h1>`, and every `<img>` has a non-empty `alt` in both languages.
- [ ] The four files in `public/images/site/` exist, are valid JPEGs (`file` reports JPEG image
data) and load with HTTP 200 on `/`.
- [ ] The hero balance renders inside the hero frame and settles level (task 24-3 behaviour).
- [ ] Each services row links to `#book`; each row shows the item chips from `home.php`.
- [ ] With three or more published posts, three post cards show date, title, excerpt and "Read
more", link to `/posts/{post}`, and contain no `<img>`; with no published posts, the
`home.posts_empty` text shows instead of the grid.
- [ ] At 1440, 768 and 390px wide, `/` has no horizontal scroll (`document.documentElement.scrollWidth <= innerWidth`).
- [ ] Hovering a service row fills it forest with cream text; hovering a value card lifts it and
rotates its medallion; hovering a post card lifts it.
- [ ] The page contains no "Unsplash" text and `lang/*/home.php` is unchanged against BASE.
## Sub-tasks
None.