Components/Design Concepts Manual/Retinal Irradiation & Weight Tuning

Retinal Irradiation & Weight Tuning

Helmholtz optical irradiation illusion, the perceived expansion of white text on dark, variable font 460/560 tuning, and discrete font fallback traps.

Design Concept

Retinal Irradiation & Weight Tuning

Identical font-weight: 500 copy appears noticeably heavier in dark mode than in light mode, eroding typographic refinement.

Optical Irradiation (The Helmholtz Illusion)

In 1867, physiological optics pioneer Hermann von Helmholtz documented this retinal mechanism in the Handbuch der physiologischen Optik: Photoreceptors stimulated by bright light spill excitation into neighboring dark-adapted cells, causing the visual cortex to perceive bright shapes expanding outward.

The Perceived Expansion of White Text

  • Light Mode (Dark on Light): Expansive light backgrounds encroach upon the boundaries of dark strokes, making typography feel compact and refined.
  • Dark Mode (Light on Dark): Radiant white strokes bleed into the surrounding darkness. The same weight reads bolder than it does dark-on-light; how much depends on luminance, contrast and size, and there is no fixed percentage.

Reusing identical numeric weights across themes causes dark mode typography to read clumsy and congested.

Variable Font 460/560 Tuning in Action

TuffEx does not lower weights in its dark theme today: components use the same 400/500/600 on both. The table below is a recommendation. When the font has a weight axis (variable fonts such as San Francisco, Segoe UI Variable or Inter), a dark theme can tune its weights like this:

RoleLight WeightRecommended Dark WeightOptical Target
Body Default400 (Regular)380 – 400Eliminates bloom and stroke fattening
Inline Emphasis500 (Medium)460Crisp emphasis without interior stroke collision
Headings / Buttons600 (Semi-Bold)560Preserves letter counters and structural posture

Discrete Static Font Fallback Guards

A critical engineering pitfall: If a platform lacks variable font axes and falls back to static fonts:

  • A CSS declaration of font-weight: 460 triggers the browser's fallback algorithm.
  • Values between 400 and 500 round up to 500!
  • Rather than compensating for optical bloom, this unintentionally thickens the text!

So declare these in-between weights only where the font is known to have a weight axis; with static fonts, keep 400/500/600 and dial back text contrast instead (--tx-text-color-regular rather than raw white) to offset the expansion. Measure CJK fonts too: with the Chinese system font on macOS, 390 draws exactly like 400, so the body-text step has no effect there; Latin system-ui has a weight axis and draws the in-between values.

Loading demo...