Phase 1a.4: one eyebrow style (4 variants → 1) - #528
Conversation
"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>
|
Important
This repository does not receive automatic reviews because it has fewer than 10 stars. ⚙️ Run configurationConfiguration used: Path: .coderabbit.yaml Review profile: CHILL Plan: Pro Plus Run ID: 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. Comment |
Screenshot diffs detected
|
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>
|
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:
The canonical eyebrow ( "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. This PR keeps only the three conversions verified safe on light surfaces: Branch is green: |
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>
**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>
…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>
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-eyebrow— 12px / 700 / 0.14em / uppercase /--color-rubyservices-critical.css--color-ruby, weight 600 — no size, tracking or transformcareers-critical.csscomponents/content-block.csspages/friday-report.css--ruby-700The 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 failuresmeans "notcaptured", not "unchanged" — exactly the trap the phase brief flags for
eyebrows.
Verified by computed style in the rendered production build instead:
For services, which is captured, I read the rendered
_overview.png— theeyebrow 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, notwhite — 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-buildclean1a.4 remaining
Three button roles (not started). Footer onto
surface-inkstays blocked —see #526; it needs dividers and adjacent dark sections migrated together across
7+ bundles.
🤖 Generated with Claude Code