Using hard memory algorithms, the benefit of ASICs is limited: RAM costs about the same price in an ASIC as it does in mainstream hardware.
Thus, one solution would be to pass the password via a hard memory function, hash the result twice and store the result in the password file.
For example. store it in the password file: sel, sha512 (sha512 (Argon2id (1 GB RAM, 1 G instructions, salt, password))).
As long as SHA512 and Argon2id are not broken, this should significantly reduce the use of ASICs.
Unfortunately, if the calculation is executed on the server, the server can be DoS by starting several connections simultaneously, because if the server has to run Argon2id (1 GB of RAM), it will use 1 GB of RAM for each simultaneous connection. This can be avoided by moving this calculation to the client:
Client: Please login in user A
Server: Here is the salt for user A
Client: computes sha512(Argon2id(1 GB RAM, 1 G instructions, salt, password))
Client: Return result to Server
Server: Compare sha512(result) with password file.
Even for modern smartphones, the use of 1 GB of RAM for 1 G instructions is possible, and for laptops this has not been a problem for a long time.
In practice, the client program would need native support for this, but for browsers, this should be possible using plug-ins / extensions / add-ons / modules.
When performing a single hash on the server, a leaked password file cannot be used directly, as calculating the reverse of a hash should be very difficult.
For customers who don't support this (for example, if they have less than 1 GB of free RAM), we can give the user the option to do a CAPTCHA, and if it does so, the server will perform the calculation for the client.