    /* ── the weather ────────────────────────────────────────────────────
       Each of these fails if the round's fix is undone: the stub if a failed
       read goes back to being drawn as an empty library, the sign-in lines if
       the toast or the card stops translating, the search note if the block
       goes back to rendering nothing at all signed out, the room note if the
       spinner loses its end, the folder row if the rescan stops refusing.
       Every one also asserts the RAW string is gone — that is the round. */
    "weather-tracks": (i) => /^Couldn't read the library index/.test(i.why) && /library folder isn't readable/.test(i.why)
        && i.again && i.trks === 0 && !/database file/.test(i.why + i.toast),
    "weather-tracks-ok": (i) => !i.why && !i.again && i.trks > 0 && !i.toast,
    "weather-signedout": (i) => i.slskOn === "offline" && i.signin && !i.signinErr && !i.toast,
    "weather-badpass": (i) => i.signinErr === "Soulseek refused that password." && !/INVALIDPASS/.test(i.signinErr),
    "weather-noserver": (i) => /^Couldn't reach the Soulseek server/.test(i.signinErr) && !/io:|address information/.test(i.signinErr),
    "weather-search-out": (i) => i.title.startsWith("Search") && /Community/.test(i.offlineNote) && !i.netAsk,
    "weather-rooms-late": (i) => i.slskOn === "online" && /hasn't sent its room list/.test(i.roomsNote) && i.again,
    "weather-rescan": (i) => /1A2B-3C4D/.test(i.folderGone) && /isn't there any more/.test(i.toast) && /1A2B-3C4D/.test(i.toast)
        && !/library-folder-missing/.test(i.toast + i.folderGone),
    "weather-clear": (i) => !i.toast && !i.why && !i.folderGone && !i.roomsNote && i.slskOn === "online" && /^(Good |Still)/.test(i.title),