Goal
Delete the page-level CSS zoom bridge and every runtime/test path that compensates for it.
PR #147 set the page scale to native size:
That made the complete zoom bridge a no-op, but the application still measures, publishes, propagates, divides by, and tests a zoom factor that can no longer differ from 1.
This issue removes that dead infrastructure and leaves every surface using native browser coordinates and containing-block sizing.
This is one atomic cleanup. Do not leave a mixed state where some popovers, drags, charts, or detached views still expect zoom-adjusted coordinates.
Scope
Remove all active implementation references to:
html { zoom: ... }
--zoom
--vp-zoom
zoomScale
viewportZoom
measureViewportZoom
applyViewportZoom
app.vpZoom
unzoomChartEvent
installChartZoomFix
Historical release notes may retain references to the removed behavior.
CSS
Remove page zoom
Delete:
html { zoom : var (--zoom ); }
Delete these custom properties:
Delete the fallback:
@supports not (zoom : 1 ) {
...
}
Remove comments that describe page-level CSS zoom, viewport-unit divergence, or zoom divisors.
Overlay sizing
The overlay is already a fixed viewport-sized containing block with its own padding:
.graph-overlay {
position : fixed;
inset : 0 ;
padding : 24px ;
}
Size its panel from the containing block:
.graph-overlay-panel {
width : 100% ;
height : 100% ;
}
Do not use viewport-unit division or a replacement JavaScript measurement.
Detached views
Use native full-height layout:
html ,
body {
height : 100% ;
}
body .detached-tab {
height : 100% ;
}
body .detached-tab .graph-overlay-panel {
width : 100% ;
height : 100% ;
}
Keep the existing detached-tab border and border-radius overrides.
Do not copy sizing custom properties from the opener.
Delete viewport measurement
Delete:
Remove from src/ui/app.js:
viewportZoom import
app.measureViewportZoom
app.applyViewportZoom
app.vpZoom
the post-mount app.applyViewportZoom() call
Do not replace this with another probe or resize observer.
Fullscreen surfaces must size correctly from normal CSS layout.
Native-coordinate anchoring
Delete zoomScale
Remove zoomScale() from:
Remove every import and call.
Keep and simplify fixedAnchor
Popover anchoring is still shared behavior and must remain centralized.
Change:
fixedAnchor ( rect , scale , opts )
to:
Required behavior:
export function fixedAnchor ( rect , opts = { } ) {
const gap = opts . gap != null ? opts . gap : 6 ;
const min = opts . min != null ? opts . min : 8 ;
const top = rect . bottom + gap ;
return opts . viewportW != null
? {
top,
right : Math . max ( min , opts . viewportW - rect . right ) ,
}
: {
top,
left : Math . max ( min , rect . left ) ,
} ;
}
Update all callers:
src/ui/app.js
src/ui/file-menu.js
src/ui/combobox.js
src/ui/combo-footer.js
Popover widths
Replace:
with:
This applies to:
combobox list width;
combobox footer width;
any other anchored fixed-position element.
Drag and resize cleanup
All pointer events and layout dimensions now use native CSS pixels.
Remove every scale argument, scale callback, and division.
Splitters
Change:
dragValue ( axis , event , rect , scale )
to:
dragValue ( axis , event , rect )
Native behavior:
if ( axis === 'col' ) {
return clamp ( event . clientX , 180 , 420 ) ;
}
if ( axis === 'drawer' ) {
return clampDrawerWidth ( rect . width - event . clientX , rect . width ) ;
}
Keep percentage-based axes unchanged.
Remove ctx.scale from startDrag().
Update all callers in src/ui/app.js and src/ui/results.js.
Result-grid columns
Change:
colResizeWidth ( startWidth , deltaX , scale )
to:
colResizeWidth ( startWidth , deltaX )
Implementation:
return Math . max ( MIN_COL , Math . round ( startWidth + deltaX ) ) ;
Remove the zoomScale() measurement from column-resize startup.
This applies to all shared grid consumers, including script-result grids.
Schema detail height
Replace:
( r . bottom - event . clientY ) / scale
r . height / scale
with:
r . bottom - event . clientY
r . height
Remove the zoom measurement and zoom-specific comments.
Cell-detail drawer
Remove the scale callback passed to startDrag().
The drawer width calculation uses native clientX directly.
Chart.js cleanup
Delete from src/core/chart-data.js:
Delete from src/ui/chart-render.js:
zoomScale import
unzoomChartEvent import
installChartZoomFix
Instantiate Chart.js directly:
const chart = new app . Chart (
canvas ,
chartJsConfig ( ...)
) ;
Keep the existing detached-document resize/update handling. It solves a cross-realm Chart.js sizing problem and is unrelated to CSS zoom.
Update comments so they describe only the cross-realm behavior.
Detached-view cleanup
In src/ui/detached-view.js:
stop reading --vp-zoom from the opener;
stop writing it into the child document;
retain theme and density mirroring;
retain copied stylesheet and favicon behavior;
retain tab/overlay fallback behavior.
Rename mirrorTheme() only when needed for clarity. A rename is not required.
Files
Expected modifications:
src/styles.css
src/ui/dom.js
src/ui/app.js
src/ui/file-menu.js
src/ui/combobox.js
src/ui/combo-footer.js
src/ui/chart-render.js
src/ui/grid-render.js
src/ui/results.js
src/ui/schema-detail.js
src/ui/detached-view.js
src/ui/splitters.js
src/core/chart-data.js
tests/unit/dom.test.js
tests/unit/app.test.js
tests/unit/chart-data.test.js
tests/unit/grid-render.test.js
tests/unit/splitters.test.js
tests/unit/schema-detail.test.js
tests/unit/detached-view.test.js
Delete:
src/core/zoom-support.js
tests/unit/zoom-support.test.js
tests/e2e/zoom-support.spec.js
tests/e2e/zoom.html
Update other tests discovered by the final repository search.
No new runtime dependency.
Test requirements
Repository-wide dead-code search
The implementation is incomplete when active source or active tests contain any of:
--zoom
--vp-zoom
zoomScale
viewportZoom
measureViewportZoom
applyViewportZoom
app.vpZoom
unzoomChartEvent
installChartZoomFix
html{zoom}
html { zoom
Exclude historical changelog text from this gate.
Unit tests
Update tests for the new signatures and native-coordinate behavior.
fixedAnchor
Cover:
default gap;
custom gap;
left alignment;
right alignment;
minimum inset;
zero and fractional coordinates;
no scale parameter.
Splitters
Cover:
sidebar width follows clientX;
drawer width follows viewportWidth - clientX;
clamping remains unchanged;
percentage axes remain unchanged;
startDrag() no longer reads ctx.scale.
Grid columns
Cover:
positive and negative native deltas;
minimum width;
paired-column resize;
last-column growth;
no scale parameter.
Schema detail
Cover:
drag delta maps directly to flex basis;
panel-height upper bound uses native height;
close during drag removes listeners.
Charts
Remove zoom-event mutation tests.
Retain:
chart configuration;
Chart.js construction;
detached/cross-realm explicit resize;
chart destruction and lifecycle.
Detached views
Verify:
theme and density still mirror;
no zoom custom property is mirrored;
panel mounts in tabs and overlay fallback;
close/teardown behavior is unchanged.
Browser tests
Use normal application surfaces rather than a synthetic zoom harness.
Run on Chromium, Firefox, and WebKit.
Verify:
File menu opens under the File button and remains inside the viewport.
Save and user popovers align to their triggers.
Variable combobox list aligns with the input.
The recents footer aligns with the combobox and matches its width.
Sidebar resize tracks the cursor.
Editor/results and sidebar vertical splitters retain their behavior.
Cell-detail drawer resize tracks the cursor.
Result-grid column resize tracks the cursor.
Schema-detail height resize tracks the cursor.
Chart hover and tooltip target the correct bar, point, or slice.
Fullscreen graph overlay fits within its padded viewport.
Detached schema, pipeline, and Data views fill their browser tab.
Narrow/mobile popovers remain inside the viewport.
Use tolerances only for normal browser layout rounding. Do not assert a zoom divisor.
Real Safari
A manual real-Safari smoke pass is recommended for release confidence:
popovers;
comboboxes;
splitters;
Chart hover;
fullscreen overlay;
detached view.
It is not a special architectural gate for this issue. The former real-Safari discrepancy was specific to CSS zoom, which this change removes.
Implementation order
1. CSS and viewport measurement
remove page zoom declarations;
replace overlay and detached sizing;
remove zoom-support.js;
remove app measurement/publication;
remove detached property mirroring.
2. Native anchoring
delete zoomScale;
simplify fixedAnchor;
migrate File menu, application popovers, combobox, and footer.
3. Native drag geometry
simplify splitter APIs;
simplify grid-column resize;
simplify schema-detail resize;
remove drawer scale callbacks.
4. Chart cleanup
remove event correction;
instantiate Chart.js directly;
retain cross-realm resize behavior.
5. Tests and documentation
delete obsolete zoom harnesses;
add behavior-level browser coverage;
update comments;
update CHANGELOG.md;
run repository-wide dead-code search.
Non-goals
Do not include:
GraphSurface extraction;
graph selection or movement changes;
new popover abstractions;
new splitter behavior;
redesign of detached views;
browser zoom detection;
application-level UI scaling or density preferences;
replacement of CSS zoom with transforms;
changes to Chart.js configuration unrelated to event correction.
Browser-native page zoom remains supported by the browser and requires no application compensation.
Acceptance criteria
html no longer uses the CSS zoom property.
--zoom and --vp-zoom are removed from active CSS and JavaScript.
src/core/zoom-support.js is deleted.
Runtime viewport probing and publication are deleted.
Detached views no longer mirror a viewport-zoom property.
zoomScale() is deleted.
fixedAnchor() uses native coordinates and has no scale argument.
File, Save, user, combobox, and footer anchoring use the simplified helper.
Splitter geometry has no scale argument or callback.
Grid-column resizing has no scale argument.
Schema-detail resizing has no zoom division.
Cell-detail drawer resizing has no zoom callback.
Chart.js event interception and unzoomChartEvent() are deleted.
Cross-realm Chart.js resize behavior remains intact.
Overlay panels fill their padded containing block.
Detached panels fill their browser tab.
Obsolete zoom unit and E2E harnesses are deleted.
Active source and tests contain no zoom-compensation identifiers.
Popovers, comboboxes, drags, charts, overlays, and detached views pass behavior tests.
Chromium, Firefox, and WebKit E2E suites pass.
Existing per-file coverage gates remain green.
npm test passes.
npm run build succeeds.
No new runtime dependency is added.
Definition of done
The application uses one coordinate system: native browser CSS pixels.
All fixed-position anchoring, pointer input, layout sizing, drag geometry, Chart.js interaction, overlays, and detached views operate without application-level page-zoom detection or conversion.
Future surfaces, including GraphSurface, have no zoom bridge to inherit.
Goal
Delete the page-level CSS zoom bridge and every runtime/test path that compensates for it.
PR #147 set the page scale to native size:
That made the complete zoom bridge a no-op, but the application still measures, publishes, propagates, divides by, and tests a zoom factor that can no longer differ from
1.This issue removes that dead infrastructure and leaves every surface using native browser coordinates and containing-block sizing.
This is one atomic cleanup. Do not leave a mixed state where some popovers, drags, charts, or detached views still expect zoom-adjusted coordinates.
Scope
Remove all active implementation references to:
Historical release notes may retain references to the removed behavior.
CSS
Remove page zoom
Delete:
Delete these custom properties:
Delete the fallback:
Remove comments that describe page-level CSS zoom, viewport-unit divergence, or zoom divisors.
Overlay sizing
The overlay is already a fixed viewport-sized containing block with its own padding:
Size its panel from the containing block:
Do not use viewport-unit division or a replacement JavaScript measurement.
Detached views
Use native full-height layout:
Keep the existing detached-tab border and border-radius overrides.
Do not copy sizing custom properties from the opener.
Delete viewport measurement
Delete:
Remove from
src/ui/app.js:Do not replace this with another probe or resize observer.
Fullscreen surfaces must size correctly from normal CSS layout.
Native-coordinate anchoring
Delete
zoomScaleRemove
zoomScale()from:Remove every import and call.
Keep and simplify
fixedAnchorPopover anchoring is still shared behavior and must remain centralized.
Change:
to:
Required behavior:
Update all callers:
Popover widths
Replace:
with:
This applies to:
Drag and resize cleanup
All pointer events and layout dimensions now use native CSS pixels.
Remove every scale argument, scale callback, and division.
Splitters
Change:
to:
Native behavior:
Keep percentage-based axes unchanged.
Remove
ctx.scalefromstartDrag().Update all callers in
src/ui/app.jsandsrc/ui/results.js.Result-grid columns
Change:
to:
Implementation:
Remove the
zoomScale()measurement from column-resize startup.This applies to all shared grid consumers, including script-result grids.
Schema detail height
Replace:
with:
Remove the zoom measurement and zoom-specific comments.
Cell-detail drawer
Remove the scale callback passed to
startDrag().The drawer width calculation uses native
clientXdirectly.Chart.js cleanup
Delete from
src/core/chart-data.js:Delete from
src/ui/chart-render.js:Instantiate Chart.js directly:
Keep the existing detached-document resize/update handling. It solves a cross-realm Chart.js sizing problem and is unrelated to CSS zoom.
Update comments so they describe only the cross-realm behavior.
Detached-view cleanup
In
src/ui/detached-view.js:--vp-zoomfrom the opener;Rename
mirrorTheme()only when needed for clarity. A rename is not required.Files
Expected modifications:
Delete:
Update other tests discovered by the final repository search.
No new runtime dependency.
Test requirements
Repository-wide dead-code search
The implementation is incomplete when active source or active tests contain any of:
Exclude historical changelog text from this gate.
Unit tests
Update tests for the new signatures and native-coordinate behavior.
fixedAnchorCover:
Splitters
Cover:
clientX;viewportWidth - clientX;startDrag()no longer readsctx.scale.Grid columns
Cover:
Schema detail
Cover:
Charts
Remove zoom-event mutation tests.
Retain:
Detached views
Verify:
Browser tests
Use normal application surfaces rather than a synthetic zoom harness.
Run on Chromium, Firefox, and WebKit.
Verify:
Use tolerances only for normal browser layout rounding. Do not assert a zoom divisor.
Real Safari
A manual real-Safari smoke pass is recommended for release confidence:
It is not a special architectural gate for this issue. The former real-Safari discrepancy was specific to CSS
zoom, which this change removes.Implementation order
1. CSS and viewport measurement
zoom-support.js;2. Native anchoring
zoomScale;fixedAnchor;3. Native drag geometry
4. Chart cleanup
5. Tests and documentation
CHANGELOG.md;Non-goals
Do not include:
Browser-native page zoom remains supported by the browser and requires no application compensation.
Acceptance criteria
htmlno longer uses the CSSzoomproperty.--zoomand--vp-zoomare removed from active CSS and JavaScript.src/core/zoom-support.jsis deleted.zoomScale()is deleted.fixedAnchor()uses native coordinates and has no scale argument.unzoomChartEvent()are deleted.npm testpasses.npm run buildsucceeds.Definition of done
The application uses one coordinate system: native browser CSS pixels.
All fixed-position anchoring, pointer input, layout sizing, drag geometry, Chart.js interaction, overlays, and detached views operate without application-level page-zoom detection or conversion.
Future surfaces, including GraphSurface, have no zoom bridge to inherit.