Skip to content

Header width and alignment, badge polish, and three copy fixes - #40

Merged
Abuubkar merged 11 commits into
devfrom
ui/nav-width-and-copy
Sep 8, 2026
Merged

Abuubkar merged 11 commits into
devfrom
ui/nav-width-and-copy

Conversation

@Abuubkar

@Abuubkar Abuubkar commented Sep 8, 2026

Copy link
Copy Markdown
Owner

Six requested changes. Three commits, split by kind.

Header width and alignment

The header turned out to be two problems wearing one symptom.

It applied its gutter inside the container, where Section and SiteFooter
apply theirs outside. That inset the brand by one gutter against every section
below, so the wordmark sat 24px right of the hero copy directly beneath it. Not
a spacing preference — the header was the only one of the three doing it this
way.

And containerWide was the canvas's 1160. At 1600px that left 244px of
nothing at each side against 110px between the three nav groups. Outer space
larger than inner space is what makes a header read as a strip floating in a
wide page. At 1280 the two are in the same range, and the wordmark now lines up
exactly with the hero badge and headline.

The container is shared, so sections widen too. Prose is unaffected — it has its
own containerText at 640 — and the grids get their columns back. Checked down
the page: Problem cards, Services, Specialties and the footer all sit correctly.

Badge and eyebrow

Shadow on the pill: it sits on surfaceAccent over a wash that ends at
surfaceAccentSoft, near enough that the 1px border was doing all the
separating and not much of it. shadow.sm.

Glow on the dot: a tight ring plus a soft bloom, alpha doing the work — a solid
ring at 8px just looks like a bigger dot. Built as a Dot prop rather than a
Badge style so it stays keyed to tone: a brand dot glows brand, and subtle
does not glow at all, having nothing to announce. Badge is the only caller
today.

Eyebrow from base to md (13px → 15px). At 13px, uppercase and letterspaced,
it read as a caption under the heading rather than a label over it.

Copy

Provider range 1-20 → 35-40, in all three user-facing places (meta
description, hero lead, Fit list), plus the OG card — regenerated — and the
Practice glossary entry in CONTEXT.md that defines the term.

The last trust point was "US-facing team · 24-hour processing": one list
item carrying its own separator, so it rendered a text middle dot where the
other four have a teal Dot. Now two items, six in the row.

"13 wks" → "13 weeks." It was the only abbreviation among four stat cards
("60%", "13.5%", "25 min") and the one whose unit a reader has to expand.

Three things the provider change touches that I did not edit

Flagging rather than fixing, because each is a judgement call rather than a
find-and-replace:

  1. The Assessment form's provider options are 1 / 2-5 / 6-10 / 11-20 / 20+. A 35-40 provider practice can only pick 20+, so the form still
    works — but the granularity is now aimed at the old range and the top band
    is where every qualified lead lands.
  2. docs/design/rcm-landing.dc.html, the design source of truth, still
    reads 1–20. The site and the canvas now disagree.
  3. docs/research/rcm-problem-statistics.md is the one worth a proper look.
    Its whole argument is scoped to 1–20 provider practices — it rejects hospital
    surveys specifically because "a 1–20 provider practice has no discharges",
    and qualifies each stat against that population. Most of it still holds at
    35-40 (delegated credentialing needs 100–150+ providers, so the 13-week
    number survives), but the sourcing notes now describe a narrower audience
    than the page claims.

Worth confirming 35-40 is the intended range: it sits oddly beside "independent
practices", which the page leans on throughout, and a 35-40 provider group is a
different buyer from the one the copy and the research were built for.

Checked

pnpm check and pnpm build pass. Verified in the browser at 1600px: brand and
hero copy share a left edge, badge dot carries the ring-and-bloom shadow, eyebrow
computes to 15px, and the trust row renders six items each with its own dot.

Two separate things, both visible as "too much space at the sides".

The header put its gutter inside the container rather than outside it,
which is the reverse of Section and SiteFooter. That inset the brand by a
gutter relative to every section below, so the wordmark sat 24px right of
the hero copy it sits directly above — close enough to read as a mistake
rather than a margin.

And containerWide was the canvas's 1160. At 1440 and up that left the
header's three groups closer to each other than to the edges of the
screen: 244px of nothing at each side against 110px between the groups,
which reads as a narrow strip floating in a wide page. 1280 puts the
outer margins and the inner gaps in the same range.

The container is shared, so sections widen too. Prose is unaffected —
it has its own containerText — and the grids simply get their columns
back.
The badge sits on surfaceAccent over the hero's wash, which ends at
surfaceAccentSoft — near enough that the 1px border was doing all the
separating and not much of it. shadow.sm lifts it.

The dot gets a glow: a tight ring plus a soft bloom, alpha doing the
work, because a solid ring at 8px just looks like a bigger dot. It is a
Dot prop rather than a Badge style, so it stays keyed to tone — a brand
dot glows brand, and `subtle` does not glow at all, having nothing to
announce. Badge is the only caller today.

Eyebrow moves from base to md. At 13px, uppercase and letterspaced, it
was reading as a caption under the heading rather than a label over it.
The provider range moves from 1-20 to 35-40 in the three places it is
user-facing — the meta description, the hero lead and the Fit list — plus
the OG card, which is regenerated, and the glossary entry for Practice
that defines the term.

