I stumbled on the answer by trial and error:
default:
formatter:
name: pretty
parameters:
output_styles:
undefined: [ null, null, [ underscore ] ]
After working with the styles and keeping them in sync with the documented color meanings (see http://docs.behat.org/guides/2.definitions.html#step-execution-result-types), I came up with the following settings which work well on dark and light terminal color schemes, and which also use non-color styles to differentiate result types:
default:
formatter:
name: pretty
parameters:
output_styles:
passed: [ white, green ]
passed_param: [ white, green, [ bold ]]
undefined: [ yellow, null, [ underscore, bold ]]
pending: [ yellow, null, [ underscore ]]
pending_param: [ yellow, null, [ underscore, bold ]]
failed: [ white, red ]
failed_param: [ white, red, [ bold ]]
skipped: [ cyan ]
skipped_param: [ cyan, null, [ bold ]]
comment: [ cyan ]
tag: [ cyan ]
Here's a screenshot of these output_styles on both a light and dark terminal: