the symptom, in your words

"Too many font-size declarations (or too much text) corrupt UI glyph rendering"

✓ verified on 26.07.08e
lane Building UIposted updated

▸ > **⚠️ SUPERSEDED (OWNER-SETTLED, ENGINE 26.07.22).** THE "TOO MANY `FONT-SIZE` DECLARATIONS

corrupt rendering" theory below was root-caused entirely from camera_screenshot / editor_camera_screenshot evidence. The owner subsequently confirmed that panels with these exact font-size declarations render pin-sharp on the physical screen, so the glyph-block corruption is a capture-path artifact only, produced somewhere in the MCP camera_screenshot pipeline, not caused by font-size declaration count and not a live-render bug. Three independent sessions each generalized a different wrong "fix" from capture evidence (strip font-size / capture ≥2200 px wide / bisect font-size per selector) and none survived owner verification.

Operative rules that replace the recipe below:

  • Never strip or ration font-size (or letter-spacing) from a shipping stylesheet to "fix" captures: the live render is already correct; there is nothing to fix.
  • Do not use screenshot-based bisection to verify text/glyph rendering. Glyph corruption in a capture is not evidence of anything about the panel.
  • Verify geometry (layout, color, shape, shadow, animation-settled state) from a capture, never text fidelity. The owner's eyeball on the real game window is the only valid typography check. See An MCP camera_screenshot cannot verify font faces or text legibility.

The historical account is preserved below as the dated investigation record only.

▸ SYMPTOM

Text in a panel renders as solid filled rounded-rectangle blocks: box-shaped placeholders that match each string's measured width (layout is correct), but the actual glyph fill is wrong. The issue appears in editor screenshots and in-game.

It shows up in two shapes:

  • Whole-panel corruption: every styled text element in the panel is affected.
  • Positional corruption: a single text run (the last-rendered one) draws as blocks while identical sibling elements above it render clean.

▸ CAUSE

This is one glyph-rendering budget with two verified triggers:

1. Declaration count. Root-caused by exhaustive bisection on a ~290-line panel SCSS: having many selectors carry an explicit font-size declaration (a handful is fine; ~13 across one panel broke every styled element) corrupts the whole panel, made worse by simultaneously having letter-spacing anywhere in the same file.

Ruled out as causes: font-family, color, font-weight, text-transform, individual font-size values, :hover pseudo-rules, render timing (18 s wait, full editor process restart).

2. Cumulative text count. A panel with zero font-size/letter-spacing anywhere can still cross the threshold on text-run count alone: adding ~19 extra mono text runs made the single last-rendered collapsible-section summary render as solid blocks while three identical sibling section headers rendered clean. Content was irrelevant: a plain literal blocked too; removing that one span brought the whole panel back under threshold.

▸ FIX - (retracted, historical record)

Everything in this section was retracted by the owner-settled verdict in the banner above. Do not strip, ration, or bisect font-size declarations, and do not trim text runs: the live render was always correct. It is preserved as the dated investigation record.

The configuration this investigation believed was working: neither font-size nor letter-spacing declared anywhere, with visual hierarchy carried entirely by:

  • font-weight (bold/normal)
  • text-transform (uppercase)
  • color

If a panel truly needs per-element font sizing:

  1. Add font-size to one selector.
  2. Screenshot-verify it renders correctly.
  3. Add the next font-size declaration.
  4. Never batch many font-size declarations into one stylesheet at once.

On a text-dense panel, additionally treat text-run count as a budget:

  • Don't assume you're safe because you added no font-size: every added text run spends budget.
  • Trim the least-important text first (a collapsed-section summary is a good sacrifice: the values reappear on expand).
  • Verify on a play-mode screenshot, never a headless build: none of this shows up in compile output.

▸ WHY IT WORKS

The shared-budget explanation was inferred from capture evidence alone. The controlled A/B that finally settled it (engine 26.07.22, 2026-07-31, one live scene) changed a single variable, the root panel's scale: a ScreenPanel left on its default AutoScreenScale renders at a fractional scale, and at a fractional scale the capture path rasterizes glyph runs as solid grey blocks. Set AutoScreenScale = false and Scale = 1 on that same panel and every glyph is pin sharp, with all font sizes and px line-heights intact. Two panels in one frame proved it independently: a HUD on an auto-scaled ScreenPanel came out as blocks while a modal on a scale-1 ScreenPanel beside it came out crisp, and flipping the HUD's panel to scale 1 made it crisp too. That is why the artifact appeared to vary by element and by capture size; both were proxies for which panel's scale happened to be fractional. Never ship a panel pinned to scale 1 to work around this.

Verified on engine 26.07.08e: seen in a real project.
s&box moves fast; an undated fix is a liability. Spot a stale detail?
changelog
  • Marked the Fix section as retracted historical record (it still read as live guidance) and replaced the glyph-budget explanation with the root-panel-scale mechanism found 2026-07-31.
  • Owner-settled (26.07.22): the declaration-count causation is a capture-path artifact, not a live-render bug. Added a superseded banner and neutralized the strip-font-size recipe, which the newest source explicitly says never to do.
  • Verified against source: removed stale unverified flag; expanded with the cumulative-text-count variant (corruption is also text-run-count dependent and positional, not only font-size/letter-spacing).

Want to know when new guides or fixes drop? Join the community to help build this out. Report gotchas, flag outdated fixes, or just lurk.

Join the Discord