Skip to content

[mobile][W1] Rankings template: list-first first screen, fold intro/ai-fact/stats (39 pages) #321

Description

@jasonhnd

Context (read this first)

  • Repo: jasonhnd/jobs → mirai-shigoto.com. JA-only static Astro site. /rankings/* receives 38.1% of entering sessions at ~10s engagement — visitors land from queries like 「AIに奪われる仕事」, see no job names on the first screen, and leave.
  • Base branch is preview. Your PR targets preview. NEVER push, merge, or open a PR to main. Never trigger a production deploy. The owner reviews everything on preview and personally decides promotion.
  • Wave gate: start only after [mobile][W0] Compact one-line cookie consent bar (site-wide) #320 is merged into preview (the compact cookie bar; your acceptance screenshots depend on it).
  • Referee spec: docs/MOBILE_SHAPES.md — read §0, §3 (esp. 3.1 type floor / 3.2 tap targets / 3.3 job-row atom / 3.5 SEO invariants), §4.1 (this issue).
  • Visual reference: mockups/shots/pair-1.png (live vs target), mockups/shots/frame-02.png. Mockup pixel values are directional; §3.1 floors and existing site tokens win.

Problem

Current first screen at 390px: breadcrumb → H1 → sub → intro paragraph → .ai-fact citation block → stats cards → highlights → sector chart → the TOP list starts ~2 screens down. See mockups/shots/live-ranking.png: not a single occupation name is visible.

Scope — one template, 39 pages

  • src/pages/rankings/[type].astro (block order + folded block + styles + desktop-open helper)
  • src/pages/rankings/_rankings-bindings.ts (summary-line binding)
  • src/templates/Ranking.ts (row markup: full-row link) + src/templates/Ranking.test.ts (snapshot updates)
  • src/components/Footer.astro (one new branch in the existing delegated click-tracking script)
  • analytics/spec.yaml (+1 event)

Spec

New order (all viewports; §3.8 desktop non-regression applies):

  1. Breadcrumb, <h1>H1 text unchanged.
  2. NEW one-line summary under the H1 (class rk-sum): 1位は{TOP1名}({score}/10) · TOP{N}平均 {mean}/10 · {YYYY年M月}更新. Data: result.items[0], safeMean (importable from @/views/ranking.js), CONTENT_DATE (src/lib/_content-date.ts) formatted as {Y}年{M}月. ~13.5px muted; names/numbers bold ink. Null score renders (defensive; all 556 are scored today).
  3. The ranked list immediately. Keep <h2>TOP {N}</h2> (a11y landmark, §3.5 no deletion) restyled visually small. Rows keep existing content (rank, name, sector, per-ranking ExtraCols, salary/workers) restyled to the §3.3 atom; one <a class="rl-row"> wraps the whole row (name becomes a <span>); rows 1–4 minimum fit in the first 844px incl. top bar.
  4. AFTER the list: <details class="chap"><summary>このランキングの読み方・出典</summary> containing in order: the former .sub line text (first), the former .intro paragraph, the unchanged, complete .ai-fact block, the .stats cards, remaining highlights, the sector chart. Nothing deleted; inner content byte-identical.
  5. Desktop expansion: this issue is the FIRST to introduce <details class="chap">, so it also ships the minimal helper — a static-bodied inline <script> (bodyEnd): if matchMedia('(min-width:900px)').matches, set open on all details.chap. No interpolation; run bun run check:csp-hashes and commit the updated hash. Style the new classes so [mobile][W4·gated] Roll List shape out to Q&A / sectors / theme hubs #328 can later reuse them — prefer a shared location (src/lib/canonical-css.ts or a small shared module) over page-local CSS.
  6. Unchanged below: MeEntry, FAQ, cross-hub, related rankings, escape-routes.
  7. GA4 list_row_click: add data-track-event="list_row_click" on the row anchor and extend the existing delegated listener in src/components/Footer.astro (the same mechanism as me_entry_click / jobtag_outbound_click) with a branch setting params { language: 'ja' }. Do NOT use inline onclick — a stale comment in analytics/spec.yaml describes an obsolete wiring; the CSP has no unsafe-inline. Register the event in analytics/spec.yaml; bun run check:analytics-config must pass.

Invariants

H1/title/meta/JSON-LD/canonical unchanged (§3.5). .ai-fact full text unchanged. Type floor §3.1 (row name ≥15.5px, captions ≥12px). No content deletion. Do not add new element ids — anchor ids are tracked in tests/baseline/internal-links.jsonl and unneeded ids force a baseline regen; use classes.

Acceptance

  • PR screenshots: 390×844 before/after of /rankings/ai-risk-high and one non-AI ranking (e.g. /rankings/salary — salary extras must still render); desktop ≥1280 after-shot with chapters expanded. Take screenshots in a consent-decided state or with [mobile][W0] Compact one-line cookie consent bar (site-wide) #320's compact bar in base.
  • First screen shows H1 + summary + rows 1–4; rank 1 fully visible.
  • Whole-row tap works anywhere on the row; hit area ≥44px.
  • bun run typecheck && bun run test && bun run verify:gates && bun run test:e2e green; Ranking.test.ts snapshots updated for the new markup and listed in the PR.
  • bun run capture:seo-baseline diff shows no title/meta/JSON-LD change.
  • list_row_click registered + firing (GA4 DebugView or document the payload {language:'ja'} in the PR).

Metadata

Metadata

Assignees

No one assigned

    Labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions