From 89688d605d9b697ed0b8adbf41dd52b036a9aca9 Mon Sep 17 00:00:00 2001 From: Jonathan Hvid Date: Tue, 12 May 2026 11:16:11 +0200 Subject: [PATCH] style(pulse): drop date + tenure line, italic-noun section titles, more air, new active nav cue MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Greeting (1, 2): the tracked date label above the greeting and the milestone tenure line below it both come out. The greeting is now just 'Good morning, Jonathan.' alone on the left, with the MEMBER · NNN / 'Founding circle' stamp on the right. tenureMilestone helper + test stay in place — they're still useful for future surfaces but no longer rendered on /pulse. Section titles (3): the noun in each section title gets serif italic + a trailing period — 'On the roadmap.' and 'The council.'. The two-word framing reads better visually than the previous flat sans-serif title. Spacing (6): bumped the major section transitions. Greeting → hero now 80px (was 56), also-coming-up → editorial 96px, editorial → roadmap 96px, roadmap → council 96px. The hero → also-coming-up gap stays at the deliberate 18px because they're a pair, and the dispatch column's internal margin-top 48px to its 'Earlier' list stays unchanged because they belong to the same story. Footer (7): 'Council manifesto' link removed from the footer for all pages. The standalone /council-manifesto route stays in the codebase (orphaned, not linked) so it isn't a 404 when someone has the URL. Active nav link (8): the previous 4px terracotta dot below the active link is gone. The active link now reads in a different typographic register entirely: - terracotta colour - serif italic Newsreader (vs sans uppercase for inactive) - sentence case (text-transform: none — the label appears as 'Pulse' instead of 'PULSE') - leading '· ' prefix dot for an additional 'you are here' marker Four cues at once, no positioned overlay, no floating elements. The typography shift alone tells you which page you're on. Co-Authored-By: Claude Opus 4.7 (1M context) --- src/components/RoadmapCarousel.astro | 3 +- src/layouts/AppLayout.astro | 31 +++++++++--------- src/pages/pulse.astro | 47 ++++++++-------------------- 3 files changed, 32 insertions(+), 49 deletions(-) diff --git a/src/components/RoadmapCarousel.astro b/src/components/RoadmapCarousel.astro index bfeccb6..94ecf5e 100644 --- a/src/components/RoadmapCarousel.astro +++ b/src/components/RoadmapCarousel.astro @@ -41,7 +41,7 @@ const hasArrows = items.length > 3; ---
-

On the roadmap

+

On the roadmap.

