Skip to content

fix(theme): remove targeted the wrong theme, switching orphaned a block, dark topbar unreadable - #104

Merged
ako merged 1 commit into
mainfrom
claude/mendix-default-styling-1fgvpm
Aug 6, 2026
Merged

fix(theme): remove targeted the wrong theme, switching orphaned a block, dark topbar unreadable#104
ako merged 1 commit into
mainfrom
claude/mendix-default-styling-1fgvpm

Conversation

@ako

@ako ako commented Aug 6, 2026

Copy link
Copy Markdown
Owner

Follow-up to #102, which merged before these landed. Three defects reported from an independent test build (Feedline, in ako/mxcli-rssreader — ~1,900 lines of MDL and ~1,400 lines of custom SCSS), each fixed with a regression test proven to fail against the old behaviour.

# Defect Root cause Verified
15 theme remove with no name removed nothing and exited 0 the bare invocation targeted the built-in default instead of the installed theme bare remove on a ledger project removes ledger; a second one errors
16 switching themes doubled _mxcli-atlas-map.scss the protected-path branch in remove() returned without writing the truncation it described signal → ledger → console, one block and 207 lines throughout (was 197 → 395)
17 topbar language selector unreadable in every dark palette (1.13:1) the guard matched at (0,1,0) against Atlas's (0,3,0), and color: inherit was the wrong value regardless 17.79:1 light, 19.47:1 dark, measured in a browser

On #17

The guard named the right element and still lost. Atlas's rule is .navbar-brand .widget-language-selector .current-language-text at (0,3,0); mine was a bare .current-language-text at (0,1,0), which only appeared to work on layouts that do not nest the selector under .navbar-brand. And color: inherit was the wrong value regardless — it inherits body ink, which is dark, while the rail is dark in both palettes. Now re-declared at matching specificity and resolved through the rail token.

My original verification was too shallow to catch this: it read getComputedStyle(el).color, saw white, and stopped. The Playwright probe now computes the WCAG ratio against the first non-transparent ancestor background — the two lines that separate "looks fine" from 1.13 vs 19.47. Recorded as a symptom row in fix-issue.md.

Behaviour changes worth flagging

  • theme remove with no name resolves the installed theme from the mxcli:theme markers, and errors on an unthemed project rather than exiting 0.
  • theme apply with no name refreshes the theme the project already has, falling back to the default only when it has none. Silently switching a ledger project to signal was the same class of surprise as the remove bug.

Testing

The #15 bug lived in the command's argument handling, not in the theme package, so a test calling theme.Resolve directly would keep passing while the CLI stayed broken. cmd/mxcli/cmd_theme_test.go drives the real cobra command — the same shape as the "grep the call sites, not the helper" lesson already in fix-issue.md.

Also documented, as a caveat rather than a defect: apply appends its block to the end of main.scss, after any @import the project already had there. That matters to a project relying on import order rather than on specificity.

Full suite, check-mdl, gofmt and vet pass.

🤖 Generated with Claude Code

https://claude.ai/code/session_01JEZmExJUvn2nWTWE9mrd4i


Generated by Claude Code

…ck, dark topbar unreadable

Three defects reported from the RssReader test build (MXCLI-FINDINGS 15-17),
each fixed with a regression test proven to fail against the old behaviour.

15. `mxcli theme remove -p app.mpr` — the invocation the docs show — targeted
    the built-in default rather than the theme actually installed. On a project
    themed with ledger or console it reported every file as unchanged, exited 0,
    and left the theme fully in place: a silent no-op on the documented command.
    Both apply and remove now resolve the target from the mxcli:theme markers.
    Remove has no fallback — an unthemed project is an error, not a no-op.
    Apply keeps one, since a project with no theme is exactly when installing
    the default is right; a bare apply on a themed project now refreshes that
    theme instead of silently switching it to signal.

16. Switching themes left the outgoing theme's block in _mxcli-atlas-map.scss
    and appended the incoming one beside it, doubling the file. Mine: the
    protected-path branch in remove() returned without ever writing the
    truncation it described. Harmless while the three Atlas maps are identical,
    but it broke the "only one theme at a time" invariant that exists precisely
    so two maps cannot fight in the cascade.

17. The topbar language selector measured 1.13:1 contrast in every dark palette
    — invisible, not merely low. Two mistakes stacked. The guard was a bare
    .current-language-text at (0,1,0) against Atlas's
    .navbar-brand .widget-language-selector .current-language-text at (0,3,0),
    so it never won. And `color: inherit` was the wrong value anyway: it
    inherits body ink, which is dark, while the rail is dark in both palettes.
    Now re-declared at matching specificity and resolved through the rail token.
    Measured in a browser: 17.79:1 light, 19.47:1 dark.

The command-level bug in #15 needed a command-level test. cmd_theme_test.go
drives the real cobra command, because a test calling theme.Resolve directly
would keep passing while the CLI stayed broken — the same shape as the
"grep the call sites, not the helper" lesson already in fix-issue.md.

My own verification of #17 was too shallow to catch it: it read
getComputedStyle(el).color once, saw white and stopped. The probe now computes
the WCAG ratio against the first non-transparent ancestor background, which is
what turns "looks fine" into a number. Recorded in fix-issue.md.

Also documents a behaviour the report flagged but which is not a defect: apply
appends its block to the end of main.scss, after any @import the project already
had there, which matters to a project relying on import order rather than on
specificity.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01JEZmExJUvn2nWTWE9mrd4i
@ako
ako merged commit d1078d0 into main Aug 6, 2026
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