# Refracting glass letterforms — a backdrop that displaces itself

Learned 2026-08-21 extending the entry above, on the same hero
(`references/milkinside/`, `page.html` and `sections/hero.html`, Chrome
151.0.7922.140 headless at 1920×1048). Rendered and seen: the fold and a
620×364 detail crop, both diffed blind under shuffled neutral names before
the numbers below were written down. The entry above stays true — that is
the reference's flat frosted pane; this is what turns one into a material.

- **`backdrop-filter: url(#…)` renders.** It is a measurable fact, not a
  thing to assume in either direction, and four probes settle it in
  increasing order of proof: computed style keeps `url("#f")` where
  `invalid(3px)` falls to `none`; an `feFlood` filter paints the backdrop
  exactly `(255,0,0)`; `feTurbulence` → `feDisplacementMap` visibly
  displaces a striped backdrop; and `feImage` from a `data:` URI
  reproduces its map 1:1 over the element box. Run the `feFlood` one
  first — it is unmistakable and takes a minute.
- **The backdrop the filter receives is clipped to the element's own
  border box.** `feOffset dx="7"` over 20px stripes left the seven
  left-hand pixels showing the page ground, not the content 7px further
  left. So an outward-sampling displacement **must** have the pane
  extended beyond the shape, or every edge that touches the box gets a
  dark fringe.
- **`clip-path` on an ancestor creates a backdrop root, and it kills the
  obvious fix.** A child with `backdrop-filter: blur(6px)` under a
  `clip-path` parent frosted *nothing* — measured as raw stripes against
  a uniform mid value on the unclipped control. "Clip the parent,
  oversize the child" does not work. Pad and clip must sit on the same
  element, which means renormalizing the clip path into the padded box:
  `x → (x·w + p) / (w + 2p)`. Pad 12 outline units against a 25px letter
  gap keeps neighbouring panes from overlapping.
- **Units, the combination that works.** `filterUnits` default
  (`objectBoundingBox`) with the region written `x="0%" y="0%"
  width="100%" height="100%"` makes the filter region exactly the
  element's box; an `feImage` with no subregion then fills it 1:1 (a 64px
  ramp on a 200px element read 0, 63, 128, 193, 255). Leave
  `primitiveUnits` at `userSpaceOnUse` so `feDisplacementMap`'s `scale`
  is in CSS px — `scale="20"` moved the stripes the predicted ±10.
- **One PNG per glyph is the whole recipe.** R and G carry the outward
  unit normal of the outline, B a signed lighting term, everything
  weighted by |∇(blurred glyph alpha)| at σ ≈ 12 outline units, on a
  neutral 128 ground so the interior displaces by nothing. Six maps,
  85.6 KB at 0.55 map px per outline unit — the field is smooth, so it
  upsamples without artefact. One `feDisplacementMap` refracts; three
  `feColorMatrix` rows lift a broad rim, a brighter core on the outline
  and an inner shadow, all out of that same B channel, at a cost far
  below one more displacement pass.
- **Blur first, then the filter.** `blur(20.0064px) url(#gr-n)` leaves
  the pane's interior bit-identical to the reference's own measurement
  and lets the filter act only where the map is not neutral. Reversing
  the order changes the frosting's whole character.
- **Magnitudes that read as material, measured.** Max shift **8.25 px =
  2.272% of cap height**, written as a fraction of the rendered char
  height by script because an SVG attribute takes no `calc()`; over a
  photographic ground it moves 11.9% of the letter band, max 17 levels.
  Lit rim **+12 luminance levels** at the outline decaying to 0 over
  26–28 px; inner shadow **−4 levels** over ~19 px. Light distant at
  129°. A magnitude sweep is worth the ten minutes: 5.5 px is barely
  visible, 8.25 reads as a bevel, 16.5 as a bright rim, 33 as a wash.
- **A distant light is why the rim may be baked into the letter.** The
  row travels horizontally; a distant source keeps the lit side the same
  side, so a letter-fixed rim is correct and does not read as pasted. A
  point-light hotspot would have to travel with the letter, which is why
  none is used. This is the answer to "should the light follow
  anything" — it depends entirely on which kind of light you claim.
- **Chromatic dispersion is unreachable behind a 20px frosting, and the
  arithmetic says so before the render does.** Three displacement passes
  putting red and blue 0.50 px apart moved a channel by at most
  **4 / 255** anywhere in the band; at 3.00 px apart it reached 8. A
  tinted warm/cool rim split moved R−B by 1–3 levels against the
  backdrop's own 46 → 34 gradient. The cause: a 20px blur flattens the
  backdrop's gradient to ~6 levels/px, so a sub-pixel channel separation
  lands under the 8-bit floor, and an overlay faint enough to stay
  restrained can only move the composite by `alpha × (tint − backdrop)`.
  **Compute `blur σ` against the intended separation before building
  it.** Dispersion needs a sharp backdrop; frosting and dispersion are
  mutually exclusive in one pane.
- **The dispersion was also the entire frame cost.** Median frame time
  8.30 ms before and after, p95 unmoved; but the three-pass build put
  **4.31%** of frames over 16.7 ms against 0–0.18% at baseline, and
  dropping it returned the tail to 0.30–1.84%. Measure over a real wheel
  scroll with the video playing, five runs, three independent
  measurements per side — a single run's p99 swings by 8 ms.
- **A capture path can go blank where the page is fine.** Scrolled into a
  sticky pin with url() filters live, `Page.captureScreenshot` with
  `captureBeyondViewport: false` returned an empty frame;
  `captureBeyondViewport: true` rendered the same state at mean luminance
  35.7 against 35.3 for the unfiltered build, and the DOM agreed. Failure
  mode 9 in the flesh — but two paths agreeing is evidence about the
  channel, not proof about a real screen, so say that check is still
  owed.
- **Connotes**: frosting says *obscured* — something is behind this and
  you may not have it. Refraction says *dense* — something is behind this
  and it is being bent on the way to you, which is a claim about the
  medium rather than about the secret. Adding an edge with thickness
  moves the letters from holes cut in the page to objects laid on it, and
  an object can be picked up while a hole cannot: the wordmark stops
  being an absence the film shows through and becomes a lens the studio
  is holding. The rim is the part that says *made* — a cut hole has no
  bevel, and a bevel is a decision someone took with a tool. Keeping the
  light distant rather than local is a refusal of theatre: no hotspot
  tracks the viewer, nothing performs, the material simply sits under the
  same sun as everything else in the frame. And the restraint is the
  content — at +12 levels the effect is below the threshold where a
  viewer names it, so what they receive is not "a glass effect" but the
  impression that the page is made of better stuff than they can account
  for.
