fix: mobile gutters, header search tiers, suggest wiring + empty-state, news pagination, hero CTAs, ghost button

- padding-block on .page/.page-head/.article: container gutter survived only >=1176px (shorthand padding zeroed it) — mobile content sat flush left
- restore <=1024px tiers: field hidden, magnifier + menu visible (header no longer overflows at 375px)
- re-wire hdr-q suggestions lost in the field restore; newsSearch inits null-safe
- focused-empty search state: recent queries (localStorage, cap 4) + latest articles (Baymard autocomplete guidance)
- suggest panel 480px (Baymard/DocSearch width convention)
- /news page 1 = 25 items (featured + 24 = even 3-col rows), later pages 24, custom slicing
- hero CTAs: primary Browse news (/news, spec-first real service), ghost Explore the data (external); mock Proposals out of hero
- .btn.btn--ghost compound selector — .btn base defined later was filling ghosts with Cherenkov

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_012jWfn3RwPfFGTtBddm36Uy
This commit is contained in:
ctao
2026-07-25 12:16:41 +02:00
co-authored by Claude Fable 5
parent eaf511a976
commit 4fa35e5317
6 changed files with 130 additions and 28 deletions
+20 -7
View File
@@ -221,7 +221,9 @@ img { max-width: 100%; height: auto; display: block; }
}
.nav-search input::placeholder { color: rgba(255, 255, 255, 0.65); } /* 6.9:1 */
.nav-search input:focus { border-color: #fff; }
.nav-search .suggest { left: auto; right: 0; width: min(380px, 92vw); top: calc(100% + 10px); }
/* Autocomplete panel: never narrower than the field, wide enough for a
typical title in ≤2 lines (Baymard autocomplete; DocSearch ~500px) */
.nav-search .suggest { left: auto; right: 0; width: min(480px, calc(100vw - 2 * var(--gutter))); top: calc(100% + 10px); }
/* ≤1024px replacement: a 44px magnifier <details> reveals a search row under
the header (NN/g mobile-search pattern) — see the menu media block. */
.search-pop { display: none; }
@@ -248,6 +250,8 @@ img { max-width: 100%; height: auto; display: block; }
}
@media (max-width: 1024px) {
.nav > nav { display: none; }
.nav-search { display: none; } /* field is desktop-only (NN/g tiers) */
.search-pop { display: block; } /* magnifier reveal takes over ≤1024px */
.menu { display: block; }
.menu summary {
display: inline-flex; align-items: center; gap: 8px; min-height: 44px;
@@ -309,15 +313,17 @@ img { max-width: 100%; height: auto; display: block; }
one quiet ghost. Links styled as buttons because they navigate. */
.hero-cta { display: flex; flex-wrap: wrap; gap: var(--space-s); margin-top: var(--space-l); }
a.btn { display: inline-flex; align-items: center; gap: 6px; text-decoration: none; }
.btn--ghost { background: transparent; color: #fff; border: 1px solid rgba(255, 255, 255, 0.55); }
.btn--ghost:hover { background: rgba(255, 255, 255, 0.12); color: #fff; border-color: #fff; }
/* Compound selector: outranks the later-defined .btn base (source-order tie
would otherwise fill the ghost with Cherenkov) */
.btn.btn--ghost { background: transparent; color: #fff; border: 1px solid rgba(255, 255, 255, 0.55); }
.btn.btn--ghost:hover { background: rgba(255, 255, 255, 0.12); color: #fff; border-color: #fff; }
/* Section-landing head (news/search/proposals/dashboard/support) — white page,
display-scale Galaxy h1 + standfirst; the navy band is reserved for / and /login. */
.page-head { padding: var(--space-band) 0 var(--space-l); }
.page-head { padding-block: var(--space-band) var(--space-l); }
.page-head h1 { color: var(--galaxy); font-size: var(--fs-h1); margin: 0 0 10px; }
.page-head .standfirst { margin: 0; max-width: 62ch; }
.page-head + .page { padding-top: 0; } /* white-on-white: head already spaces */
.page-head + .page { padding-block-start: 0; } /* white-on-white: head already spaces */
/* Search field (/search page) — large pill input with inline magnifier; real GET form */
.search-form { position: relative; display: flex; gap: 8px; max-width: 560px; }
@@ -340,6 +346,13 @@ a.btn { display: inline-flex; align-items: center; gap: 6px; text-decoration: no
.suggest:empty { display: none; }
.suggest li { display: flex; align-items: flex-start; gap: var(--space-s); padding: 0 12px; border-radius: calc(var(--radius) - 8px); }
.suggest li:hover, .suggest li:focus-within { background: var(--moon); }
/* Focused-empty state labels ("Recent" / "Latest news") — quiet, non-interactive */
li.suggest-label {
color: var(--muted); font-size: var(--fs-xs); font-weight: 600;
text-transform: uppercase; letter-spacing: 0.08em; padding-top: 8px;
}
.suggest li.suggest-label:hover { background: none; }
.search-results li.suggest-label { background: none; border: 0; box-shadow: none; padding: 8px 0 0; }
/* The link holds <mark>-split text nodes — it must lay out as flowing text,
never as a flex row (flex would turn every fragment into its own item and
stop titles from wrapping). ≥44px target comes from the block padding. */
@@ -441,7 +454,7 @@ span.page-step { color: var(--muted); } /* disabled end stop — non-interactive
/* Article — 70ch column; on ≥1200px a sticky "On this page" rail sits to the right */
.article-layout { display: grid; grid-template-columns: minmax(0, 70ch); }
.article { padding: var(--space-l) 0 var(--space-xl); max-width: 70ch; }
.article { padding-block: var(--space-l) var(--space-xl); max-width: 70ch; }
.article .back { color: var(--muted); font-size: var(--fs-s); }
.article h1 { color: var(--galaxy); font-size: var(--fs-h1); margin: 14px 0 10px; }
.article .meta {
@@ -541,7 +554,7 @@ span.page-step { color: var(--muted); } /* disabled end stop — non-interactive
.post-nav a:hover .post-nav-title { color: var(--link); }
/* Generic page section — one rhythm token for all pages */
.page { padding: var(--space-xl) 0; }
.page { padding-block: var(--space-xl); }
.panel {
background: #fff; border: 1px solid var(--border); border-radius: var(--radius);
padding: var(--space-m); box-shadow: var(--shadow-ambient);