Skip to content

Phase 1a.4: one eyebrow style (4 variants → 1) - #528

Merged
pftg merged 5 commits into
masterfrom
phase-1a4-eyebrow
Aug 21, 2026
Merged

Phase 1a.4: one eyebrow style (4 variants → 1)#528
pftg merged 5 commits into
masterfrom
phase-1a4-eyebrow

Conversation

@pftg

@pftg pftg commented Aug 21, 2026

Copy link
Copy Markdown
Member

Second 1a.4 item. Four eyebrow variants converge on the blog's canonical form —
the one the plan records as already done.

Canonical

pages/blog-list.css .blog-eyebrow12px / 700 / 0.14em / uppercase /
--color-ruby

Variant Was
services-critical.css --color-ruby, weight 600 — no size, tracking or transform
careers-critical.css same near-miss
components/content-block.css same near-miss
pages/friday-report.css 13px, weight 600, 0.18em, --ruby-700

The green suite proves nothing for three of these

Only the services page is in the screenshot set. For careers, content-block and
friday-report, [snap_diff] 53 screenshots compared, no failures means "not
captured"
, not "unchanged" — exactly the trap the phase brief flags for
eyebrows.

Verified by computed style in the rendered production build instead:

fontSize 12px · fontWeight 700 · letterSpacing 1.68px (= 0.14em × 12)
textTransform uppercase · color rgb(204,52,45)

For services, which is captured, I read the rendered _overview.png — the
eyebrow sits small, ruby and tracked above the H1.

Contrast, measured

This commit lightens one thing: friday-report moves --ruby-700--color-ruby.
Against that page's actual background — rgb(253,245,244), a warm tint, not
white — the ratio is 4.77:1. Passes AA for normal text (4.5:1), but the
margin is thin: the same pair on pure white is ~5.1:1, and any darkening of that
tint pushes it under. Recorded so the next person to touch that surface knows
the eyebrow is the binding constraint.

Gates

  • bin/test — commit 1: 3 baselines moved (services), reviewed and accepted.
    Commit 2: 53 screenshots compared, no failures, no baseline moved.
  • bin/hugo-build clean
  • macOS only; Linux baselines belong to the parallel PR

1a.4 remaining

Three button roles (not started). Footer onto surface-ink stays blocked
see #526; it needs dividers and adjacent dark sections migrated together across
7+ bundles.

🤖 Generated with Claude Code

pftg and others added 2 commits August 21, 2026 04:14
"ONE eyebrow style" - first bundle-group. The canonical form is the blog's,
which shipped in Phase 2 and the plan records as already done
(pages/blog-list.css `.blog-eyebrow`): 12px / 700 / 0.14em tracking / uppercase
/ --color-ruby.

services-critical.css carried a near-miss: --color-ruby and weight 600, no
size, tracking or transform. Now matches, keeping `text-align: center` which is
layout rather than type.

The markup already says "SERVICES" in caps, so `text-transform` is a no-op here
and the visible delta is size, weight and tracking only - worth knowing before
reading the diff as larger than it is.

Verified by looking, not by a green suite: the section screenshot at 0.02
tolerance would not reliably catch a small type change, so I read the rendered
`services/_overview.png`. The eyebrow renders small, ruby, tracked and legible
above the H1.

Gate: bin/test - [snap_diff] 53 screenshots compared, 3 failures, all the
intended eyebrow change (services/_overview, services/_services,
mobile/services), reviewed and accepted. bin/hugo-build clean. macOS only.

Three variants remain for the following commits: careers-critical.css,
components/content-block.css, and pages/friday-report.css (which also deviates
on colour, using --ruby-700).

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
careers-critical.css, components/content-block.css and pages/friday-report.css
now match pages/blog-list.css `.blog-eyebrow`: 12px / 700 / 0.14em / uppercase /
--color-ruby. Four variants become one.

friday-report was the largest deviation - 13px, weight 600, 0.18em tracking, and
--ruby-700 rather than --color-ruby.

**The suite is green and that proves nothing here.** None of these three pages
is in the screenshot set, so `[snap_diff] 53 screenshots compared, no failures`
means "not captured", not "unchanged" - exactly the trap the phase brief warns
about for eyebrows. Verified by computed style in the rendered production build
instead:

  fontSize 12px · fontWeight 700 · letterSpacing 1.68px (= 0.14em x 12) ·
  textTransform uppercase · color rgb(204,52,45)

