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

92 lines
4.9 KiB
Markdown

---
id: 24-8
title: 24-8 Articles and Legal Pages
status: Ready for Dev
date: 2026-10-31
parent: 24
---
## Description
Restyle the articles index, the article page and the legal pages. Behaviour does not change:
search (`wire:model.live.debounce.300ms="search"`), pagination (`paginate(10)`), result counts,
empty states, the 404 for unpublished posts, and the CMS content of legal pages. Remove the
temporary `<div class="wrap py-8">` wrappers added in 24-1.
### `/posts` — `resources/views/livewire/pages/posts/index.blade.php`
`<section class="sec" style="padding-top:56px"><div class="wrap">`:
- `<x-site.section-head :label="__('site.hero_eyebrow')" :title="__('site.nav_articles')">`
(the h2 reads «المقالات» / "Articles"; the existing `posts.posts` key reads "Posts" in English, so
it is not used here) with,
in the slot, the search field: a pill input (`.search`: min-height 48px, radius 999px, padding
12px 20px, `1.5px solid rgba(45,54,36,.18)`, white, width min(360px, 100%); focus gold border
plus `0 0 0 4px rgba(166,137,102,.2)`), same `wire:model` and placeholder
`posts.search_placeholder`, with an accessible label (`sr-only` text
`posts.search_placeholder`).
- The existing result-count / no-result lines (`posts.search_results`, `posts.no_results`) as a
muted paragraph, and the existing clear-search action as `btn btn-ghost`.
- The posts as `<x-site.post-card :post="$post" />` in a `.posts` grid (3 columns; 2 at ≤1100px;
1 at ≤760px — the grid CSS exists from 24-4; at this page the last card does not span two
columns: add `body.site .posts-index .post:last-child{grid-column:auto}` and give the grid the
extra class `posts-index`).
- Empty states `posts.no_posts` as before.
- Pagination: `{{ $posts->links() }}` kept; style its links under `body.site .pagination-wrap`
(wrap the call in `<div class="pagination-wrap">`): 44px pill buttons, `1.5px solid var(--line)`,
current page `background:var(--forest)` with cream text, disabled at 50% opacity.
### `/posts/{post}` — `resources/views/livewire/pages/posts/show.blade.php`
`<section class="sec" style="padding-top:56px"><article class="wrap" style="max-width:768px">`
(720px content + padding):
- `<span class="meta">` the published date (existing `translatedFormat('l, d F Y')` expression),
colour `--gold-ink`, .85rem, weight 600.
- `<h1>` = `$post->getTitle()` — display font, `clamp(2rem,3.4vw,3rem)`, margin 10px 0 28px.
- Body `<div class="prose prose-lg prose-brand max-w-none site-prose">{!! $post->getBody() !!}</div>`
(keep the existing output exactly). New CSS: `body.site .site-prose :is(h2,h3,h4){font-family:var(--display)}`,
`body.site .site-prose a{color:var(--olive)}`, `body.site .site-prose{font-size:1.06rem;line-height:1.85}`.
- Footer: `<a class="btn btn-ghost" href="{{ route('posts.index') }}" wire:navigate>`
`posts.back_to_posts`, preceded by a hairline `border-top:1px solid var(--line)` with 48px
margin-top and 24px padding-top. Remove `flux:heading`.
### Legal pages
- `resources/views/pages/legal.blade.php` — inside `<x-layouts.public>`:
`<section class="sec" style="padding-top:56px"><div class="wrap" style="max-width:768px">`,
`<h1>` `$page->getTitle()` (same h1 style as the article page), the existing
`prose prose-brand` block with the class `site-prose` added and its card styling replaced by
white background, radius 16px, `--shadow-1`, padding 40px (24px ≤760px); the existing
"last updated" line as muted .85rem text. Keep the `clean()` call and the
`pages.content_coming_soon` fallback unchanged.
- `resources/views/pages/terms.blade.php` and `resources/views/pages/privacy.blade.php` — the same
structure with their existing title and placeholder text. (`/terms` and `/privacy` redirect to
`/page/terms` and `/page/privacy`; these two views are kept in case they are rendered
directly.)
### Language keys
None new; `site.hero_eyebrow` (24-4) and `site.nav_articles` (24-2) are reused.
### Files
- Modify: `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/css/public.css`.
## Acceptance Criteria
- [ ] `/posts` shows the section head, a working search (typing filters results after the
debounce and shows the count line), text-only post cards and styled pagination when there
are more than 10 published posts.
- [ ] `/posts/{post}` for a published post shows date, a display-font `<h1>`, the body and a Back
button to `/posts`; an unpublished post still returns 404.
- [ ] `/page/terms` and `/page/privacy` show the title, the sanitised CMS content (or the
coming-soon text) and the last-updated line.
- [ ] Each of these pages has exactly one `<h1>` and no horizontal scroll at 1440, 768 and 390px.
- [ ] The admin posts screens (`/admin/posts`) are unchanged (they do not use the public layout).
## Sub-tasks
None.