The last trust point was "US-facing team · 24-hour processing": one list
item carrying its own separator, so it rendered a text middle dot where
the other four have a teal Dot. Now two items, six in the row.

"13 wks" was the only abbreviation among four stat cards ("60%", "13.5%",
"25 min"), and the one whose unit a reader has to expand. Now "13 weeks".
@cloudflare-workers-and-pages

cloudflare-workers-and-pages Bot commented Sep 8, 2026 •

Copy link
Copy Markdown

Deploying with  Cloudflare Workers  Cloudflare Workers

The latest updates on your project. Learn more about integrating Git with Workers.

Status Name Latest Commit Preview URL Updated (UTC)
✅ Deployment successful!
View logs
execil 784776f Commit Preview URL

Branch Preview URL
Sep 08 2026, 05:22 AM

Six changes from a review of the first pass.

The desktop header was appearing at 940px, but the nav links, the phone
number and the CTA need 1000px before they all stop wrapping — so between
940 and 1000 the "desktop" header rendered three lines deep. The
breakpoint moves to 1040, a gutter of slack past where it fits. Hero
shares that token for its side-by-side layout, and HERO_SIZES repeats the
number because a `sizes` attribute cannot read a token; both move
together, and the token comment now says so.

The comparison table used auto layout, so each column sized to its
longest cell and the surplus went to whichever asked for most. That left
the Execil column half again as wide as the vendor column it is compared
against, with its text stopping well short of filling it. Fixed layout,
22% for the labels and the value columns even, so the comparison does not
look weighted before it is read.

The hero's top padding drops to the bottom's value. The canvas drew it
taller, which made sense when the hero was centred text; the picture now
supplies that height on the right.

The badge dot only had a static bloom, which reads as a slightly fuzzy
dot rather than a live one. It gains a travelling ring on ::after,
animating opacity and transform only — no colour named, composited not
repainted, and the global prefers-reduced-motion rule in app.css already
covers ::after.

Stat sources go from xs to base. At 11px they were the smallest text on
the page by two steps; one step would not have been visible.

Provider bands gain 21-34, 35-40 and 40+ in place of 20+, so the range the
copy now names is selectable rather than folded into a catch-all.
@Abuubkar

Abuubkar commented Sep 8, 2026

Copy link
Copy Markdown
Owner Author

Second pass

Six more changes, pushed as 8a7dbca. PR body above still describes the first three commits.

Nav breakpoint 940 → 1040. You were right that 940–988 looked wrong, and it was worse than it looked: the header needs 1000px before the nav links, the phone number and the CTA all stop wrapping, so the whole band between 940 and 1000 rendered a three-line "desktop" header. 1040 leaves a gutter of slack past where it fits. Verified at 1039 (hamburger, 69px tall) and 1040 (full nav, 69px tall).

Hero shares that token for its side-by-side layout, and HERO_SIZES repeats the number because a sizes attribute cannot read a token — both moved together, and the token comment now says they must.

Why Us table. It was on auto layout, so every column sized to its longest cell and the surplus went to whichever asked for most. That left Execil at 538px against the vendor column's 409px — the column being compared against us was 24% narrower, with our own text stopping well short of filling ours. Fixed layout now: 273 / 484 / 484. A comparison should not look weighted before it is read.

The dot. You were right, it was not glowing — a static bloom just reads as a fuzzy dot. It now has a travelling ring on ::after, animating opacity and transform only, so no colour is named and it composites rather than repaints. The steady bloom stays underneath, which matters because app.css already suppresses *::after animation under prefers-reduced-motion — the dot still reads as lit when the pulse is off.

Hero padding is now 80px top and bottom, level. The canvas drew the top taller, which made sense when the hero was centred text; the picture supplies that height on the right now.

Stat sources went xs → base (11px → 13px), not sm. One step is 1px and you would not have seen it; 13px is still clearly a caption against 15px body.

Provider bands are now 1 / 2-5 / 6-10 / 11-20 / 21-34 / 35-40 / 40+. 20+ was replaced rather than added to, so the range the copy names is selectable instead of folded into a catch-all. The server caps this field at 40 characters and does not validate against the list, so no endpoint change was needed.

pnpm check and pnpm build pass.

The observer only ever called setCurrent when it found a section in the
band, so with nothing there the last match stayed highlighted. Scrolling
back over the hero left Services lit.
Sources were xs in Results and base in Problem; both are sm now. The
assessment findings line was sm, which is caption size for a sentence
that carries the offer — md. Pulse 2400ms to 1300ms.
Long block comments explaining what was tried and why, across the files
this session touched. Replaced with one line where a constraint is worth
recording and nothing where the code already says it. The Wordmark
emitter in the scratchpad produces the shorter docstring too, so a
regenerate does not undo this.
A link is current from its section's top to the next linked section's
top, so Systems reads as Specialties and Fit and Results as Why Us. The
last chapter ends at its own bottom, leaving the form unlit. Replaces the
10% intersection band, which went blank over every unlinked section.
Two crisp 2px rings on ::before and ::after, half a period apart, easing
out to three times the dot's size, and the dot breathes to 1.18x on the
same beat. Replaces the single blurred ring. New motion.easeOut token.
@Abuubkar
Abuubkar merged commit 784776f into dev Sep 8, 2026
1 of 2 checks passed
@Abuubkar
Abuubkar deleted the ui/nav-width-and-copy branch September 8, 2026 05:20
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant