    /* ── the weather ────────────────────────────────────────────────────
       Everything above this line is the happy path; nothing in thirty
       rounds of walk had ever made a command reject or taken the client
       offline, so none of these lines had ever been drawn. The mock's own
       doors (__ssMock.fail / answer / offline / clear) are the weather, and
       every assertion below is on SETTLED state — an armed failure stays
       armed, a sign-in card stays up, the folder-gone row stays — because
       the probe lands after the screenshot, well past the step's own wait.
       The one timed assertion is the room list, and its timeout is shortened
       to 1.2 s against the 3.1 s of waits between arming it and reading it.
       The last step puts the weather away and
       leaves the app exactly as it found it — anything appended after this
       block inherits a signed-in app on Home.

       The first step settles FIRST, and it has to: the landscape block above
       leaves the library tab three screens deep (record → artist), so one tap
       on the Library tab lands on the artist page and `.segtabs button` would
       be its discography tabs, not Albums/Artists/Tracks. It also wipes any
       error the happy path left standing, so `!i.toast` below means this
       block's toast and no other. */
    { do: `(function () { __ss.player.error = ''; __ss.lib.error = ''; __ss.player.retry = null; return __settle(); })()`, wait: 800 },
    { do: `__ssMock.fail('library_track_index', 'unable to open database file')`, wait: 300 },
    { do: `document.querySelectorAll('.nav button')[2].click()`, wait: 700 },
    { do: `document.querySelectorAll('.segtabs button')[2].click()`, name: "weather-tracks", wait: 1300 },
    { do: `__ssMock.fail('library_track_index', '')`, wait: 200 },
    { do: `__click('.imp-foot .btn', 'Try again')`, name: "weather-tracks-ok", wait: 1300 },
    /* signed out, in a lift: the card is back and nothing says why in Rust */
    { do: `__ssMock.offline(true)`, wait: 600 },
    { do: `document.querySelectorAll('.nav button')[3].click()`, name: "weather-signedout", wait: 1100 },
    /* the single most visible raw-Rust site on the phone, twice over */
    { do: `__ssMock.fail('connect_and_login', 'login failed: INVALIDPASS')`, wait: 200 },
    { do: `(function () { var p = document.querySelectorAll('.signin .field')[1]; p.value = 'hunter2'; p.dispatchEvent(new Event('input', { bubbles: true })); return true; })()`, wait: 400 },
    { do: `__click('.signin .btn-fill', 'Sign in')`, name: "weather-badpass", wait: 1200 },
    { do: `__ssMock.fail('connect_and_login', 'could not reach server: io: failed to lookup address information: no address associated with hostname')`, wait: 200 },
    { do: `__click('.signin .btn-fill', 'Sign in')`, name: "weather-noserver", wait: 1200 },
    /* Search signed out with a query typed showed NOTHING where the network
       section lives — no row, no reason. Now it says so and offers the door */
    { do: `document.querySelectorAll('.nav button')[1].click()`, wait: 700 },
    { do: `(function () { var i = document.querySelector('.sfield input'); i.value = 'daft punk'; i.dispatchEvent(new Event('input', { bubbles: true })); return true; })()`, name: "weather-search-out", wait: 1800 },
    /* the room list is fire-and-forget over the wire (the client sends it and
       nothing answers if the server will not), so the wait is ours: an armed
       answer that resolves and emits nothing is exactly that server. Community
       is left on Buddies by the walk above, so the Rooms tab is asked for by
       name — the note lives under that one. */
    { do: `__ssMock.fail('connect_and_login', ''); __ssMock.offline(false)`, wait: 1200 },
    { do: `(function () { __ss.slsk.roomsWaitMs = 1200; __ss.slsk.rooms = []; __ssMock.answer('slsk_room_list', null); __ss.refreshRooms(); return true; })()`, wait: 200 },
    { do: `document.querySelectorAll('.nav button')[3].click()`, wait: 900 },
    { do: `__click('.segtabs button', 'Rooms')`, name: "weather-rooms-late", wait: 2200 },
    /* one tap on Rescan library used to empty the whole index and say Ok */
    { do: `__ssMock.fail('rescan_library', 'library-folder-missing: /storage/1A2B-3C4D/Music')`, wait: 200 },
    { do: `document.querySelectorAll('.nav button')[4].click()`, wait: 800 },
    { do: `__click('.screen .row', 'Rescan library')`, name: "weather-rescan", wait: 1500 },
    /* and the weather clears */
    { do: `(function () { __ss.slsk.roomsWaitMs = 12000; __ssMock.clear(); __ss.refreshRooms(); __ss.player.error = ''; __ss.lib.error = ''; __ss.player.retry = null; return true; })()`, wait: 900 },
    { do: `__settle()`, wait: 900 },
    { do: `document.querySelectorAll('.nav button')[0].click()`, name: "weather-clear", wait: 1000 },
