Span<T> all the things: enables the secure erasure of bytes and boosts performance.
Descriptive naming: BLAKE2b, not GenericHash.
Minimal parameters: no key parameter for an unkeyed hash.
One primitive for each task: (X)ChaCha20-Poly1305, BLAKE2b, Argon2id, X25519, and Ed25519.
No 128-bit keys: the minimum and universally recommended size is 256 bits.
Public constants: easy to create buffers.
Same vocabulary for everything: key, nonce, salt, input keying material, output keying material, etc.
Consistent parameter ordering: buffers come first.
Some low-level functions: useful for custom constructions.
Out of scope
Full misuse resistance (e.g. no nonces or optional nonces). This can limit the user, doesn't work well with spans, and overcomplicates code.
Solving the key reuse problem (e.g. a mandatory context for everything or wrappers instead of naked bytes). I'm not convinced either tactic works, and it again adds complexity.
Old NaCl APIs and high-level libsodium APIs, such as crypto_secretbox, crypto_box, and crypto_secretstream. secretstream is good for file encryption, but that's a bit specific. Then the older APIs shouldn't be used.
Other primitives unless they solve a problem. AES-GCM causes problems (e.g. it requires hardware support).
Experimental ideas/custom constructions (e.g. anything without an RFC or Internet Draft), which can go in a separate project.
Duplicate methods that return byte arrays.
Unnecessary 'convenience' functions, like GenerateKey() in almost every class.
Guarded heap allocations, which would add complexity and aren't the fastest.