From 76c82a5e96a202406720b0c8a1070ba1060eb908 Mon Sep 17 00:00:00 2001 From: Ben Stull Date: Mon, 1 Jun 2026 07:22:19 -0700 Subject: [PATCH] v0.31.4: fix invisible light-surface btn-link + harmonize RFC breadcrumb action bar MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit `.btn-link` was a dark-header utility (white text on translucent white) reused on light surfaces — the RFC breadcrumb action bar, PR diff toggle, modals, discussion panel — where it rendered white-on-white and looked like missing buttons (reported: "Metadata"/"Claim ownership"/"Invitations" absent on a super-draft header). Root-cause fix: - Base .btn-link is now a light-surface secondary button (white fill, hairline border, dark label); the dark-header "Sign out" keeps the translucent-on-dark treatment via an .app-header .btn-link scope. - .breadcrumb-actions normalizes the toggle, filled CTAs, and secondary buttons to one height/radius/type as a single control group, and flex-wraps instead of clipping off the right edge. - Diff-mode active toggle now reads as clearly selected (filled ink). CSS-only; patch release, plain frontend rebuild applies it. No upgrade steps. Driver session 0059.0. Co-Authored-By: Claude Opus 4.8 --- CHANGELOG.md | 44 +++++++++++++++++++++++++++++++++++++ VERSION | 2 +- frontend/package.json | 2 +- frontend/src/App.css | 51 +++++++++++++++++++++++++++++++++++++------ 4 files changed, 90 insertions(+), 9 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index af643de..ad84b89 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -23,6 +23,50 @@ skip versions are the composition of each intervening adjacent release's steps in order — no A-to-B path is pre-computed beyond that. +## 0.31.4 — 2026-06-01 + +**Patch — bug fix + UI polish: secondary buttons that were invisible on +light surfaces now render legibly, and the RFC view's breadcrumb action +bar is harmonized into one coherent control group. CSS-only +(`frontend/src/App.css`); no schema, API, config, overlay, or secret +change — a plain frontend rebuild applies it. No upgrade steps. Shipped +from driver session 0059.0.** + +`.btn-link` was authored as a *dark-header* utility — white text on a +translucent-white fill (`rgba(255,255,255,0.15)`), the established +on-dark pattern for the app header's "Sign out". But the same class is +reused on **light** surfaces: the RFC breadcrumb action bar +(`RFCView.jsx`), the PR view's diff-mode toggle and "Edit title" control +(`PRView.jsx`), the invitations and inbox modals, and the discussion +panel. On those near-white backgrounds the buttons were white-on-white — +present in the DOM, fully functional, but visually invisible. The +reported symptom: on a super-draft's header, "Metadata", "Claim +ownership", and "Invitations" looked *missing*, while the filled CTAs +("Start Contributing", "Graduate to RFC repo") rendered fine because +their fill carried them. + +The fix is root-cause, not a per-site patch: + +- The base `.btn-link` rule is now a proper light-surface secondary + button (white fill, hairline `--c-gray-300` border, `--c-gray-700` + label, hover darkens both). This corrects every light-surface reuse at + once. +- The original translucent-on-dark treatment is preserved for the one + legitimate dark-surface use via an `.app-header .btn-link` scope, so + the header "Sign out" is unchanged. +- The breadcrumb action bar (`.breadcrumb-actions`) normalizes every + action — the discuss/contribute toggle, the filled CTAs, and the + secondary buttons — to one height, radius, and type scale, so the row + reads as a single intentional control group. The bar now `flex-wrap`s + instead of clipping buttons off the right edge when the set is wide. +- The diff-mode toggle's active option now reads as clearly selected + (filled ink) rather than relying on a weight change alone. + +Smooth hover transitions and the keyboard focus ring were already +provided globally by the v0.21.0 interaction-polish layer, so this +change adds no new motion or focus rules — it only corrects resting-state +color/contrast and harmonizes sizing. + ## 0.31.3 — 2026-05-30 **Patch — admin Users tab: "Last seen" reads "Never" for unclaimed diff --git a/VERSION b/VERSION index 8239f42..a8a0217 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -0.31.3 +0.31.4 diff --git a/frontend/package.json b/frontend/package.json index d9085ba..ac13081 100644 --- a/frontend/package.json +++ b/frontend/package.json @@ -1,7 +1,7 @@ { "name": "rfc-app-frontend", "private": true, - "version": "0.31.3", + "version": "0.31.4", "type": "module", "scripts": { "dev": "vite", diff --git a/frontend/src/App.css b/frontend/src/App.css index 6dfe3d1..c2e3f94 100644 --- a/frontend/src/App.css +++ b/frontend/src/App.css @@ -34,13 +34,31 @@ .role-owner { background: var(--c-warning-accent); } .role-admin { background: var(--c-accent-strong); } +/* The default surface for .btn-link is LIGHT (breadcrumb bar, PR view, + * modals, discussion panel, inbox). It renders as a quiet secondary + * button: white fill, hairline border, dark label. The dark app-header + * reuse ("Sign out") opts back into the translucent-on-dark treatment + * via the .app-header scope below. (Before v0.31.4 the base rule WAS the + * dark-header style, so every light-surface .btn-link was white-on-near- + * white and effectively invisible.) */ .btn-link { - color: var(--c-white); text-decoration: none; - background: var(--color-on-dark-soft); + display: inline-flex; align-items: center; + color: var(--c-gray-700); text-decoration: none; + background: var(--c-white); + border: 1px solid var(--c-gray-300); border-radius: var(--radius-md); padding: 4px 10px; - font-size: var(--text-base); + font-size: var(--text-base); cursor: pointer; +} +.btn-link:hover { + background: var(--c-gray-50); border-color: var(--c-gray-400); color: var(--c-ink); +} +/* Dark header reuse: restore the original translucent-white treatment. */ +.app-header .btn-link { + color: var(--c-white); background: var(--color-on-dark-soft); border-color: transparent; +} +.app-header .btn-link:hover { + color: var(--c-white); background: var(--color-on-dark-hover); border-color: transparent; } -.btn-link:hover { background: var(--color-on-dark-hover); } .btn-signin-header { color: var(--c-white); text-decoration: none; @@ -599,7 +617,7 @@ } .rfc-breadcrumb { - display: flex; align-items: center; gap: 8px; + display: flex; align-items: center; flex-wrap: wrap; gap: 8px; padding: 10px 16px; border-bottom: 1px solid var(--c-gray-200); background: var(--c-gray-50); @@ -612,7 +630,25 @@ } .breadcrumb-sep { color: var(--c-gray-300); } .breadcrumb-meta { color: var(--c-gray-500); font-size: var(--text-sm); } -.breadcrumb-actions { margin-left: auto; display: flex; gap: 8px; align-items: center; } +.breadcrumb-actions { + margin-left: auto; + display: flex; flex-wrap: wrap; justify-content: flex-end; + gap: 8px; align-items: center; min-width: 0; +} +/* Normalize every action in the bar to one height + shape so the mode + * toggle, the filled CTAs (Start Contributing / Open PR / Graduate) and + * the secondary buttons (Metadata / Claim ownership / Invitations / …) + * line up as a single, intentional control group. Higher specificity + * than the per-variant rules, so it harmonizes their size/radius/type + * without disturbing each variant's fill colors. */ +.breadcrumb-actions > button, +.breadcrumb-actions > a { + display: inline-flex; align-items: center; + height: 30px; padding: 0 12px; + border-radius: var(--radius-md); + font-size: var(--text-sm); font-weight: 600; + white-space: nowrap; +} .btn-mode-toggle { font-size: var(--text-sm); font-weight: 600; @@ -1444,7 +1480,8 @@ font-size: var(--text-sm); } .diff-mode-toolbar .btn-link.active { - font-weight: 600; color: var(--c-ink); + font-weight: 600; color: var(--c-white); + background: var(--c-ink); border-color: var(--c-ink); } .pr-diff-accent { margin-left: auto;