Unexpected unsigned-to-signed promotion

As a newcomer to C, I also found this behavior less than "transparent". I've taken to using compiler directives to make things very explicit. For example,

byte Category, Name, Target;
unsigned int ID;
ID = (uint16_t) ((Category << 6 | Name ) << 3 | Target) << 5;

forces the calculations on the right to be done in a 16-bit unsigned register thus matching the type of ID. While composing I also tend to put in more of these (uint16_t) and parentheses than really needed as I never remember order of precedence rules (or almost anything else for that matter - my biological RAM leaves lots to be desired). Because it makes things look messy, I then clean it up, but making sure that I'm getting the same result.
Ciao,
Lenny