What This Is
Contrast Optima is a reading interface designed to simulate the visual characteristics of a cathode ray tube monitor while maintaining the ergonomic standards required for extended reading on modern displays. Every visual effect in this project—the scanlines, the phosphor glow, the barrel distortion, the chromatic aberration, the color grading—is a faithful simulation of a specific physical phenomenon that occurred in real CRT hardware. None of it is decorative. All of it is engineered.
This essay documents the complete intellectual history of the project, explains every major design decision, and provides a plain-language guide to modifying the code.
I. The CRT as a Physical System
A cathode ray tube works by firing electrons at a glass screen coated with phosphor compounds. Three electron guns (red, green, blue) sweep across the screen in horizontal lines, exciting phosphors that emit light. The guns are not perfectly aligned. Their beams pass through a shadow mask—a metal plate with tiny holes—to hit the correct color phosphor, but manufacturing tolerances mean the three beams never converge exactly. This is chromatic aberration: the red, green, and blue images are slightly offset from each other.
The beam sweeps left to right, line by line, top to bottom. Each horizontal pass is a scanline. Between scanlines, the beam is off, creating a thin dark stripe. On a real monitor these dark stripes were subpixel-thin and invisible at normal viewing distance, but at close range or on lower-resolution tubes they became visible—the characteristic CRT scanline look.
The glass faceplate of a CRT is curved. Not perfectly flat like an LCD. This curvature causes barrel distortion: straight lines near the edges of the screen bow outward. Engineers compensated for this electronically, but perfect correction was expensive, so consumer monitors always had some residual barrel effect.
Phosphors do not switch off instantly. When the electron beam excites a phosphor dot, it glows brightly, then decays over milliseconds. This persistence creates a soft halo around bright elements—the phosphor glow. The glow bleeds through the dark scanline gaps because light scatters through the glass faceplate omnidirectionally. This is why text on a CRT appears to have a subtle luminous aura that text on an LCD does not.
II. Simulating CRT Physics in CSS and SVG
Scanlines are implemented as a repeating-linear-gradient on an absolutely-positioned overlay element (.crt-scanlines). The gradient alternates 1px of opaque black with 1px of transparency, producing a 2px-period pattern. The scanline element sits at z-index 999 inside .crt-wrapper but outside the <header class="site-header"> element. This is critical: the header carries the barrel distortion SVG filter, and if scanlines were inside it, the barrel filter would warp the horizontal lines into curves. Keeping scanlines outside the filter means they stay perfectly horizontal while the text underneath them bends.
Barrel distortion uses an SVG feDisplacementMap filter. A 200×82 pixel displacement map encodes the curvature: the red channel stores X displacement and the green channel stores Y displacement, with 128 as the neutral (no displacement) value. Pixels near the edges have values that pull content toward center, simulating the glass curvature. The map is stretched across the full header with preserveAspectRatio="none" so it matches the 2000/821 aspect ratio regardless of element size.
Chromatic aberration is achieved by rendering the title text three times—once for each RGB channel—as separate <span class="crt-ch r/g/b"> elements. Each channel is colored pure red, green, or blue and composited with mix-blend-mode: screen (additive blending). When the channels are perfectly aligned, the three colors add to white. When JavaScript offsets them via CSS custom properties (--tr-jx, --tg-jy, etc.), the misalignment produces colored fringing exactly like real convergence errors.
Phosphor glow is a duplicate set of text layers with CSS blur and reduced opacity, composited above the scanlines. This is the key architectural decision: because the glow physically represents light scattering through the glass faceplate, it must be visible on top of the dark scanline stripes, not trapped beneath them. The glow layers sit inside .crt-group elements alongside the main text layers, and their blur radius and opacity are controlled by sliders.
III. The Stacking Context Problem
CSS stacking contexts are the single most recurring technical hazard in this project. When an element has certain properties—filter, transform, opacity less than 1, or mix-blend-mode—it creates a new stacking context. Children of that element can never paint above siblings of that element, regardless of z-index. The barrel distortion filter on .site-header creates such a context, which means everything inside the header (text, glow, backing layers) gets composited into a single flat bitmap before being placed into the parent stacking order. If the scanlines were inside the header, they would be part of that bitmap and would get barrel-distorted. If the glow were only inside the header, it would be trapped below the scanlines.
The solution is architectural: elements that must composite above scanlines (glow) live inside the text groups, which are inside the header but rendered with z-indices that place them above the main text. The scanlines sit outside the header entirely, as a direct child of .crt-wrapper. The vignette and RGB stripe border sit on .crt-wrapper::after at z-index 1000, above everything.
IV. Color Science and Reading Ergonomics
The text and background colors were not chosen aesthetically. They were computed from first principles of human vision physiology.
Contrast ratio. The text color is rgb(206, 206, 206) against a content background of rgb(12, 12, 12). Converting to relative luminance: text luminance = (206/255)2.2 ≈ 0.625; background luminance = (12/255)2.2 ≈ 0.00147. The WCAG 2.0 contrast ratio formula gives (0.625 + 0.05) / (0.00147 + 0.05) = 13.12:1. WCAG AAA requires 7:1 for normal text. This exceeds it by nearly double. The colors are neutral gray rather than tinted because chromatic text causes faster eye fatigue during extended reading.
Pupil stabilization. On a dark screen, pupils dilate. On a bright screen, they constrict. Rapid changes in ambient brightness cause the pupil to oscillate, which produces fatigue and headaches. The content background at rgb(12, 12, 12) was chosen to sit at the minimum threshold where pupil constriction begins to engage (~0.29 cd/m² on a typical display), preventing full dilation while keeping the display dark enough for the CRT aesthetic.
Iso-melanopic color design. Pupil response is not driven by rod and cone cells. It is driven by melanopsin-containing intrinsically photosensitive retinal ganglion cells (ipRGCs). Melanopsin has peak sensitivity at 480nm (blue), with dramatically lower response to red and green wavelengths. Quantitatively, blue light is approximately 275 times more effective at triggering pupil constriction than red light. This means that two colors which appear equally bright to your conscious visual system (rods and cones) can have wildly different effects on your pupils.
The project includes a triangular melanopic color picker that maps all RGB combinations producing equal melanopic stimulation. Every point on the triangle causes the same pupil constriction, so you can change the green overlay color or the index text color without disrupting the reader’s adapted pupil state. This is critical for reading comfort: if you switched from a green-tinted display to a blue-tinted one at the same perceived brightness, the melanopic response would spike and the reader’s pupils would constrict sharply, causing momentary discomfort.
V. Typography and Scanline Survival
Fonts were selected through empirical testing under scanline overlays. The scanlines in this project are 1px black lines repeating every 2px. A font that renders critical features (the dot on an i, the crossbar of a t, the counter of an e) at exactly the height of a scanline stripe will have those features obliterated. This is not a hypothetical concern—it was observed during testing with several fonts.
The fonts that survived testing: Share Tech for titles and the index header (clean geometric sans-serif, thick enough strokes that no critical feature falls entirely within a 1px scanline); Audiowide for subtitles (wider letterforms, decorative but legible at display sizes); IBM Plex Mono for body text and index entry titles (monospace, excellent x-height, strokes designed for screen rendering); and Digits for numerals only (applied via unicode-range: U+0030-0039 so it only activates for the characters 0–9). Verdana serves as the body text font—it was specifically designed by Matthew Carter for screen legibility at small sizes, with large x-height and open counters that resist scanline occlusion.
The essay content displays without CRT scanlines. This was a deliberate decision: extended reading (thousands of words) through a scanline overlay causes eye strain regardless of font choice. The scanlines are an aesthetic element for the index and header, not a reading aid.
VI. Animation Timing: Prime Numbers Against Synchronization
Every animation in this project uses prime-number-based timing to prevent visual synchronization artifacts. When multiple periodic animations have periods that share common factors, they periodically align—all channels snapping to the same position simultaneously, all effects peaking at the same moment. This creates a visible “pulse” or “heartbeat” that breaks the illusion of random analog degradation.
The background blur cycle sums five sine waves at periods of 2, 3, 5, 7, and 11 seconds (the first five primes). Their least common multiple is 2×3×5×7×11 = 2,310 seconds—over 38 minutes before the pattern repeats. The hue rotation cycle defaults to 59 seconds (prime). The chromatic aberration drift animation uses a state machine with randomized hold times rather than periodic functions, further preventing synchronization.
The title glitch uses a “drift” state machine: IDLE → DRIFT_A → HOLD_A → DRIFT_B → HOLD_AB → RETURN. One color channel drifts to a target offset with smoothstep interpolation, holds, then a second channel drifts in a random direction to the same distance. Both return together. The subtitle uses a “snap glitch” with burst/calm phases—rapid discrete position changes during bursts, stillness during calm. Subtitle Y-displacement is constrained to downward-only to prevent interference with the title above it.
VII. The Rendering Stack (Top to Bottom)
Understanding the z-order is essential for modifying the visual effects:
z:1000 — .crt-wrapper::after — The bezel. RGB stripe border + vignette (inset box-shadows). Above everything. Never barrel-distorted.
z:999 — .crt-scanlines — The scanline overlay. Direct child of .crt-wrapper, outside the header. Never barrel-distorted. 1px/1px repeating gradient.
z:8 — .tear-slab — Horizontal tearing effect. Cloned content strips displaced horizontally to simulate H-sync errors.
z:7 — .scan-deform-layer — Rolling scan bar deformation. A cloned copy of the header content, masked to a horizontal band, displaced horizontally with summed sine waves.
z:6 — .scan-bar — The bright scan bar itself. A gradient band that scrolls vertically, simulating the CRT’s electron beam refresh.
z:5 — .crt-layer.glow — Phosphor glow. Blurred duplicate of text, additive blended.
z:2 — .site-header — Contains all text layers. Has filter: url(#crt-barrel) for barrel distortion.
z:1 — .green-overlay — Green color grading via mix-blend-mode: multiply. Tints the background image green (or amber).
z:0 — .placeholder-bg — The background image. Animated with a blur cycle (sharp ↔ blurred) and subtle jitter.
VIII. The Skeleton Build System
The source file is a skeleton HTML file (~186KB) with six placeholder tokens: {{FONT_SHARE_TECH}}, {{FONT_AUDIOWIDE}}, {{FONT_IBM_PLEX_MONO}}, {{FONT_DIGITS}}, {{BG_IMAGE_BASE64}}, and {{DMAP_BASE64}}. Each token is replaced with the contents of a corresponding .b64 file during assembly. The assembled file is ~384KB. This architecture exists because the base64 data is binary noise that an AI cannot meaningfully process—separating it saves approximately 29,000 tokens per interaction. The skeleton contains all the logic, CSS, and HTML structure. The .b64 files contain raw base64 strings with no headers or wrappers.
To assemble manually: open the skeleton in a text editor, find-and-replace each {{TOKEN}} with the full contents of the matching .b64 file. Or use the command: sed -i "s|{{FONT_SHARE_TECH}}|$(cat font_share_tech.b64)|g" skeleton.html for each token. The assembled file is a fully self-contained single HTML file with no external dependencies.
IX. How to Add Your Own Content
The content lives in the <nav class="index"> section. Each entry is an <a> tag containing three <span> elements:
<span class="title"> — The clickable title shown in the index. Replace the text between the tags. Keep it to one line.
<span class="desc"> — The summary that types out word-by-word on hover/click. One to three sentences. Plain text only (no HTML tags inside this span).
<span class="essay" style="display:none"> — The full article. Hidden until the reader clicks through. Use these tags inside it:
• <p>Your paragraph.</p> — Every block of text needs paragraph tags or it will have no spacing.
• <span class="essay-heading">Section Title</span> — A section heading. Renders larger and bolder.
• <span class="essay-quote">A quote.</span> — A styled blockquote.
• <b>bold</b>, <i>italic</i>, <br> — Standard formatting.
To add an entry: copy any <a>...</a> block (including its preceding separator <span class="index-sep">) and paste it before the final separator. To remove one: delete from its separator through its closing </a>.
X. The Slider Tuning System
The margin sliders (visible on wide screens, hidden below 1200px) control every visual parameter in real time. They are organized into sections: BLUR CYCLE (background blur intensity and thresholds), HUE (hue rotation speed), GLOW (phosphor glow blur and opacity), SCANLINES (opacity, width, gap), VIGNETTE (inner and outer shadow parameters), GREEN (overlay color tinting), BARREL (distortion intensity, corner radius, border colors), and several more for the scan bar, tearing, glitch animations, and essay readability.
Each slider modifies a property in the global window.V object and calls an update function that applies the change to the DOM. To change a default value permanently, find the window.V = { ... } block in the JavaScript section and modify the number. The slider will initialize to your new value on next page load.
The sliders display as narrow cells on the left and right edges of the viewport. Click the number to type a value directly. Click the tiny arrows to increment/decrement. Cells turn red (with a hue-cycling animation) once you have modified them from their default.
XI. Changing the Header Text
The title and subtitle are rendered six times each (three RGB channels × two layers: main + glow, plus a backing layer). All copies must contain identical text. Find the <div class="crt-group crt-title-group"> section and change every instance of the title string. Do the same for crt-subtitle-group. There are 9 copies of the title and 9 copies of the subtitle (3 in backing + 3 in main + 3 in glow). If any copy differs, the chromatic aberration will show misaligned text instead of clean color fringing.
The title font is Share Tech (set in the fitText() function). The subtitle font is Audiowide. The fitText() function automatically sizes both to fill the available width, so you do not need to set font sizes manually.
XII. Changing the Background Image
The background image is a base64-encoded JPEG in the .placeholder-bg element’s inline style. In the skeleton, it is the {{BG_IMAGE_BASE64}} token. To change it: convert your image to base64 (base64 -w0 yourimage.jpg > bg_image.b64 on Linux, or use an online converter), save the result as bg_image.b64, and reassemble the skeleton. The image should be at least 2000px wide for sharp rendering. It will be displayed with background-size: cover so aspect ratio does not matter.
XIII. Version History
The project has gone through over 190 versioned iterations. Major milestones:
v1–v50: Initial development. Title with RGB chromatic aberration using pseudo-elements and data-text attributes. Scanline experiments (6+ techniques tested including backdrop-filter blur, multi-layer premium, and simple repeating gradients). Font comparison testing with 21 typefaces under scanline overlays. Index navigation system with typewriter-effect summaries.
v51–v55: Token efficiency refactoring. Extraction of base64 assets into separate files. Creation of the skeleton build system. Melanopic color picker development. Corner radius controls. Transparent body backgrounds for ambient lighting.
v55–v128: Index interaction system. Expandable essays with typewriter descriptions. “Finished reading” button. Phosphor glow on index text (clone layer above scanlines). Essay collapse animations with height-scaled duration and lerped scroll correction. Multiple iterations on z-index stacking and scanline exemption for essay content.
v128–v186: Barrel distortion implementation via SVG displacement map. Glow layer relocation to composite above scanlines. Background blur cycle restoration. Prime-number sine summation for blur timing. Vignette banding diagnosis (8-bit quantization in large-radius box-shadows). RGB stripe border system.
v186–v188: Complete glitch system redesign. Title drift animation (state machine with smoothstep interpolation). Subtitle snap glitch (burst/calm phases). Vertical scan bar addition. Horizontal tearing with DOM-based geometric displacement (cloned content strips). Rolling scan bar with masked deformation layer. Scan bar hue rotation applied per-group instead of per-element. Title and subtitle scale sliders. Margin rack repositioned to window edges.
v188–v193: Removal of crtFocusIn blur-in animation (interfered with tearing system). Hover flash changed from color+background to text-shadow-only blue glow. Header border added (RGB stripe matching index). Glitch parameter tuning. 33-slot index template with documentation annotations. This essay.