Skip to content

White labels on status tags, sharper and aligned column headings - #56

Open
Fivell wants to merge 1 commit into
activeadmin-plugins:masterfrom
yeti-switch:status-tags-and-header-text
Open

Fivell wants to merge 1 commit into
activeadmin-plugins:masterfrom
yeti-switch:status-tags-and-header-text

Conversation

@Fivell

@Fivell Fivell commented Oct 3, 2026 •

Copy link
Copy Markdown
Member

Two reports after 3.0.0 — the label inside a status tag should be white, and index-table column headings read too soft — plus what verifying them turned up.

Status tags

White on its own was the wrong fix. Against the five shipped fills it lands between 2.35:1 and 3.78:1, under the 4.5:1 small text needs, which is exactly why the label went black during the review of #49. So the fills move down with it:

fill was is
neutral #8a909a → #707681 3.21:1 4.57:1
ok / published / green / yes #8daa92 → #5e7e63 2.53:1 4.53:1
notice / blue #6090db → #3874d2 3.23:1 4.57:1
warn / orange #e29b20 → #9e6c15 2.35:1 4.56:1
error / red #d45f53 → #ce483b 3.78:1 4.55:1

The five fills join $skinStatusTagTextColor as variables, so black-on-pale is still one line away. They were literals inside the mixin call before.

Column headings

Too soft. $skinTableHeaderTextColor was #5e6469, 4.93:1 against the header fill while the rows underneath run at 10.15:1. Passing, but visibly weaker than the data it labels. It takes $skinTextColor now.

Not above their own columns. ActiveAdmin puts the sort arrow inside the heading link, on the left, cleared with padding-left: 13px. The cell and the heading share the same 12px padding, so the cell is aligned — but the label inside is pushed 13px right while the data below starts at the padding edge. Every sortable column is affected, not only the one reported.

                   before   after
cell left          559.9    559.9
heading link left  571.9    571.9
tag left           571.9    571.9
heading TEXT left  584.9    571.9

Moving the background image to the right edge is not enough: the link is display: block, so the arrow would park at the far side of the column instead of beside the label. It is a pseudo-element now, which

  • sits immediately after the text,
  • keeps the link full width, so the whole cell stays clickable,
  • takes currentColor — the stock sprite is a fixed grey PNG that cannot follow the text into dark mode.

At 0.6 opacity the unsorted marker is 3.40:1 light and 4.22:1 dark against the header fill. It is the only thing separating a sortable heading from a plain one, so WCAG 1.4.11 asks 3:1 of it.

The check that should have caught this

rake css compares the README variables table against the declarations. It was doing so in one direction, and loosely. Four holes, each reproduced before and after the fix:

what passed now
undocumented variable a new !default with no row, while the success line claimed the table matched every declaration fails
blank cell the name entered the documented set, exempting it from the undocumented check, while the mismatch check skipped it for having no value — passing on both sides fails
row listed twice the last row won, so the table could agree with the stylesheet while a reader meets the stale one fails
declared twice unnoticed, though Sass keeps the first !default and drops the rest fails

The advertised count comes from the declarations now, rather than a hand-maintained constant that said 52 while 81 variables were being compared.

Screenshots

All four README sheets are reshot. The dummy index carries a Tags column under a sortable heading — the block-column shape the reports came from — labelled release / draft / featured / deprecated / review, which between them use all five tag colours; the previous pair showed two.

Before and after, zoomed, in the comments: light and dark.

Supersedes #55.

@Fivell
Fivell force-pushed the status-tags-and-header-text branch from d18e3e5 to d0663b5 Compare October 3, 2026 12:38
@Fivell Fivell changed the title White labels on status tags, sharper column headings White labels on status tags, sharper and aligned column headings Oct 3, 2026
@Fivell
Fivell force-pushed the status-tags-and-header-text branch from d0663b5 to 95d70df Compare October 3, 2026 12:52
@Fivell

Fivell commented Oct 3, 2026

Copy link
Copy Markdown
Member Author

Before and after, zoomed. Top half of each image is 3.0.0 as released, bottom half is this branch. Same page, same data.

Light

Light

Dark

Dark

Three things change in the same frame:

  1. Tag labels go from black on a pale fill to white on a darker one — the fill moves with the label so the result still clears 4.5:1.
  2. Headings line up with their columns. LegA DC sat 13px right of the tags it labels, Published On 13px right of the dates. Both start at the column edge now.
  3. The sort marker sits beside the label instead of in front of it, and takes currentColor — the stock sprite is a fixed grey PNG, which is why in the dark half of each image the old arrow is barely there while the new one matches the heading.

The marker also still covers the whole cell for clicking: the link keeps display: block, only the arrow moved into a pseudo-element.

@Fivell
Fivell force-pushed the status-tags-and-header-text branch from 95d70df to c57e4cf Compare October 3, 2026 14:32
@Fivell

Fivell commented Oct 3, 2026

Copy link
Copy Markdown
Member Author

Rebased on #57, which this now sits on top of — the four commits collapse to three once that lands.

#57 is right about something this branch had wrong, and it is my regression: > li#theme_toggle { display: flex } breaks the utility navigation, because ActiveAdmin lays that row out as li { display: inline }. My screenshots never showed it, because the dummy admin had an empty utility nav and the injected switch was the only item in it. The dummy now declares a username, a clock and a logout link, as yeti-web does, so the row has something to break.

Utility nav

Top: 3.0.0 as released — the switch takes a line of its own and pushes the username, clock and logout onto a second row. Bottom: with inline-flex.

Two changes to #57's work

The guard it added only fires while display is written first. It matches /^\s*display:\s*(?:flex|block|grid)\s*;/ against the whole rule, which works because sassc puts the first declaration on its own line. Swap the two declarations in the source and it returns nil — I checked. It now reads the rule body and compares each declaration, so order does not matter. Verified by writing { align-items: center; display: flex; } and watching it fail.

DECLARED_ROWS was fiction. Nothing compares it to anything; it is interpolated into the success line. It said 52, #57 raised it to 53, and the real number of variables being compared is 81. It is counted from the comparison now.

The one real disagreement

#57 makes the label white but leaves the fills as they were, which is 2.35:1 to 3.78:1 — its own comment says to set #000000 for AA. This branch moves the fills down with the label instead, so white clears 4.5:1 with nothing to configure:

fill was is
neutral #8a909a → #707681 3.21:1 4.57:1
ok #8daa92 → #5e7e63 2.53:1 4.53:1
notice #6090db → #3874d2 3.23:1 4.57:1
warn #e29b20 → #9e6c15 2.35:1 4.56:1
error #d45f53 → #ce483b 3.78:1 4.55:1

$skinStatusTagTextColor stays, and the five fills become variables alongside it, so the other choice is still one line away.

Everything in one frame

Light

Light

Dark

Dark

Top half of each is 3.0.0 as released, bottom half is this branch. Tag labels go white on darker fills; headings line up with their columns instead of sitting 13px right of them; the sort marker moves beside the label and takes currentColor, which is why the old arrow is barely visible in the dark half and the new one matches the heading.

@Fivell
Fivell force-pushed the status-tags-and-header-text branch from c57e4cf to 9891a41 Compare October 3, 2026 14:36
@Fivell
Fivell requested a balanced review from Copilot October 3, 2026 14:49

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copilot review overview

🟡 Changes recommended

A duplicate Sass variable and incomplete declaration-to-documentation comparison should be corrected.

Review effort: Balanced
Findings: 1 Medium severity · 1 Low severity

Open (2)
What changed in this PR

Improves status-tag contrast and index-table heading clarity and alignment.

Changes:

  • Adds configurable, WCAG-compliant status-tag colors.
  • Strengthens and realigns sortable table headings.
  • Extends Sass override and README consistency checks.
File Description
README.md Documents updated theme variables.
active_admin_theme.scss Updates tag colors and table headings.
test/​css_check.rb Expands Sass and documentation checks.

💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.

Comment thread test/css_check.rb Outdated
Comment thread app/assets/stylesheets/wigu/active_admin_theme.scss
@Fivell

Fivell commented Oct 3, 2026

Copy link
Copy Markdown
Member Author

Both findings confirmed and fixed in 83be687.

Duplicate declaration. Right, and it arrived when this branch rebased onto #57 — that PR added its own $skinStatusTagTextColor next to the table header colours while this branch declares it beside the status tag fills. Sass keeps the first !default, so the second was dead code. Both read #ffffff, so nothing rendered differently; it was waiting to drift. One declaration now, with the fills it belongs to.

One-directional check. Also right, and the success line was the worse half of it: I added $skinTotallyUndocumented: #ff00ff and rake css passed while printing README table matches 81 declarations. It compares both sets now — a declaration with no row fails, a row naming nothing fails, and a second declaration of the same name fails. The count comes from the declarations, not the rows.

Verified by reintroducing each defect:

$skinTotallyUndocumented: declared in the stylesheet, absent from the README table
$skinStatusTagOkColor: declared more than once; Sass keeps the first !default and drops the rest

The second one is how I noticed a git checkout -- app during testing had quietly reverted the dedup — the guard caught its own fix going missing.

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copilot review overview

🟡 Changes recommended

The README checker can overlook paired variables whose documented default is blank.

Review effort: Balanced
Findings: 1 Medium severity

Open (1)
Resolved since last review (2)

Comment thread test/css_check.rb Outdated
@Fivell
Fivell force-pushed the status-tags-and-header-text branch from 04915c3 to 0d84f26 Compare October 3, 2026 15:17
@Fivell
Fivell requested a balanced review from Copilot October 3, 2026 15:32

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copilot review overview

🟡 Changes recommended

The sort indicator misses accessibility contrast requirements, and README validation can overlook incomplete or duplicate entries.

Review effort: Balanced
Findings: 4 Medium severity · 1 Low severity

Open (5)

Comment thread app/assets/stylesheets/wigu/active_admin_theme.scss Outdated
Comment thread test/css_check.rb Outdated
Comment thread test/css_check.rb
Comment thread app/assets/stylesheets/wigu/active_admin_theme.scss Outdated
@Fivell

