Properly securing a private key for remote storage I am attempting to secure a private key for remote storage on an untrusted device. Here are the parameters and my assumptions, I'd like to confirm I'm correct with them.

The keypair that I wish to encrypt is generated with ECDSA using the P-256 curve. My understanding is that this curve has 128 bits of security.

I give the user a Diceware passphrase (using cryptographically secure entropy) consisting of 10 words. This has 129 bits of security (12.9 bits per word).

I use HKDF with SHA-256 (no salt, no "info" label) to turn this passphrase into an actual key. The WebCrypto API dictates that I also specify the algorithm I intend to use this key for. I specify AES-CTR with a key length of 128 bits. The derivation function then outputs 128 bits of data (presumably truncated from 256 bits from the SHA-256 HMAC used by HKDF). Should I use the full 256 bits here instead?

Finally, I wrap the key using AES-CTR with a new empty 16-length byte array counter and a length of 128. According to the WebCrypto docs that I could find, length is a value from 1 to 128. What does this length represent and am I using it correctly?

In conclusion, my assumptions: The passphrase has 129 bits of security, it gets fed to a key derivation function that preserves 128 bits of security, and then this 128-bit key is used with AES-CTR which I'm hoping someone can confirm preserves the 128 bits of security as well.

Therefore, can I conclude that the encrypted private key being public is as secure as the public key being public? Deriving the private key from the public is 128 bits of security hard and so is decrypting the private key.
You should store a salt for HKDF-Hash alongside the encrypted message.  That way, the adversary can't attack many passwords simultaneously.
You should use your application's name, and the purpose of the key, as the info for HKDF-Extract.  That way, even if you are tempted in the future to use the same password for another purpose, it will be clearer what you must do to avoid accidentally reusing the key.
It may be OK to use a 128-bit key, but unless you're budget-constrained, you should use a 256-bit key to avoid multi-target attacks on AES.  There's nothing wrong with using a larger key than your target security level.
The way that AES-CTR works is that for a key $k$ and a nonce $n$, it generates a one-time pad $\operatorname{AES}_k(n \mathbin\Vert 0) \mathbin\Vert \operatorname{AES}_k(n \mathbin\Vert 1) \mathbin\Vert \cdots$, and xors that with your message to get the ciphertext.

What does $n \mathbin\Vert 0$ mean, exactly?  It's the concatenation of some bit encoding of a per-message nonce, which may be anywhere from 0 to 128 bits, with some bit encoding of a per-block counter, whose length must be $128 - \ell_n$ where $\ell_n$ is the maximum number of bits in the nonce.  The point is that we never reuse $\operatorname{AES}_k(x)$ for different parts of the plaintext.

In the WebCrypto API, §25.3 AesCtrParams dictionary, your obligation is to pass a byte array [0x00 0x01 0x02 0x03 0x04 0x05 0x06 0x07 0x08 0x09 0x0a 0x0b; 0x00 0x00 0x00 0x00] that will serve as the initial input with the nonce, and then specify how long the counter is to be incremented as an integer, marked in this example by a semicolon.

First, you must never use a nonce more than once with any given key.  If your key is used only once ever, then you can just use an all-zero or empty nonce.  If you reuse a key, then with AES, you should use a sequentially incrementing nonce, or think very carefully about what limits your application can live with on the number of messages you use any particular key with.  In this case, I recommend a single-use key; if you want to use the same password for different purposes, just derive an independent key using a different HKDF-Expand info parameter.

Second, the number of bits in the counter must fit the length of the longest message you can encounter.  That is, if you handle up to $\ell_m$-bit messages, then you must specify a counter length in bits that is at least $\lceil\log_2 \ell_m/128\rceil$.  Here we divide by 128 because each counter value corresponds to 128 bits of AES-CTR key stream.
Actually, you may not want to use AES-CTR directly because it does not provide authentication.  Unless you are again budget-constrained, or for some reason you want to avoid authentication (which makes sense in some applications, like a scheme to require 2FA for disk encryption so that the adversary can't even test a password guess without a separate physical token, but seems unlikely here), you should always use authenticated encryption by default absent a particular reason not to: AES-GCM, not AES-CTR.
Beware timing side channels in software implementations of AES (and GHASH, if you use AES-GCM)!  Even though hardware AES support is widespread today, it takes a lot of effort to audit your software stack well enough to guarantee it is reliably using the hardware AES support on all platforms that may be of interest to you.  If you use NaCl crypto_secretbox_xsalsa20poly1305 instead, this is not a problem.