Gravity is the reference. The accelerometer reads which way is down — absolutely, without drift. The gyroscope fills the gaps between those readings, because gravity gets buried in noise the moment the phone is moving.
Browsers disagree about which gyroscope channel carries which axis, so the first thing this does is watch your motion and work it out. Rock the phone side to side when it asks.
Accelerometer anchors the angle, gyroscope smooths it. This is the one you ship.
Detecting…
The spec puts the screen-normal rate in α, but WebKit maps its channels straight onto CoreMotion's x/y/z, so on iOS it lands in γ and α carries pitch. Auto settles it by correlating each channel against the accelerometer's own roll rate.
Time constant of the complementary filter. Short reacts fast and shakes; long is glassy but lags.
Gravity sign: normal.