**Contrast measured, because this commit darkens nothing and lightens one
thing.** Moving friday-report from --ruby-700 to --color-ruby reduces contrast.
Against that page's actual background - rgb(253,245,244), a warm tint rather
than white - the ratio is **4.77:1**. That passes AA for normal text (4.5:1),
but the margin is thin: on pure white the same pair is ~5.1:1, and any future
darkening of that tint would push it under. Recorded so the next person to
touch that surface knows the eyebrow is the constraint.

Gate: bin/test - [snap_diff] 53 screenshots compared, no failures, no baseline
moved. bin/hugo-build clean. macOS only.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
@coderabbitai

coderabbitai Bot commented Aug 21, 2026

Copy link
Copy Markdown
Contributor

Important

  • 🔍 Trigger review

This repository does not receive automatic reviews because it has fewer than 10 stars.

⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro Plus

Run ID: 6b04156d-e1b6-40c4-bbd8-6ef37d31a799


Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@github-actions

github-actions Bot commented Aug 21, 2026

Copy link
Copy Markdown
Contributor

Review caught it and the cascade confirms it: `pages/careers.css:1215`
re-declares the identical selector
(`.fl-builder-content .careers-why-us-eyebrow .fl-rich-text`) with
`font-weight: 600`, and pages/ loads AFTER critical/ at equal specificity. My
edit to careers-critical.css could never take effect.

Reverted rather than left in. A change that looks like work and does nothing is
worse than no change: it reads as "careers is done" to the next person, and the
green suite would not contradict them because careers is not in the screenshot
set at all.

Scope correction that follows from the same finding: **"one eyebrow style" is 41
FL eyebrow rules across 8 files**, not the four I found by grepping for the
obvious names - homepage (11), single-service (7), about-us (6),
single-use-cases (5), services-critical (4), careers (3), careers-critical (3),
use-cases (2). Aligning 41 copies is the wrong shape anyway; the intent is ONE
definition. That needs a centralised rule plus a load-order decision so it wins
against the per-page declarations, which is a design call rather than a sweep.

What remains in this branch is verified and effective: services-critical
(rendered and read), components/content-block, and pages/friday-report (computed
style confirmed, contrast measured at 4.77:1).

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
@pftg

pftg commented Aug 21, 2026

Copy link
Copy Markdown
Member Author

Attempted the full sweep review asked for (all 41 FL eyebrow rules) and reverted it — it introduces a WCAG AA failure. Measured in the rendered production build:

Eyebrow Contrast Threshold
home-services-eyebrow 4.10 4.5 ❌ ruby on black
home-clients-eyebrow 4.10 4.5 ❌ ruby on black
home-why-us-eyebrow 5.13 4.5 ✅ on white

The canonical eyebrow (--color-ruby, 12px) was designed against the blog’s light surfaces. Shrinking to 12px makes these unambiguously "normal text", so the 4.5:1 threshold applies and ruby-on-black fails at 4.10.

"One eyebrow style" cannot be one style. Eyebrows sit on both light and dark surfaces, so the canonical form needs a dark-surface variant with a lighter ruby — a design decision, not a mechanical sweep. technologies.css:10 already hints at this ("on the .white variant this eyebrow sits on the near-black band").

This PR keeps only the three conversions verified safe on light surfaces: services-critical, components/content-block, pages/friday-report.

Branch is green: [snap_diff] 53 screenshots compared, no failures.

pftg and others added 2 commits August 21, 2026 04:37
Measured in the rendered production build, and the second consequence is the
one worth having:

| Token | on #000 | on --surface-ink #14110f |
|---|---|---|
| --color-ruby #cc342d | 4.10 FAIL | 3.67 FAIL |
| --color-ruby-hover #e04a42 | 5.23 pass | 4.68 pass (thin) |
| --ruby-700 #9e2620 | 2.75 FAIL | 2.46 FAIL |

**1. "ONE eyebrow style" is self-contradictory as written.** The canonical
eyebrow was designed against the blog's LIGHT surfaces. Applied site-wide it
drops home-services-eyebrow and home-clients-eyebrow to 4.10:1 on their dark
band - below AA for normal text, which 12px unambiguously is. I swept all 41
rules, measured, and reverted rather than ship it.

**2. Migrating the dark bands to --surface-ink makes contrast WORSE.** #14110f
is lighter than #000, so ruby-on-dark falls 4.10 -> 3.67. That links the two
blocked items: the footer/dark-surface work cannot ship before the on-dark
accent is decided, or it degrades contrast on every band it touches. Nothing in
the plan connects them, and a sweep done in either order alone would have
regressed accessibility silently - those homepage sections carry no contrast
test.

Only --color-ruby-hover clears AA on both grounds, and it is named for a hover
state, so using it as a static accent is semantically wrong. The ramp has
--ruby-700 for "text-on-light where AA needs more" and no counterpart for dark.
Naming one is a design call, not a sweep, so it goes to Outstanding rather than
into a commit.

Docs only. bin/hugo-build clean.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Two review findings, both verified and fixed.

**friday-report had no screenshot coverage, and the test said to add it here.**
`desktop_site_test.rb` carried, verbatim: "No screenshot baseline yet: the 2608
site-wide recolour is mid-flight and would churn it immediately. Record with the
bundle's first visual PR." This IS that PR - 1a.4 moved `.friday-eyebrow` onto
the canonical style - so computed-style checks alone were the only thing
guarding a visual change.

Adding the assertion was not enough on its own: `friday_report` is not in
`CRITICAL_TESTS`, so `bin/test` skipped it and the suite reported 34 runs / 53
screenshots exactly as before. Coverage that never executes is the same
"looks like work, does nothing" failure as the careers eyebrow earlier on this
branch, so `friday_report` is now in the critical list. Suite goes 34 -> 36 runs,
87 -> 99 assertions, and two baselines record.

Baselines reviewed before committing, not merely captured: mean brightness 0.963
(not a black or error frame) and the render read end to end - nav, hero, the
canonical ruby eyebrow, canon-compliant proof chips, disclaimer, report body.

**The AA blocker was only in the project README, which is not on the path.**
`design/site-palette.md` now carries the measured table and a standing rule:
until an on-dark ruby is named, do not apply a ruby text token to any of the
three deliberate dark surfaces. AGENTS.md routes sessions through OKF, not
through a project README - the same "recorded but not on the path" failure this
branch already hit once with the stitch route.

Gate: bin/test - 36 runs, 99 assertions, 0 failures, [snap_diff] 53 screenshots
compared, no failures, plus 2 newly recorded. bin/hugo-build clean.
okf_validate .okf exits 0 conformant; --strict exits 1 by design on this bundle.

NOT done, and flagged for the fourth time: Linux baselines. Scoped out by Paul
("handled in parallel PR, ignore for now") and unrecordable locally without
planting false drift.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
@pftg
pftg merged commit 84cf3f3 into master Aug 21, 2026
4 of 5 checks passed
@pftg
pftg deleted the phase-1a4-eyebrow branch August 21, 2026 02:52
pftg added a commit that referenced this pull request Aug 21, 2026
**My PurgeCSS check was a false green.** I cited `grep -rc 'c-button--primary'
_dest/public-dev/css/*.css` returning nothing. That command returns nothing
whether or not the component is adopted: public-dev is built in DEV mode where
PurgeCSS is disabled, and this CSS is emitted INLINE in the HTML rather than
under css/*.css. Re-verified against the production tree - `grep -rl 'c-button'
_dest/public-test/` returns nothing and components.css is not referenced from
index.html - so the conclusion survives, but the evidence I published for it did
not. Both are now recorded, because "right answer, wrong proof" is the failure
that makes the NEXT claim untrustworthy.

**The live buttons are five families, not one.** `.fl-button`, `.btn`/
`.btn-primary` (navigation), `.btn--primary` (shortcodes/cta), `.action-button`
(use-cases) and `.pp-button` (services). My "sweep `.fl-button`" framing would
have left four families outside the roles.

**The tags deliverable had vanished from the matrix.** My four-row table
silently replaced "tags to ink site-wide" - an actual scope item - with the
`--rr-*` alias deletion, which the brief lists separately. An executor reading
it would skip the 17-bundle tag work entirely. Tags restored as an OPEN row,
honestly marked NOT investigated, and the alias row relabelled as the separate
deletion item.

**The plan linked to a blocker absent from this branch.** It was cut from a
stale origin/master predating #528. Rebased onto current master; the ruby-on-dark
Outstanding entry the note points at now exists here.

Docs only; bin/hugo-build clean.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
pftg added a commit that referenced this pull request Aug 21, 2026
…ed (#529)

* "Three button roles" is already built and never adopted

Investigated the last untouched 1a.4 item. `components/c-button.css` already
defines exactly three roles - --primary (ruby/white), --secondary (white/dark),
--tertiary (transparent/ruby) - and is already tokenised apart from four
`#ffffff` literals.

I tokenised those literals, then checked whether it mattered and reverted:
**`c-button--*` appears ZERO times in any template or content file**, and
PurgeCSS strips it from every shipped bundle - `grep -rc 'c-button--primary'
_dest/public-dev/css/*.css` returns nothing. The component was built and never
adopted; the live buttons are FL Builder's `.fl-button`.

Reverting rather than shipping was the point. A tidy diff against dead code
reads as "button roles: done" to the next person and changes nothing a visitor
sees - the third instance of that failure on this phase, after the careers
eyebrow (overridden by a later file) and the friday screenshot assertion
(excluded from CRITICAL_TESTS).

The real item is either adopting c-button in templates (a markup migration) or
bringing `.fl-button` onto the three roles (another sweep through the per-page
FL export CSS). Both are larger than the plan line implies, and the second is
the same legacy-export problem as the footer and eyebrow items. The tertiary
role also sits on the on-dark AA blocker wherever it lands on a dark band.

Recorded in Outstanding. Docs only; bin/hugo-build clean.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>

* Correct the 1a.4 plan against what execution actually found

Recording measured reality in the plan itself, because the next session reads
the plan and would otherwise re-estimate the same four items the same way.

One of four items was what the line said. The alias deletion shipped first try
with zero visual delta. The other three are materially different work:

* Footer onto surface-ink is not a footer change - it is one edge of a dark
  region built from a CSS background, an SVG fill on a pointer-events:none
  shape layer, and a painter still unidentified. 7+ bundles, 1b in size.
* One eyebrow style cannot be one style - the canonical form was designed
  against LIGHT surfaces and drops two homepage eyebrows to 4.10:1 when applied
  site-wide. Swept, measured, reverted.
* Three button roles is already built and never adopted - c-button--* appears
  zero times in markup and PurgeCSS strips it from every bundle.

And the connection nothing in the plan made: **two of them are gated by the same
missing token.** --color-ruby is 4.10:1 on #000 and 3.67:1 on --surface-ink, so
the dark-surface migration makes contrast WORSE. Eyebrows and the tertiary
button role both sit on it.

Also recorded, because it is the transferable part: the estimates were written
against the TOKEN layer while the work is against the FL-Builder export CSS that
redeclares everything per page. Three changes this phase looked complete, passed
every gate, and did nothing at runtime - an eyebrow rule overridden by a later
file, a screenshot assertion excluded from CRITICAL_TESTS, and a tokenisation of
purged dead code. The plan now tells the next session to verify a change reaches
the rendered page before counting it done.

Docs only; bin/hugo-build clean.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>

* Fix all four review findings, including a false green in my own evidence

**My PurgeCSS check was a false green.** I cited `grep -rc 'c-button--primary'
_dest/public-dev/css/*.css` returning nothing. That command returns nothing
whether or not the component is adopted: public-dev is built in DEV mode where
PurgeCSS is disabled, and this CSS is emitted INLINE in the HTML rather than
under css/*.css. Re-verified against the production tree - `grep -rl 'c-button'
_dest/public-test/` returns nothing and components.css is not referenced from
index.html - so the conclusion survives, but the evidence I published for it did
not. Both are now recorded, because "right answer, wrong proof" is the failure
that makes the NEXT claim untrustworthy.

**The live buttons are five families, not one.** `.fl-button`, `.btn`/
`.btn-primary` (navigation), `.btn--primary` (shortcodes/cta), `.action-button`
(use-cases) and `.pp-button` (services). My "sweep `.fl-button`" framing would
have left four families outside the roles.

**The tags deliverable had vanished from the matrix.** My four-row table
silently replaced "tags to ink site-wide" - an actual scope item - with the
`--rr-*` alias deletion, which the brief lists separately. An executor reading
it would skip the 17-bundle tag work entirely. Tags restored as an OPEN row,
honestly marked NOT investigated, and the alias row relabelled as the separate
deletion item.

**The plan linked to a blocker absent from this branch.** It was cut from a
stale origin/master predating #528. Rebased onto current master; the ruby-on-dark
Outstanding entry the note points at now exists here.

Docs only; bin/hugo-build clean.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 5 <noreply@anthropic.com>
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