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

4.9 KiB

id, title, status, date, parent
id title status date parent
24-8 24-8 Articles and Legal Pages Ready for Dev 2026-10-31 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.
  • 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.