Fivell commented Oct 5, 2026

Copy link
Copy Markdown
Member Author

All five confirmed and fixed in 3c7823d. The numbers on the marker were exact — I measured the blend rather than trusting them:

light  #323537 on #e6e9ee   opacity 0.4 → 2.13:1    0.6 → 3.40:1
dark   #dde2e8 on #363c43   opacity 0.4 → 2.73:1    0.6 → 4.22:1

0.6 it is. It is the only thing telling a sortable heading from a plain one, so 1.4.11 applies.

Blank cells. Right, and worse than described: the name went into documented, which exempted it from the undocumented check, while the mismatch check skipped it for having no value — it passed on both sides. Blank cells are not recorded now. Reproduced with a paired row ending | `#ffffff` / |:

$skinInputBgColorDark: declared in the stylesheet, absent from the README table

Duplicate rows. Also right, and symmetric to the declaration side I had already added. Reproduced by listing $skinBorderRadius twice:

$skinBorderRadius: listed more than once in the README table

The contradictory comment. Fair — 2.35 to 3.78 belonged to the fills this palette replaces, not to the ones the sentence sits above. Reworded so the old range is identified as the old one.

Screenshots reshot for the marker change.

@Fivell
Fivell force-pushed the status-tags-and-header-text branch from 0d84f26 to 56fbbd9 Compare October 5, 2026 08:30
@Fivell
Fivell requested a balanced review from Copilot October 5, 2026 09:00

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Comment thread README.md
| `$skinTableHeaderTextColor` / `$skinTableHeaderTextColorDark` | `#5e6469` / `#dde2e8` | index-table column header text |
| `$skinStatusTagTextColor` | `#ffffff` | status tag label; `#000000` passes WCAG AA on every fill |
| `$skinTableHeaderTextColor` / `$skinTableHeaderTextColorDark` | `$skinTextColor` / `#dde2e8` | index-table column header text; the body text colour, so headings read as strongly as the rows |
| `$skinStatusTagTextColor` | `#ffffff` | label inside every status tag |
Two reports after 3.0.0, and what verifying them turned up.

## Status tags

The label was black on a mid-tone fill. White on its own was the wrong fix —
against the five shipped fills it lands between 2.35:1 and 3.78:1, under the
4.5:1 small text needs, which is why it went black during the review of activeadmin-plugins#49.
So the fills move down with the label. Measured against white:

  neutral  #8a909a -> #707681   3.21 -> 4.57
  ok       #8daa92 -> #5e7e63   2.53 -> 4.53
  notice   #6090db -> #3874d2   3.23 -> 4.57
  warn     #e29b20 -> #9e6c15   2.35 -> 4.56
  error    #d45f53 -> #ce483b   3.78 -> 4.55

The five fills join $skinStatusTagTextColor as variables, so the other choice
is still one line away. They were literals inside the mixin call before.

## Column headings

$skinTableHeaderTextColor was #5e6469, 4.93:1 against the header fill while
the rows underneath run at 10.15:1 — passing, but visibly softer than the data
it labels, which is what made it look blurry. It takes $skinTextColor now.

They also did not line up with their own columns. ActiveAdmin puts the sort
arrow inside the heading link, on the left, cleared with `padding-left: 13px`.
Cell and heading share the same 12px padding, so the cell is aligned, but the
label inside is pushed 13px right while the data below starts at the padding
edge. Measured on a block column of status tags, the shape the report came
from:

  cell left          559.9   559.9
  heading link left  571.9   571.9
  tag left           571.9   571.9
  heading TEXT left  584.9   571.9

Moving the image to the right edge is not enough: the link is `display: block`,
so the arrow would park at the far side of the column. It is a pseudo-element
now, which puts it beside the label, keeps the link full width so the whole
cell stays clickable, and lets the marker take currentColor — the stock sprite
is a fixed grey PNG that cannot follow the text into dark mode. At 0.6 opacity
it is 3.40:1 light and 4.22:1 dark against the header fill; it is the only
thing separating a sortable heading from a plain one, so WCAG 1.4.11 asks 3:1.

## The check that was supposed to prevent this

rake css compares the README variables table against the declarations. It was
doing so in one direction only, and loosely:

- a variable with no row in the table passed, while the success line claimed
  the table matched every declaration;
- a blank cell counted as documentation — the name entered the documented set,
  which exempted it from the undocumented check, while the mismatch check
  skipped it for having no value, so it passed on both sides;
- a name listed twice kept the last row, so the table could agree with the
  stylesheet while a reader meets the stale row first;
- a name declared twice went unnoticed, though Sass keeps the first !default
  and drops the rest.

All four fail now, each reproduced before and after. The advertised count comes
from the declarations rather than a hand-maintained constant that said 52 while
81 variables were being compared.
@Fivell
Fivell force-pushed the status-tags-and-header-text branch from 56fbbd9 to 4c3f43b Compare October 5, 2026 09:07
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.

2 participants