# ✅ At least two thirds of the title's disagreement is GEOMETRY, not tone > ⚠️ **The 10.92 title baseline here could not be reproduced on 2026-08-29** — > `screen render --build 4 --black` against the same capture gives 14.07 both at > `formats-pin-2026-08-29c` and today. The *ratio* this document argues for may > well survive; the absolute is in doubt. Separately, part of the title's residual > is now known to be neither tone nor rotation but `rest()` posing five transient > flashes at their peaks — [`ui-settle-time.md`](ui-settle-time.md) closes the > light-arc band from 33.22 to 11.79. **Classification: measured**, on committed captures. Answers a question the pending rotation decision needs: *how much would drawing the rotation actually buy?* Two separate effects are known to make our renders differ from the console: * the **tone curve** — the console renders midtones brighter than we do ([`ui-render-tone-curve.md`](ui-render-tone-curve.md)), and its single-exponent model is refuted above render ≈ 40; * the **missing rotation** — our blit draws axis-aligned rectangles, so the title's two tilted light sweeps land as upright bars ([`ui-keyframe-rotation.md`](ui-keyframe-rotation.md)). They are confounded in any whole-frame number. This separates them. ## Method, and why the split is an upper bound on tone A **per-level lookup table** fitted on a screen is the most general tone model there is: it maps every render level to whatever capture level minimises the error, with no functional form assumed. **Whatever such a LUT cannot close is, by construction, not a per-pixel-level effect** — it is spatial. So fitting a LUT *on the screen itself* and measuring what remains gives an **upper bound on the tone share** and a **lower bound on the geometry share**. ## The positive control The method must be able to close a residual that really is tone. On the **main menu** it does: > 🔴 **THE PREMISE OF THIS CONTROL WAS WRONG, corrected 2026-08-31.** It read > *"where the port measures only 0.06 % of pixels differing, so geometry is > essentially right"*. That 0.06 % is `verify-capture`'s, and it counts pixels > surviving `-threshold 25%` — differing by more than ~64 levels. **It is a > gross-displacement detector by design**, blind to sub-pixel offsets and > antialiasing, which are exactly what a per-level LUT also cannot close. It says > *no gross displacement*, not *geometry is right*, and I read one as the other. > > `sylpheed-port` measured the screen directly (`DECISIONS.md` at `5738b83`): after > this LUT, the menu's residual is **6.94 on edge pixels against 2.20 on flat — > 3.2×**, with a known negative (a render against itself under a pure gamma) > leaving exactly **0.00**, since a per-level LUT inverts a per-level effect > perfectly. **So the menu carries spatial error and is not a geometry-free > control.** ⚠️ I have **not** reproduced that split — it needs their render beside > the capture — and it is recorded as their measurement, not mine. > > ✅ **The result below does not rest on this control.** *"Whatever a fitted > per-level LUT cannot close is, by construction, not a per-pixel-level effect"* is > stated as the method's basis above and stands on its own. What the control > actually shows is narrower than claimed: the LUT closes 70 % of the menu's > residual — evidence it works on tone, not evidence the menu is tone-only. | | mean abs difference | closed | |---|---|---| | main menu, uncorrected | 9.26 | — | | **main menu + LUT fitted on the main menu** | **2.75** | **70.3 %** | ✅ The instrument works: a tone-dominated residual collapses by 70 %. ## The result | | mean abs difference | closed | |---|---|---| | title, uncorrected | 10.92 | — | | **title + LUT fitted on the title** | **7.42** | **32.0 %** | 🔴 **At most 32 % of the title's disagreement is a tone effect, so at least 68 % is spatial** — content in the wrong place. That is where the rotation lives, and it makes the rotation the dominant term by roughly two to one. ⚠️ The same-screen LUT is *fitted*, so 32 % is generous to tone. The true tone share is smaller and the geometry share larger. ## 🔴 And a claim this refutes: there is no single transferable tone curve Fitting on one screen and applying to the other: | | closed | |---|---| | main menu + LUT fitted on the **title** | **+29.7 %** | | title + LUT fitted on the **main menu** | **−24.0 %** ✗ | **The menu's curve makes the title worse.** A curve fitted on a dark, flat screen is unconstrained at the bright end — the menu's populated range is levels 5–204 with few bright pixels — and extrapolating it onto the title's planet and wordmark actively harms. ⚠️ So *"the tone curve"* is not one thing that can be measured once and applied. This extends [`ui-render-tone-curve.md`](ui-render-tone-curve.md)'s refutation of the single **exponent**: even a full per-level LUT fails to transfer between screens. **A consumer must not carry a global tone correction.** ## Reach * Two screens, one capture each; the title capture is the plate-free frame and our render is at rest, so they are **the same screen but not the same instant** — a looser pairing than the port's posed comparison, which is why the absolute numbers here (10.92) are larger than its 1.81 % of pixels. ⚠️ The *ratio* is what this page claims, not the absolute level. * Our render draws the sweeps' **parent** record only — the pre-leaf-fix state — so the geometry share measured here includes both the missing rotation and the missing leaf placement. Both are closed by the same decision. ## ✅ The menu's edge residual is NOT global misregistration, and not blur **Measured by `sylpheed-port`** (`tools/port/edge-residual-kind`, branch `auto/port-p6-audio` at `f4351b0`), running the discriminator I proposed but could not execute — it needs their render beside the capture, which I do not have. Recorded as their measurement. The test, made concrete: a shift by `(dx,dy)` makes the **signed** residual track the **gradient**, and the fitted slope *is* the shift in pixels; a blur makes it track the **laplacian**, symmetric and directionless. | | | |---|---| | **control** — a known +1 px shift | reads back **+0.938 px** (r +0.789) | | **control** — a known blur | **r −0.896** on the laplacian | | neither leaked into the other's channel | ✅ | | **`main_menu` vs the capture** | **−0.010 px** horizontal, **−0.009 px** vertical; laplacian **r +0.103** | ❌ **Global misregistration is excluded**: any whole-frame translation is under a hundredth of a pixel, against a control that reads a true 1 px at 0.938. ❌ **Blur is excluded**: the weak laplacian term is the **opposite sign** to the blur control, so the capture is not a softened render either. ⚠️ **The reach is the whole reach: this is a WHOLE-FRAME fit.** One misplaced element is a small share of 38 752 edge pixels and would not move these numbers. It excludes a **global** translation, not a **local** one. 📌 **So of the three candidates I named — misregistration, antialiasing, a misplaced soft element — the third survives, and it is the only one left.** The next test is necessarily **local**: where does the edge residual concentrate spatially, and does that region correspond to one element? ⚠️ That needs the residual map, which is on the port's side; I can state the test and cannot run it.