diff --git a/CHANGES.md b/CHANGES.md
--- a/CHANGES.md
+++ b/CHANGES.md
@@ -12,6 +12,7 @@
 
     - 1.1.0.1 (October 27, 2020): Limit `optparse-applicative` to 0.16.x
     - 1.1.1 (June 2, 2021): Build with GHC 9.0.1
+    - 1.1.2 (January 20, 2023): Build with GHC 9.2.4 (thanks @Arraying)
 
 ## 1.0 (July 27, 2020)
 
diff --git a/README.md b/README.md
--- a/README.md
+++ b/README.md
@@ -1,6 +1,6 @@
 # Byline
 
-[![CI](https://github.com/pjones/byline/workflows/CI/badge.svg)](https://github.com/pjones/byline/actions)
+[![tests](https://github.com/pjones/byline/workflows/tests/badge.svg)](https://github.com/pjones/byline/actions)
 [![GitHub tag (latest by date)](https://img.shields.io/github/v/tag/pjones/byline?label=release)](https://github.com/pjones/byline/releases)
 [![Hackage](https://img.shields.io/hackage/v/byline)](https://hackage.haskell.org/package/byline)
 
@@ -20,13 +20,13 @@
 ```haskell
 example :: MonadByline m => m Text
 example = do
-  sayLn ("Hey, I like " <> ("Haskell" <> fg magenta) <> "!")
+  sayLn ("Hey, I like " <> ("Haskell" & fg magenta) <> "!")
 
   let question =
         "What's "
-          <> ("your" <> bold)
+          <> ("your" & bold)
           <> " favorite "
-          <> ("language" <> fg green <> underline)
+          <> ("language" & fg green & underline)
           <> "? "
 
   askLn question (Just "Haskell")
diff --git a/byline.cabal b/byline.cabal
--- a/byline.cabal
+++ b/byline.cabal
@@ -1,17 +1,17 @@
 cabal-version:      2.2
 name:               byline
-version:            1.1.1
+version:            1.1.2
 homepage:           https://github.com/pjones/byline
 bug-reports:        https://github.com/pjones/byline/issues
 license:            BSD-2-Clause
 license-file:       LICENSE
 author:             Peter Jones <pjones@devalot.com>
 maintainer:         Peter Jones <pjones@devalot.com>
-copyright:          Copyright: (c) 2015-2021 Peter J. Jones
+copyright:          Copyright: (c) 2015-2023 Peter J. Jones
 category:           System, User Interfaces
 build-type:         Simple
 stability:          stable
-tested-with:        GHC ==8.8.4 || ==8.10.4 || ==9.0.1
+tested-with:        GHC ==8.10.7 || ==9.0.2 || ==9.2.5
 synopsis:
   Library for creating command-line interfaces (colors, menus, etc.)
 
@@ -101,12 +101,12 @@
     , colour                ^>=2.3
     , exceptions            >=0.8  && <0.11
     , free                  ^>=5.1
-    , haskeline             >=0.8  && <0.8.2
-    , mtl                   >=2.1  && <2.3
-    , optparse-applicative  ^>=0.16
-    , relude                >=0.6  && <1.1
+    , haskeline             >=0.8  && <0.8.3
+    , mtl                   >=2.1  && <2.4
+    , optparse-applicative  ^>=0.17
+    , relude                >=0.6  && <1.2
     , terminfo-hs           >=0.1  && <0.3
-    , text                  >=0.11 && <1.3
+    , text                  >=0.11 && <2.1
 
   mixins:
     base hiding (Prelude),
@@ -173,6 +173,15 @@
 executable shell
   import:        options, dependencies
   main-is:       examples/shell.hs
+  build-depends: byline
+
+  if !flag(build-examples)
+    buildable: False
+
+--------------------------------------------------------------------------------
+executable colors
+  import:        options, dependencies
+  main-is:       examples/colors.hs
   build-depends: byline
 
   if !flag(build-examples)
diff --git a/examples/colors.hs b/examples/colors.hs
new file mode 100644
--- /dev/null
+++ b/examples/colors.hs
@@ -0,0 +1,35 @@
+-- |
+--
+-- Copyright:
+--   This file is part of the package byline. It is subject to the
+--   license terms in the LICENSE file found in the top-level
+--   directory of this distribution and at:
+--
+--     https://github.com/pjones/byline
+--
+--   No part of this package, including this file, may be copied,
+--   modified, propagated, or distributed except according to the
+--   terms contained in the LICENSE file.
+--
+-- License: BSD-2-Clause
+module Main
+  ( main,
+  )
+where
+
+import Byline
+import Control.Monad
+
+-- | Simple example.
+example :: MonadByline m => m ()
+example = do
+  let colors = [black, red, yellow, green, blue, cyan, magenta, white]
+  let styles = [id, underline, bold, bold . underline]
+  let intensity = [id, vivid]
+  let fgbg = [id, swapFgBg]
+  let mods = [ (text "byline" &) <$> [fb . fg (i c) . s | c <- colors] | fb <- fgbg, i <- intensity, s <- styles]
+  mapM_ (sayLn . fold) mods
+
+-- | Main.
+main :: IO ()
+main = Control.Monad.void (runBylineT example)
diff --git a/examples/demo.hs b/examples/demo.hs
--- a/examples/demo.hs
+++ b/examples/demo.hs
@@ -22,13 +22,13 @@
 -- | Simple example.
 example :: MonadByline m => m Text
 example = do
-  sayLn ("Hey, I like " <> ("Haskell" <> fg magenta) <> "!")
+  sayLn ("Hey, I like " <> ("Haskell" & fg magenta) <> "!")
 
   let question =
         "What's "
-          <> ("your" <> bold)
+          <> ("your" & bold)
           <> " favorite "
-          <> ("language" <> fg green <> underline)
+          <> ("language" & fg green & underline)
           <> "? "
 
   askLn question (Just "Haskell")
diff --git a/examples/menu.hs b/examples/menu.hs
--- a/examples/menu.hs
+++ b/examples/menu.hs
@@ -29,8 +29,8 @@
 -- | How to display a menu item.
 instance ToStylizedText Item where
   toStylizedText item = case item of
-    Fruit name -> text name <> (" (fruit)" <> fg red)
-    Vegetable name -> text name <> (" (vegetable)" <> fg green)
+    Fruit name -> text name <> (" (fruit)" & fg red)
+    Vegetable name -> text name <> (" (vegetable)" & fg green)
 
 -- | The list of menu items.
 items :: NonEmpty Item
@@ -46,10 +46,10 @@
 main :: IO ()
 main = do
   let menuConfig =
-        menuBanner ("Pick a snack: " <> bold) $
+        menuBanner ("Pick a snack: " & bold) $
           menu items
-      prompt = "Which snack? " <> bold <> fg yellow
-      onError = "Please pick a valid item!" <> fg red
+      prompt = "Which snack? " & bold & fg yellow
+      onError = "Please pick a valid item!" & bg (vivid red)
 
   -- Display the menu and get back the item the user selected.  The
   -- user will be able to select an item using it's index, name, or
diff --git a/examples/simple.hs b/examples/simple.hs
--- a/examples/simple.hs
+++ b/examples/simple.hs
@@ -25,7 +25,7 @@
 main = void $
   runBylineT $ do
     -- Start with a simple message to standard output:
-    sayLn ("I can use " <> ("color" <> fg blue) <> "!")
+    sayLn ("I can use " <> ("color" & fg blue) <> "!")
 
     -- When not using any stylized modifiers you can use the `text'
     -- helper function to avoid "Ambiguous type variable":
@@ -34,26 +34,26 @@
     -- Get user input with a stylized prompt:
     let question =
           "What's your favorite "
-            <> ("language" <> bold <> fg green)
+            <> ("language" & bold & fg green)
             <> "? "
     language <- askLn question Nothing
 
     if Text.null language
-      then Exit.die ("Cat got your tongue?" <> fg magenta)
-      else sayLn ("I see, you like " <> (text language <> fg red) <> ".")
+      then Exit.die ("Cat got your tongue?" & fg (vivid magenta))
+      else sayLn ("I see, you like " <> (text language & fg red) <> ".")
 
     -- Keep prompting until a confirmation function indicates that the
     -- user's input is sufficient:
     let question =
           "What's your "
-            <> ("name" <> fg green <> underline)
+            <> ("name" & fg green & underline)
             <> "? "
     name <- askUntil question Nothing (pure . atLeastThreeChars)
-    sayLn $ "Hey there " <> text name <> fg (rgb 108 113 196)
+    sayLn $ "Hey there " <> text name & fg (rgb 108 113 196)
 
 -- | Example confirmation function that requires the input to be three
 -- or more characters long.
 atLeastThreeChars :: Text -> Either (Stylized Text) Text
 atLeastThreeChars input
-  | Text.length input < 3 = Left ("You can do better." <> bg red)
+  | Text.length input < 3 = Left ("You can do better." & bg red)
   | otherwise = Right input
diff --git a/src/Byline.hs b/src/Byline.hs
--- a/src/Byline.hs
+++ b/src/Byline.hs
@@ -49,6 +49,8 @@
     magenta,
     cyan,
     white,
+    vivid,
+    dull,
     rgb,
   )
 where
diff --git a/src/Byline/Internal/Color.hs b/src/Byline/Internal/Color.hs
--- a/src/Byline/Internal/Color.hs
+++ b/src/Byline/Internal/Color.hs
@@ -24,6 +24,8 @@
     magenta,
     cyan,
     white,
+    vivid,
+    dull,
     rgb,
     colorAsANSI,
     colorAsIndex256,
@@ -42,15 +44,25 @@
 --
 -- @since 1.0.0.0
 black, red, green, yellow, blue, magenta, cyan, white :: Color
-black = ColorCode ANSI.Black
-red = ColorCode ANSI.Red
-green = ColorCode ANSI.Green
-yellow = ColorCode ANSI.Yellow
-blue = ColorCode ANSI.Blue
-magenta = ColorCode ANSI.Magenta
-cyan = ColorCode ANSI.Cyan
-white = ColorCode ANSI.White
+black = ColorCode ANSI.Dull ANSI.Black
+red = ColorCode ANSI.Dull ANSI.Red
+green = ColorCode ANSI.Dull ANSI.Green
+yellow = ColorCode ANSI.Dull ANSI.Yellow
+blue = ColorCode ANSI.Dull ANSI.Blue
+magenta = ColorCode ANSI.Dull ANSI.Magenta
+cyan = ColorCode ANSI.Dull ANSI.Cyan
+white = ColorCode ANSI.Dull ANSI.White
 
+-- | Intensify an ANSI color.
+vivid :: Color -> Color
+vivid (ColorCode _ c) = ColorCode ANSI.Vivid c
+vivid c = c
+
+-- | Dull an ANSI color.
+dull :: Color -> Color
+dull (ColorCode _ c) = ColorCode ANSI.Dull c
+dull c = c
+
 -- | Specify a color using a RGB triplet where each component is in
 -- the range @[0 .. 255]@.  The actual rendered color will depend on
 -- the terminal.
@@ -81,7 +93,7 @@
 --
 -- @since 1.0.0.0
 colorAsANSI :: Color -> ANSI.Color
-colorAsANSI (ColorCode c) = c
+colorAsANSI (ColorCode _ c) = c
 colorAsANSI (ColorRGB c) = nearestColor c ansiColorLocations
 
 -- | Convert a Byline color to an index into a terminal 256-color palette.
@@ -89,7 +101,7 @@
 -- @since 1.0.0.0
 colorAsIndex256 :: Color -> Word8
 colorAsIndex256 = \case
-  ColorCode c -> ANSI.xtermSystem ANSI.Dull c
+  ColorCode i c -> ANSI.xtermSystem i c
   ColorRGB c -> nearestColor c term256Locations
 
 -- | Convert a Byline color to a 'C.Colour'.  If the color is
@@ -97,9 +109,9 @@
 -- instead.  This allows the terminal to pick the color on its own.
 --
 -- @since 1.0.0.0
-colorAsRGB :: Color -> Either ANSI.Color (C.Colour Float)
+colorAsRGB :: Color -> Either (ANSI.ColorIntensity, ANSI.Color) (C.Colour Float)
 colorAsRGB = \case
-  ColorCode c -> Left c
+  ColorCode i c -> Left (i,c)
   ColorRGB (r, g, b) -> Right (C.sRGB24 r g b)
 
 -- | Find the nearest color given a full RGB color.
diff --git a/src/Byline/Internal/Stylized.hs b/src/Byline/Internal/Stylized.hs
--- a/src/Byline/Internal/Stylized.hs
+++ b/src/Byline/Internal/Stylized.hs
@@ -43,8 +43,6 @@
 data Stylized a
   = -- | Something to stylize.
     Stylized Modifier a
-  | -- | Modify the next stylized value.
-    StylizedMod Modifier
   | -- | Multiple stylized values.
     StylizedList [Stylized a]
   deriving (Show, Eq, Functor, Foldable, Traversable)
@@ -53,15 +51,9 @@
 instance Semigroup (Stylized a) where
   -- StylizedText on LHS.
   (<>) a@(Stylized _ _) b@(Stylized _ _) = StylizedList [a, b]
-  (<>) (Stylized m t) (StylizedMod m') = Stylized (m <> m') t
   (<>) a@(Stylized _ _) (StylizedList b) = StylizedList (a : b)
-  -- StylizedMod on LHS.
-  (<>) (StylizedMod m) (Stylized m' t) = Stylized (m <> m') t
-  (<>) (StylizedMod m) (StylizedMod m') = StylizedMod (m <> m')
-  (<>) m@(StylizedMod _) (StylizedList l) = StylizedList (map (m <>) l)
   -- StylizedList on LHS.
   (<>) (StylizedList l) t@(Stylized _ _) = StylizedList (l <> [t])
-  (<>) (StylizedList l) m@(StylizedMod _) = StylizedList (map (<> m) l)
   (<>) (StylizedList l) (StylizedList l') = StylizedList (l <> l')
 
 -- | @since 1.0.0.0
@@ -100,32 +92,37 @@
 -- @
 --
 -- @since 1.0.0.0
-fg :: Color -> Stylized Text
-fg c = StylizedMod (mempty {modColorFG = OnlyOne (Just c)})
+fg :: Color -> Stylized Text -> Stylized Text
+fg c (Stylized m t) = Stylized (m {modColorFG = OnlyOne (Just c)}) t
+fg c (StylizedList l) = StylizedList (map (fg c) l)
 
 -- | Set the background color.
 --
 -- @since 1.0.0.0
-bg :: Color -> Stylized Text
-bg c = StylizedMod (mempty {modColorBG = OnlyOne (Just c)})
+bg :: Color -> Stylized Text -> Stylized Text
+bg c (Stylized m t) = Stylized (m {modColorBG = OnlyOne (Just c)}) t
+bg c (StylizedList l) = StylizedList (map (bg c) l)
 
 -- | Produce bold text.
 --
 -- @since 1.0.0.0
-bold :: Stylized Text
-bold = StylizedMod (mempty {modBold = On})
+bold :: Stylized Text -> Stylized Text
+bold (Stylized m t) = Stylized (m {modBold = On}) t
+bold (StylizedList l) = StylizedList (map bold l)
 
 -- | Produce underlined text.
 --
 -- @since 1.0.0.0
-underline :: Stylized Text
-underline = StylizedMod (mempty {modUnderline = On})
+underline :: Stylized Text -> Stylized Text
+underline (Stylized m t) = Stylized (m {modUnderline = On}) t
+underline (StylizedList l) = StylizedList (map underline l)
 
 -- | Produce swapped foreground/background text.
 --
 -- @since 1.0.0.0
-swapFgBg :: Stylized Text
-swapFgBg = StylizedMod (mempty {modSwapFgBg = On})
+swapFgBg :: Stylized Text -> Stylized Text
+swapFgBg (Stylized m t) = Stylized (m {modSwapFgBg = On}) t
+swapFgBg (StylizedList l) = StylizedList (map swapFgBg l)
 
 -- | How to render stylized text.
 --
@@ -181,7 +178,6 @@
 renderInstructions :: RenderMode -> Stylized Text -> [RenderInstruction]
 renderInstructions mode = \case
   Stylized m t -> renderMod mode (t, m)
-  StylizedMod _ -> []
   StylizedList xs -> concatMap (renderInstructions mode) xs
   where
     renderMod :: RenderMode -> (Text, Modifier) -> [RenderInstruction]
@@ -192,7 +188,9 @@
           [RenderText t]
         Simple ->
           -- Terminal supports basic 16 colors.
-          let color l = ANSI.SetColor l ANSI.Dull . Color.colorAsANSI
+          let color l c = case c of
+                Color.ColorCode ai ac -> ANSI.SetColor l ai ac
+                rgb -> ANSI.SetColor l ANSI.Dull (Color.colorAsANSI rgb)
            in renderToSGR t m color
         Term256 ->
           -- Terminal supports the 256-color palette.
@@ -201,7 +199,7 @@
         TermRGB ->
           -- Super terminal!
           let color l c = case Color.colorAsRGB c of
-                Left ac -> ANSI.SetColor l ANSI.Dull ac
+                Left (ai,ac) -> ANSI.SetColor l ai ac
                 Right rgb -> ANSI.SetRGBColor l rgb
            in renderToSGR t m color
     renderToSGR ::
diff --git a/src/Byline/Internal/Types.hs b/src/Byline/Internal/Types.hs
--- a/src/Byline/Internal/Types.hs
+++ b/src/Byline/Internal/Types.hs
@@ -33,7 +33,7 @@
 --
 -- @since 1.0.0.0
 data Color
-  = ColorCode ANSI.Color
+  = ColorCode ANSI.ColorIntensity ANSI.Color
   | ColorRGB (Word8, Word8, Word8)
   deriving (Show, Eq)
 
diff --git a/src/Byline/Shell.hs b/src/Byline/Shell.hs
--- a/src/Byline/Shell.hs
+++ b/src/Byline/Shell.hs
@@ -144,7 +144,7 @@
         then pure []
         else case Atto.parseOnly go input of
           Left e -> do
-            sayLn (("invalid input" <> fg red) <> ": " <> text (toText e))
+            sayLn (("invalid input" & fg red) <> ": " <> text (toText e))
             pure []
           Right ws ->
             pure ws
diff --git a/test/Main.hs b/test/Main.hs
--- a/test/Main.hs
+++ b/test/Main.hs
@@ -23,13 +23,13 @@
 
 example :: MonadByline m => m Text
 example = do
-  sayLn ("Hey, I like " <> ("Haskell" <> fg magenta) <> "!")
+  sayLn ("Hey, I like " <> ("Haskell" & fg magenta) <> "!")
 
   let question =
         "What's "
-          <> ("your" <> bold)
+          <> ("your" & bold)
           <> " favorite "
-          <> ("language" <> fg green <> underline)
+          <> ("language" & fg (vivid green) & underline)
           <> "? "
 
   askLn question (Just "Haskell")
