The literal is checked where you wrote it. The variable is not.
The common read: the check is a property of the object, so a value that fails a shape check fails it wherever I write it.
Excess property checking is not part of assignability. It is a separate check, and the compiler runs it only on an object literal at the point that literal is assigned or passed.
That is why the two lines behave differently. The excess property check reports the exact unknown key it found, so when the target declares a key with a similar spelling, the message adds Did you mean to write 'color'?. On the variable line the excess property check does not run. Only the ordinary assignability check runs, and that check never looks for unknown keys, so it reports no key and suggests no spelling. There are three documented ways around the check and they are not equal.
A type assertion says you have decided the type yourself. A string index signature says the shape accepts arbitrary extra keys, and it is the only one of the three that changes the type rather than skipping the check. Assigning through a variable is the accidental one, because nobody chooses it as a workaround: developers write it because the config needed a line of preparation, and the check stopped applying with no error.
For example, a user reports that the dark theme flag does nothing on the settings page, the report goes to the theme service, and its author reads the call site, sees a key that looks like the right name, and closes the report as unreproducible.

