Typographic callout library. 15 components, CSS custom properties, zero dependencies.
Vision begins at the retina, where 130 million photoreceptors compress into 1.2 million ganglion cell axons — a 100:1 reduction before information reaches the brain. This isn't a bottleneck. It's an editorial decision, made in parallel across the visual field, about what matters enough to transmit.
Note: Ganglion cell density peaks at ~35,000 cells/mm² in the fovea and drops to ~5,000 cells/mm² at 10° eccentricity. The mg-dropcap above mirrors this hierarchy — the initial letter demands foveal attention.
Center-surround receptive fields perform edge detection and contrast normalization before any cortical processing occurs. Midget cells in the fovea carry high-acuity color-opponent signals. Parasol cells across the periphery prioritize motion and luminance transients. Two parallel channels, tuned to different statistics, feeding V1 LGN SC simultaneously.
// Retinal ganglion cell density falloff (Watson 2014)
float ganglionDensity(float eccentricity) {
float fovealPeak = 35000.0; // cells/mm²
float e2 = 1.72; // half-density eccentricity
return fovealPeak / pow(1.0 + eccentricity / e2, 2.0);
}
Foveated rendering exploits this density falloff. If you match your
shader's spatial frequency budget to the retina's sampling capacity at
each eccentricity, you can reduce fragment processing by 60-70% with
no perceptible quality loss. The ganglionDensity()
function above is the biological ground truth that rendering LOD curves
approximate.
Note: The cortical magnification function falls off roughly as 1 / (1 + e/e2) where e2 varies by visual field meridian.
Tip: Use shape-outside with pull quotes to create text that wraps along the perspective tilt, not just a rectangular float.
Warning: MIP level selection at extreme eccentricities can produce visible banding. Clamp to maxLod - 1 for smoother falloff.
Important: The 3D perspective transform uses transform: perspective(600px) rotateY(14deg). This is removed on viewports below 720px for readability.
Note: Add data-bar="none" to any callout, pull quote, or code block to remove the left border accent. The tinted background still provides visual separation.
Warning: Without the border, the background tint carries the semantic color. Works best with typed variants that have distinct tints.
Hardware texture MIP chains and biological retinal processing share a structural parallel that runs deeper than analogy. Both systems face the same computational problem: reducing high-resolution spatial information into progressively coarser representations while preserving the features that matter for downstream processing.
The GPU MIP chain builds power-of-two reductions through box filtering. The retina builds a spatial frequency cascade through center-surround receptive fields whose sizes increase with eccentricity from the fovea. Different mechanisms, same computational strategy, same mathematical structure — a Laplacian pyramid.
This convergence isn't mysterious. Progressive spatial pooling is simply an efficient solution to the problem of representing visual information at multiple scales. Evolution and engineering arrived at the same answer independently, which is exactly what you'd expect for a well-constrained optimization problem.
The mg-flat modifier removes the perspective
tilt while keeping the sidebar float behavior. This works for content where the
3D effect would feel excessive — technical asides, definition boxes, or
supplementary notes that sit alongside body text without demanding attention
through visual skew.
Flat pull quotes still float right by default and can be combined with
mg-flip to float left. The left border
accent remains as the visual anchor.
The oculomotor system makes roughly three saccadic eye movements per second during active viewing. Each saccade commits the visual system to a new fixation point for 200-300 milliseconds. The choice of where to look next is informed by peripheral vision — specifically, the low-spatial-frequency information available in the parafoveal and peripheral visual field during the current fixation.
Saliency models attempt to predict these fixation sequences from image statistics. The best-performing models combine bottom-up feature contrast (color, orientation, spatial frequency) with top-down task demands and scene grammar — the learned statistical regularities of where objects tend to appear in natural scenes.
// Lorenz attractor step — the heart of Psychodeli+'s fractal engine
vec3 lorenzStep(vec3 p, float sigma, float rho, float beta, float dt) {
return p + vec3(
sigma * (p.y - p.x),
p.x * (rho - p.z) - p.y,
p.x * p.y - beta * p.z
) * dt;
}
// Cortical magnification — FOVI model (Blauch, Alvarez & Konkle 2026)
function corticalMagnification(eccentricity, e2 = 0.75) {
return 1 / (1 + eccentricity / e2);
}
Inline code: The shape-outside property creates
a polygon that text wraps around, matching the visual tilt of the
perspective() transform.
Badges work inline: this feature is New and requires WebGL 2 GPU support.
The cortical magnification factor M describes how many millimeters of cortical surface represent one degree of visual angle at eccentricity e:
M(e) = M0 / (1 + e/e2)
Where M0 is the foveal magnification (~15-20 mm/deg for V1) and e2 is the eccentricity at which M drops to half its foveal value (~0.75 deg for V1, varying by meridian). This hyperbolic falloff means roughly half of V1 is devoted to the central 2-3 degrees of the visual field.
The shape-outside: polygon(0% 0%, 100% 0%, 100% 100%, 14% 100%)
creates a trapezoid that approximates the visual footprint of the perspective-tilted
pull quote. The 14% bottom-left inset roughly matches the apparent narrowing from
rotateY(14deg) at the default perspective distance.
For the flipped variant, the polygon mirrors:
polygon(14% 0%, 100% 0%, 100% 100%, 0% 100%).
The foveal region covers roughly 2 degrees of visual angle — about the width of your thumbnail at arm's length. Everything beyond that peripheral field is processed at progressively lower spatial resolution, following the cortical magnification function described above.
Peripheral vision is not blurry vision. The retina's ganglion cell density drops with eccentricity, but peripheral processing excels at detecting motion, flicker, and large-scale spatial structure. The visual system trades resolution for temporal sensitivity as you move away from the fovea — a design tradeoff, not a deficiency.
Every typeface carries its own history. The drop cap, or lettrine, dates to hand-illuminated manuscripts where monks painted the opening letter in gold leaf and lapis lazuli. Modern typography inherited the convention stripped of its gilding but not its function: signal the start, reward the eye, set the pace for what follows.
The ganglion cell layer is where the retina's editorial decisions become irreversible. Signals that survive center-surround filtering are bundled into 1.2 million axons — the optic nerve — and there is no going back to the raw photoreceptor mosaic after this point.
Cortical magnification describes how many millimeters of cortical surface represent one degree of visual angle. The function falls off hyperbolically from the fovea, with roughly half of V1 devoted to the central 2–3 degrees.
Rubrication dates to medieval manuscripts where scribes wrote opening words in red ink — Latin ruber. The convention survived into modern editorial design as the colored lead-in, signaling the start of a new section without the weight of a full subheading.
The fovea covers roughly 2 degrees of visual angleAbout the width of your thumbnail at arm's length, or roughly 1.5mm on the retina. Ganglion cell density peaks here at ~35,000 cells/mm². but accounts for over half of the neural real estate in primary visual cortexThis disproportionate allocation is described by the cortical magnification function: M(e) = M₀ / (1 + e/e₂), where M₀ ≈ 15–20 mm/deg for V1.. This overrepresentation is not waste — it's the biological cost of high-acuity central visionPeripheral vision compensates with superior temporal resolution and motion sensitivity, making it the dominant early-warning system for saccade targeting..
Footnote markers auto-number via CSS counters. Content lives inline with its reference — no bottom-of-page lists to maintain. Hover or tab to a marker to reveal the note. Works without JavaScript; JS enhances popover positioning near viewport edges.
You can also provide explicit marker text: some
claim*This
uses a manual marker instead of auto-numbering. Just put text inside the
mg-fn-ref element.
rather than a number.
Click any image to expand in a lightbox overlay. Arrow keys navigate between images, ESC or click outside to close. Side-by-side comparison grids stack on mobile.
Note: The V1 cortex tiles the visual field with orientation columns spaced at roughly 0.5mm intervals. Each hypercolumn contains a complete set of orientation preferences — a local Fourier basis for spatial frequency analysis.
Tip: Pair skewed callouts with pull quotes for a consistent 3D language across the page. The subtle 4° tilt here complements the stronger 14° on pull quotes.
Sidebars float alongside body text, providing tangential context without interrupting the reading flow. They use body-copy sizing — small enough to be subordinate, large enough to be legible. The subtle background and border distinguish them from the main column without the visual weight of a full callout.
Use sidebars for implementation notes, historical context, or definitions that support the main argument but aren't essential to it. They work best when the reader can skip them on a first pass and return on a closer read.
The mg-wide modifier increases sidebar width to
220px for longer content that needs breathing room. Both variants collapse to
full-width blocks on mobile viewports.
Sidebars are the marginalia equivalent of a penciled annotation — they belong to the document but live at a lower priority level than the prose they accompany.
On screens wider than 1200px, margin notes escape the content column and float in the gutter with large peripheral-readable text. On narrower screens they degrade to inline callouts. Resize your browser to see both modes.
The content column needs a parent with mg-margin-scope
to allow the note to escape via absolute positioning. On desktop, the note appears
in the left gutter at 2.8rem / 800-weight with a 14° perspective tilt pointing
inward toward the body text.
The 5px border sits on the inside edge — right border for left-gutter notes, left border for right-gutter notes — creating a visual bridge between the annotation and the text it refers to.
Add mg-right to position the note in the right
gutter instead. The border flips to the left (inside) edge and the perspective tilt
mirrors to point inward. On narrow screens both variants collapse identically to
inline callouts.
Left and right gutter notes can alternate down a long article, creating the kind of margin annotation rhythm you see in academic textbooks or magazine feature spreads.
Combining mg-flat and
mg-flip gives a left-floated sidebar without the
3D perspective tilt. This is the quietest pull quote variant — no skew drawing the
eye, just a bordered float sitting in the left margin.
The four pull quote configurations form a 2×2 matrix: skewed/flat × right/left. Each serves a different editorial role, from the dramatic tilted hero quote to the understated left-margin gloss.
Repeat mode (data-content="repeat")
signals that the callout duplicates text from the surrounding body — the traditional
pull quote. It renders in italics at slightly reduced opacity, telling the reader
"you've seen this already; this is emphasis, not new information."
Progressive spatial pooling solves the same problem whether evolution or engineering builds it. Hardware MIP chains and retinal eccentricity gradients converge on the same Laplacian pyramid structure because the optimization landscape has one global minimum.
Insert mode (data-content="insert")
signals new standalone content — a tangential observation, an aside, a definition.
Normal weight, full opacity. The reader knows this is additive information worth
reading even if they've read every word of the body text.
The content mode attribute works on any callout variant: pull quotes, margin notes, sidebars, and inline callouts. It's a semantic flag, not a layout modifier.
Aside: The magnocellular pathway carries achromatic, high-temporal-frequency signals from parasol ganglion cells. It's faster than the parvocellular pathway by ~20ms — enough to prime spatial attention before fine detail arrives.
Content mode on a sidebar signals whether the tangential note paraphrases nearby body text or introduces a new definition. Insert mode keeps normal weight; repeat mode would italicize the sidebar body.
Two-column body text with callouts that bridge both columns. The classic
editorial spread — inspired by CSS Regions (Adobe's abandoned spec) but
built on column-count +
column-span: all, which actually ships
in every browser.
The retina performs more computation than any other structure in the central nervous system relative to its size. Six layers of neurons — photoreceptors, horizontal cells, bipolar cells, amacrine cells, ganglion cells, and their associated interneurons — implement a signal processing pipeline that would require roughly 10 billion operations per second to simulate digitally.
Center-surround receptive fields emerge at the ganglion cell layer through lateral inhibition mediated by horizontal and amacrine cells. This architecture performs simultaneous contrast normalization across the entire visual field, adapting the neural code to local luminance statistics on a millisecond timescale. The result is a representation that encodes edges, gradients, and transients rather than absolute intensity — exactly the features that matter for object recognition downstream.
Midget ganglion cells in the central retina maintain a one-to-one connection with individual cone photoreceptors, preserving the full spatial resolution of the cone mosaic. This private-line architecture is unique to primates and explains why human visual acuity exceeds that of all other mammals despite having a similar optical system. The tradeoff: midget cells consume roughly 80% of ganglion cell bandwidth for the central 5 degrees alone.
Note: The midget pathway's 80% bandwidth allocation for 5° of visual field is the biological precedent for foveated rendering's aggressive LOD falloff. If the retina can justify that resource distribution, so can your shader.
Parasol cells cover the remaining visual field with larger receptive fields optimized for temporal contrast and motion detection. Their faster conduction velocity and transient response profiles feed the magnocellular pathway, which drives saccade targeting and the perception of optic flow. This is the system that makes you flinch before you consciously see the baseball.
The division of labor between midget and parasol pathways is not a compromise — it's a Pareto-optimal allocation of neural bandwidth given the statistics of natural scenes. High spatial frequency information is concentrated at fixation. Motion energy dominates the periphery. The retina matches its channel capacity to the signal structure at each eccentricity.
<!-- Include in your page -->
<link rel="stylesheet" href="marginalia.css">
<script src="marginalia.js" defer></script>
<!-- Callout -->
<div class="mg-callout" data-type="note">
<p><strong>Note:</strong> Your content here.</p>
</div>
<!-- Pull quote -->
<aside class="mg-pull">Your quote text.</aside>
<aside class="mg-pull mg-flat">Flat sidebar (no 3D tilt).</aside>
<!-- Code block -->
<pre class="mg-code" data-lang="js">const x = 42;</pre>
<!-- Badge -->
<span class="mg-badge">Label</span>
<!-- Collapse -->
<details class="mg-collapse">
<summary>Title</summary>
<div class="mg-collapse-body">Content</div>
</details>
<!-- Highlight -->
<mark class="mg-mark">highlighted text</mark>
<!-- Drop cap -->
<p class="mg-dropcap">Your opening paragraph.</p>
<p class="mg-dropcap" data-type="ornate">Ornate variant with border accent.</p>
<!-- Lead-in (rubrication) -->
<p><span class="mg-lede">Opening words</span> rest of text.</p>
<p><span class="mg-lede" data-type="caps">Small caps</span> variant.</p>
<!-- Footnote (auto-numbered) -->
Text<span class="mg-fn">
<a class="mg-fn-ref" tabindex="0"></a>
<span class="mg-fn-body">Footnote content shown on hover/focus.</span>
</span> continues.
<!-- Inline skew callout -->
<div class="mg-callout mg-skew" data-type="note">Tilted block callout.</div>
<!-- Sidebar — float-right body-copy tangential note -->
<aside class="mg-sidebar">
<strong>Title</strong>
<p>Tangential context at body-copy size.</p>
</aside>
<aside class="mg-sidebar mg-wide">Wider variant.</aside>
<!-- Margin note — escapes into the gutter on wide screens -->
<div class="mg-margin-scope">
<div class="mg-margin">
Big gutter text
<small>Explanatory subtext.</small>
</div>
<p>Body text continues normally.</p>
</div>
<!-- Content mode: repeat (duplicated body text) vs insert (new content) -->
<aside class="mg-pull" data-content="repeat">Emphasized body text.</aside>
<aside class="mg-pull" data-content="insert">New standalone aside.</aside>
<!-- Two-column magazine spread -->
<div class="mg-spread">
<p>Body text flows into two columns.</p>
<aside class="mg-pull">Bridges both columns.</aside>
<p>Text resumes in two columns.</p>
</div>
<!-- Remove vertical bar from any component -->
<div class="mg-callout" data-type="note" data-bar="none">No left border.</div>