fix(ui): define the orphan .mono class and restore the .nb nowrap span - #161
Merged
Merged
Conversation
Two class-parity defects measured by the C1986 audit (`tmp/classparity.py`, three independent extractions) are fixed here; both were silent, because the affected elements still rendered — just without the intended styling rule. 1. `.mono` was referenced but never defined anywhere The sharing table's Key cell has been written as `<td class='mono'>` since the initial UI commit (d70e032) while no commit ever contained a `.mono` rule, so the cell fell back to the UI font. Measured (headless computed styles, both themes/languages): before `font-family: -apple-system, "system-ui", …` and `font-variant-numeric: normal`, while the `.num` cells in the same row got `ui-monospace, …` + `tabular-nums`. After: `ui-monospace, …`. Alignment is deliberately left alone (the prototype writes `class="num"` on that cell, which would also right-align it); this only restores the monospace face. 2. `.nb` (white-space: nowrap) lost together with its span The login brand headline used to wrap "token plan" in `<span class="nb">`, and the prototype defines `.nb { white-space: nowrap }` (line 132) so the phrase never breaks. Both the span and the rule were dropped in the migration, and the ZH headline then broke inside the phrase. Measured at 1024/1280/1440/1912: before, `token` and `plan` sat on different lines (top 137 vs 185, 149 vs 203) in all four widths; after, both on the same line (137==137, 149==149), with a real `<span class="nb">` in the DOM whose computed white-space is `nowrap`. Since `applyStatic()` injects i18n values via `innerHTML`, the span lives in the `login.brand.headline` values for both ZH and EN (markup inside i18n values already exists for `login.foot` / `ops.users.sub`); the static ZH default in index.html is kept identical to the i18n value. Also bumps the asset cache-bust token `?v=20260911-5` -> `?v=20260911-6` (5 refs) so the CSS/JS changes are picked up. Verification - `cargo test`: 148 passed / 0 failed - `cargo fmt --check` clean, `cargo clippy --all-targets -- -D warnings` clean - `node --check` on api.js / data.js / i18n.js / app.js: all OK - i18n parity gate: ZH 762 == EN 762, 0 unresolved - `classparity.py`: bucket [1] 4 -> 3 (only the disproved JS toggle hooks `admin-pane` / `ops-pane` and the globally-covered `tx-count` remain), bucket [2] 17 -> 16 (`.cap` resolved as a deliberate rename to `.recent-label`), bucket [3] still 0 -> the global reset layer stays complete. - A/B acceptance probe over both trees built by the same generator (`git archive HEAD ui` vs the working tree): `.mono` monospace false -> true in both languages; `.nb` phrase split true -> false at every measured width. - Reset-layer regression guard re-run: native control count still 0 / 140.
This was referenced Sep 11, 2026
Merged
argszero
added a commit
that referenced
this pull request
Sep 14, 2026
Ships the 76 PRs merged since v0.7.22 (#161-#237), the largest release so far. Database schema moves 12 -> 14: - v13 (#217): `keys.used` changes unit from tokens to points, and the live values are healed from the ledger (`used = SUM(transactions.pts WHERE type='consume')`), gated on schema_version < 13. - v14 (#234): four indexes for the monthly aggregates — `transactions(user_id, time, type, pts)`, `transactions(time, type, pts)`, `usage_records(time)`, `usage_records(user_id, time)`. Deployments must apply the DeepSeek flash rename (#233) to their own config.toml: `seed_models` is a full sync, so a model absent from the config is deleted at startup; the retired names are gone from config.example.toml. - Cargo.toml / Cargo.lock: 0.7.22 -> 0.7.23. - ui/index.html: asset cache-bust 20260912-4 / 20260912-5 / 20260914-1 / 20260914-4 / 20260914-9 -> 20260914-10 (all five refs). - CHANGELOG.md: v0.7.23 entry, grouped by area with the PR and hash of each fix. Gates: `cargo test` 249 passed / 0 failed, `cargo fmt --check` clean, `node --check` on the four ui/js files OK.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Two silent UI defects found by the class-parity audit of the prototype vs. the implementation are fixed here. Both were invisible in ordinary use because the affected elements still rendered — just without the styling rule they were asking for.
.monowas referenced but defined nowhere. The sharing table's Key cell has carriedclass='mono'since the initial UI commit (d70e032), yet no commit ever contained a.monorule, so the cell silently fell back to the UI font..nbwas lost together with its span. The login brand headline used to wraptoken planin<span class="nb">, and the prototype defines.nb { white-space: nowrap }(prototype line 132) so the phrase never breaks. The migration dropped both the span and the rule, and the ZH headline then broke inside the phrase.Related Issue
None — found internally by a prototype-vs-implementation class-parity audit, not by a filed issue.
Changes
.monorule (font-family: var(--mono)) so the sharing table's Key column renders monospace like it was always meant to. Alignment is deliberately left untouched: the prototype writesclass="num"on that same cell, which would additionally right-align it — this change only restores the monospace face..nb { white-space: nowrap }inui/css/style.css<span class="nb">token plan</span>wrapper for both languages.applyStatic()injects i18n values viainnerHTML, so the span lives in thelogin.brand.headlinevalues ofui/js/i18n.js(ZH + EN); markup inside i18n values is already established forlogin.footandops.users.sub. The static ZH default inui/index.htmlis kept byte-identical to the i18n value so no first-paint flash is introduced.?v=20260911-5→?v=20260911-6(5 refs)Tests
cargo test全部通过 — 148 passed / 0 failedcargo fmt --check通过cargo clippy --all-targets -- -D warningsclean;node --checkonapi.js/data.js/i18n.js/app.jsall OKEvidence (headless computed styles — not eyeballing)
A/B over two trees produced by the same harness generator (pre-fix tree exported with
git archive HEAD ui, post-fix tree = the working tree), identity-keyed measurements:.monoKey-cellfont-family(both langs)-apple-system, "system-ui", …(inert)ui-monospace, SFMono-Regular, Menlo, Consolas, …text-alignstartstart(unchanged, intentional).numcell (control)tabular-numstabular-nums(no regression)span.nbwhite-space: nowraptokenvsplanline tops @1024tokenvsplanline tops @1280/@1440/@1912classparity.pybucket [1] (referenced, no rule)classparity.pybucket [3] (missing global rules)Checklist
fix/ui-class-parity-mono-nb)