1. Is this behavior by design for custom tables in D365FO?
It's about what logic you used in the form; it's not about the table.
2. What is the recommended best practice to design a custom document number so that it behaves similarly to PO / SO?
As always, the implementation should follow your business requirements. Nevertheless I recommend avoiding continuous number sequences whenever possible. Normal sequences performs better, there are fewer things that can go wrong and it's usually not important whether a number wasn't reused.
3. Is using NumberSeq::newGetNumFromCode(..., true) together with abort() considered production-safe for document numbers?
It is. If use cross-references, you'll find more than a hundred cases in production code from Microsoft.
4. If the requirement is “do not consume the number when a Draft document is deleted”, what is the Microsoft-recommended pattern?
I don't think that Microsoft has any recommendation for your particular requirement. I would also challenge the requirement itself. If you delete an existing record (regardless of that a status field had a specific value), it doesn't mean that reusing the number is save. There may be references to the number, e.g. in logs, and reusing the same number for another record may be confusing or lead to errors.
I would ask users to explain what would be the problem for the business if it the number wasn't reused. Maybe someone just wish to have that but it doesn't have a real business justification.