On iOS, nodes in ClientScreen appeared practically touching. NodeLayout.kt
placed nodes at layout coordinates (e.g. baseDistance = 210.0). Those
coordinates are later converted to Dp via position.x.toDp() in NodeItem.kt,
which divides by LocalDensity.current.density. On a 3× iPhone the 210-unit gap
shrinks to 70 dp — just 10 dp of air around a 60 dp node icon.
baseDistanceFor, idealDistanceFor, nodeRadiusFor in
composeApp/src/commonMain/kotlin/krill/zone/app/NodeLayout.kt) so the values
are testable from desktopTest without a live iOS device.baseDistance: 210 → 2100idealDistance: 170 → 1700nodeRadius: 40 → 400NodeLayoutIosDistanceTest in desktopTest that asserts each iOS
parameter is exactly 10× its Android peer, guarding against accidental reversion.NodeLayout.kt are raw floats in Compose’s “pixel”
space. NodeItem.kt converts them to Dp via toDp(), which divides by the
screen density. Any platform-specific layout constant must account for the
density of the target device, not just the logical node count.when block, verify the
value after the toDp() round-trip: value / density.density must exceed the
node’s visual diameter (CommonLayout.NODE_SIZE = 60 dp) with comfortable
margin.