    /* the contact editor's three fields go through the prompt sheet. The
       username travels as a VALUE, the way the playlist prompts do: the
       sheet switches kind under the prompt, so the contact block's
       {@const} is a destroyed derived by the time Save lands. */
    function metaPrompt(u, field, title, placeholder, value, multiline = false) {
        openHalf("prompt", {
            title, value, placeholder, ok: "Save", multiline, allowEmpty: true,
            onsubmit: (v) => { void setMeta(u, { [field]: v }); openHalf("contact", { username: u }); },
        });
    }