See the full roadmap → {hasArrows && ( @@ -138,6 +138,7 @@ const hasArrows = items.length > 3; color: var(--on-surface); margin: 0; } + .roadmap-title em { font-style: italic; } .roadmap-actions { display: flex; align-items: baseline; diff --git a/src/layouts/AppLayout.astro b/src/layouts/AppLayout.astro index 71b08f0..b3d8ba0 100644 --- a/src/layouts/AppLayout.astro +++ b/src/layouts/AppLayout.astro @@ -15,8 +15,7 @@ const navLinks = [ ]; const footerLinks = [ - { href: '/vision', label: 'Vision' }, - { href: '/council-manifesto', label: 'Council manifesto' }, + { href: '/vision', label: 'Vision' }, ]; const currentPath = Astro.url.pathname; @@ -190,20 +189,24 @@ const year = new Date().getFullYear(); color: var(--on-surface); border-bottom: none; } + /* Active nav link: terracotta color + a serif italic "·" bracket. The + prefix dot acts as a 'you are here' marker without floating below + the link the way the previous indicator did. Switching from sans + uppercase to terracotta serif italic also doubles as a typography + cue, so the active state reads even before colour processes. */ .nav-link.active { - color: var(--on-surface); + color: var(--pigment-terracotta); + font-family: var(--font-serif); + font-style: italic; + font-weight: 400; + letter-spacing: var(--tracking-snug); + text-transform: none; + font-size: 15px; } - /* 4px terracotta dot under the active link, 22px below its baseline. */ - .nav-link.active::after { - content: ''; - position: absolute; - left: 50%; - bottom: -22px; - width: 4px; - height: 4px; - border-radius: 50%; - background: var(--pigment-terracotta); - transform: translateX(-50%); + .nav-link.active::before { + content: '·'; + margin-right: 6px; + color: var(--pigment-terracotta); } /* ── User zone ──────────────────────────────────────────────────── */ diff --git a/src/pages/pulse.astro b/src/pages/pulse.astro index 17696da..679d7c9 100644 --- a/src/pages/pulse.astro +++ b/src/pages/pulse.astro @@ -10,7 +10,7 @@ import { getAllCabMembers, getPulseById, getUserVote, castVote, } from '../lib/db'; import { - timeOfDay, pulseDateLabel, daysSince, tenureMilestone, relativeTime, + timeOfDay, relativeTime, eventKindLabel, dispatchSlug, dispatchKindLabel, dispatchKindPigment, dispatchLongPreview, } from '../lib/format'; @@ -54,12 +54,6 @@ if (Astro.request.method === 'POST') { // ── Greeting ─────────────────────────────────────────────────────── const firstName = user.name.split(' ')[0]; const greetingPrefix = `Good ${timeOfDay()}, `; // "Good morning, " -const dateLabel = pulseDateLabel(); // "MONDAY, 11 MAY" - -const tenureAnchor = user.role === 'cab' && user.cab_joined_date - ? user.cab_joined_date - : user.created_at; -const tenureCopy = tenureMilestone(daysSince(tenureAnchor)); const memberNumberLabel = user.member_number != null ? `MEMBER · ${String(user.member_number).padStart(3, '0')}` @@ -112,9 +106,7 @@ const members = getAllCabMembers();
-

{dateLabel}

{greetingPrefix}{firstName}.

-

{tenureCopy}

{memberNumberLabel && (
@@ -236,7 +228,7 @@ const members = getAllCabMembers(); {members.length > 0 && (
-

The council

+

The council.

See who our council is made up of →
@@ -274,14 +266,16 @@ const members = getAllCabMembers(); flex-direction: column; } - /* Per-section spacing table (no shared gap — each transition is tuned). - Read top-down: greeting → hero → also → editorial → roadmap → council. */ - .greeting { margin-top: 48px; } /* below nav */ - .hero-slot { margin-top: 56px; } /* greeting → hero */ - .also-coming-up { margin-top: 18px; } /* hero → also (tight; related) */ - .editorial-row { margin-top: 72px; } /* also → editorial */ - .roadmap-wrap { margin-top: 72px; } /* editorial → roadmap */ - .council-section{ margin-top: 72px; } /* roadmap → council */ + /* Per-section spacing table. More air between sections than before + (96px between editorial / roadmap / council); editorial-row internal + dispatch → 'Earlier' gap stays tight at the original 48px because + they're the same story. */ + .greeting { margin-top: 64px; } /* below nav */ + .hero-slot { margin-top: 80px; } /* greeting → hero */ + .also-coming-up { margin-top: 18px; } /* hero → also (tight; pair) */ + .editorial-row { margin-top: 96px; } /* also → editorial */ + .roadmap-wrap { margin-top: 96px; } /* editorial → roadmap */ + .council-section{ margin-top: 96px; } /* roadmap → council */ /* ── Cascade entry (first paint only) ─────────────────────────── */ .cascade { @@ -309,7 +303,6 @@ const members = getAllCabMembers(); .greeting-left { display: flex; flex-direction: column; - gap: 10px; max-width: 30rem; } .greeting-right { @@ -318,14 +311,6 @@ const members = getAllCabMembers(); align-items: flex-end; gap: 6px; } - .greeting-date { - font-family: var(--font-sans); - font-size: 11px; - letter-spacing: var(--tracking-wider); - text-transform: uppercase; - color: var(--on-surface-variant); - margin: 0; - } .greeting-line { font-family: var(--font-serif); font-weight: 400; @@ -336,13 +321,6 @@ const members = getAllCabMembers(); margin: 0; } .greeting-first { font-style: italic; } - .greeting-tenure { - font-size: 13px; - color: var(--on-surface-variant); - margin: 0; - max-width: 380px; - line-height: var(--leading-relaxed); - } .greeting-member { font-family: var(--font-sans); font-size: 11px; @@ -641,6 +619,7 @@ const members = getAllCabMembers(); color: var(--on-surface); margin: 0; } + .council-title em { font-style: italic; } .council-all { font-family: var(--font-sans); font-size: 11px;