diff --git a/CHANGELOG.md b/CHANGELOG.md
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,6 +1,37 @@
 # Changelog for safe-coloured-text
 
-## [0.3.0.2] - 2024-03-26
+## [0.6.0.0] - 2026-05-13
+
+### Added
+
+* `chunkStyleHyperlink :: !(Maybe Text)` field in `ChunkStyle` for OSC 8 hyperlink URLs
+* `renderOsc8Open` and `renderOsc8Close` for emitting OSC 8 terminal hyperlink sequences
+* `renderChunkBuilder` now emits OSC 8 sequences when `chunkStyleHyperlink` is set
+
+## [0.5.0.0] - 2026-04-12
+
+### Changed
+
+* Separated styling from text: `Chunk` now has `chunkText` and `chunkStyle` fields
+* New `ChunkStyle` type holds all styling attributes (italic, bold, colours, etc.)
+* Styling field names now use `chunkStyle` prefix (e.g. `chunkStyleItalic`)
+* Added `noStyle` constructor and `plainStyle`, `styleSGR` functions
+* Renamed `chunkSGR` to `styleSGR`
+
+## [0.4.0.0] - 2026-04-12
+
+### Added
+
+* Strikethrough support (`chunkStrikethrough`, `strikethrough`, SGR 9/29)
+* Reverse video support (`chunkSwapForegroundBackground`, `swapForegroundBackground`, SGR 7/27)
+* Concealed/hidden text support (`chunkConcealed`, `concealed`, SGR 8/28)
+* Overline support (`chunkOverlined`, `overlined`, SGR 53/55)
+
+### Fixed
+
+* `chunkBlinking` is now rendered in `chunkSGR` (was stored but never emitted)
+
+## [0.3.0.2] - 2024-06-23
 
 ### Added
 
diff --git a/safe-coloured-text.cabal b/safe-coloured-text.cabal
--- a/safe-coloured-text.cabal
+++ b/safe-coloured-text.cabal
@@ -1,11 +1,11 @@
 cabal-version: 1.12
 
--- This file has been generated from package.yaml by hpack version 0.36.0.
+-- This file has been generated from package.yaml by hpack version 0.38.3.
 --
 -- see: https://github.com/sol/hpack
 
 name:           safe-coloured-text
-version:        0.3.0.2
+version:        0.6.0.0
 synopsis:       Safely output coloured text
 category:       User Interfaces
 homepage:       https://github.com/NorfairKing/safe-coloured-text#readme
diff --git a/src/Text/Colour.hs b/src/Text/Colour.hs
--- a/src/Text/Colour.hs
+++ b/src/Text/Colour.hs
@@ -9,6 +9,8 @@
   ( -- * Building chunks
     chunk,
     Chunk (..),
+    ChunkStyle (..),
+    noStyle,
 
     -- ** Styling
 
@@ -26,6 +28,10 @@
     bold,
     faint,
     italic,
+    strikethrough,
+    swapForegroundBackground,
+    concealed,
+    overlined,
     underline,
     doubleUnderline,
     noUnderline,
diff --git a/src/Text/Colour/Chunk.hs b/src/Text/Colour/Chunk.hs
--- a/src/Text/Colour/Chunk.hs
+++ b/src/Text/Colour/Chunk.hs
@@ -24,12 +24,7 @@
 
 data Chunk = Chunk
   { chunkText :: !Text,
-    chunkItalic :: !(Maybe Bool),
-    chunkConsoleIntensity :: !(Maybe ConsoleIntensity),
-    chunkUnderlining :: !(Maybe Underlining),
-    chunkBlinking :: !(Maybe Blinking),
-    chunkForeground :: !(Maybe Colour),
-    chunkBackground :: !(Maybe Colour)
+    chunkStyle :: !ChunkStyle
   }
   deriving (Show, Eq, Generic)
 
@@ -38,24 +33,53 @@
 instance IsString Chunk where
   fromString = chunk . fromString
 
+data ChunkStyle = ChunkStyle
+  { chunkStyleItalic :: !(Maybe Bool),
+    chunkStyleStrikethrough :: !(Maybe Bool),
+    chunkStyleSwapForegroundBackground :: !(Maybe Bool),
+    chunkStyleConcealed :: !(Maybe Bool),
+    chunkStyleOverlined :: !(Maybe Bool),
+    chunkStyleConsoleIntensity :: !(Maybe ConsoleIntensity),
+    chunkStyleUnderlining :: !(Maybe Underlining),
+    chunkStyleBlinking :: !(Maybe Blinking),
+    chunkStyleForeground :: !(Maybe Colour),
+    chunkStyleBackground :: !(Maybe Colour),
+    -- | OSC 8 hyperlink URL, if any.
+    -- Rendered as @ESC]8;;\<url\>ESC\\@ before the text and @ESC]8;;ESC\\@ after.
+    chunkStyleHyperlink :: !(Maybe Text)
+  }
+  deriving (Show, Eq, Generic)
+
+instance Validity ChunkStyle
+
 -- TODO This is not correct because text-width is correct but it's a
 -- good place to put this so we can fix it later and it'll get fixed
 -- everywhere.
 chunkWidth :: Chunk -> Int
 chunkWidth = T.length . chunkText
 
-plainChunk :: TerminalCapabilities -> Chunk -> Bool
-plainChunk tc Chunk {..} =
-  let Chunk _ _ _ _ _ _ _ = undefined
+plainStyle :: TerminalCapabilities -> ChunkStyle -> Bool
+plainStyle tc ChunkStyle {..} =
+  let ChunkStyle _ _ _ _ _ _ _ _ _ _ _ = undefined
    in and
-        [ isNothing chunkItalic,
-          isNothing chunkConsoleIntensity,
-          isNothing chunkUnderlining,
-          isNothing chunkBlinking,
-          maybe True (plainColour tc) chunkForeground,
-          maybe True (plainColour tc) chunkBackground
+        [ isNothing chunkStyleItalic,
+          isNothing chunkStyleStrikethrough,
+          isNothing chunkStyleSwapForegroundBackground,
+          isNothing chunkStyleConcealed,
+          isNothing chunkStyleOverlined,
+          isNothing chunkStyleConsoleIntensity,
+          isNothing chunkStyleUnderlining,
+          isNothing chunkStyleBlinking,
+          maybe True (plainColour tc) chunkStyleForeground,
+          maybe True (plainColour tc) chunkStyleBackground,
+          isNothing chunkStyleHyperlink
         ]
 
+plainChunk :: TerminalCapabilities -> Chunk -> Bool
+plainChunk tc Chunk {..} =
+  let Chunk _ _ = undefined
+   in plainStyle tc chunkStyle
+
 plainColour :: TerminalCapabilities -> Colour -> Bool
 plainColour tc = \case
   Colour8 {} -> tc < With8Colours
@@ -105,19 +129,40 @@
     then LTB.fromText chunkText
     else
       mconcat
-        [ renderCSI (SGR (chunkSGR tc c)),
+        [ maybe mempty renderOsc8Open (chunkStyleHyperlink chunkStyle),
+          renderCSI (SGR (styleSGR tc chunkStyle)),
           LTB.fromText chunkText,
-          renderCSI (SGR [Reset])
+          renderCSI (SGR [Reset]),
+          maybe mempty (const renderOsc8Close) (chunkStyleHyperlink chunkStyle)
         ]
 
-chunkSGR :: TerminalCapabilities -> Chunk -> [SGR]
-chunkSGR tc Chunk {..} =
+-- | Render an OSC 8 hyperlink open sequence: @ESC]8;;<url>ESC\@.
+-- An empty URL renders the close sequence.
+renderOsc8Open :: Text -> Text.Builder
+renderOsc8Open url =
+  mconcat
+    [ LTB.fromText (T.pack "\ESC]8;;"),
+      LTB.fromText url,
+      LTB.fromText (T.pack "\ESC\\")
+    ]
+
+-- | Render an OSC 8 hyperlink close sequence: @ESC]8;;ESC\@.
+renderOsc8Close :: Text.Builder
+renderOsc8Close = LTB.fromText (T.pack "\ESC]8;;\ESC\\")
+
+styleSGR :: TerminalCapabilities -> ChunkStyle -> [SGR]
+styleSGR tc ChunkStyle {..} =
   catMaybes
-    [ SetItalic <$> chunkItalic,
-      SetUnderlining <$> chunkUnderlining,
-      SetConsoleIntensity <$> chunkConsoleIntensity,
-      chunkForeground >>= colourSGR tc Foreground,
-      chunkBackground >>= colourSGR tc Background
+    [ SetItalic <$> chunkStyleItalic,
+      SetStrikethrough <$> chunkStyleStrikethrough,
+      SetSwapForegroundBackground <$> chunkStyleSwapForegroundBackground,
+      SetConcealed <$> chunkStyleConcealed,
+      SetOverlined <$> chunkStyleOverlined,
+      SetUnderlining <$> chunkStyleUnderlining,
+      SetBlinking <$> chunkStyleBlinking,
+      SetConsoleIntensity <$> chunkStyleConsoleIntensity,
+      chunkStyleForeground >>= colourSGR tc Foreground,
+      chunkStyleBackground >>= colourSGR tc Background
     ]
 
 -- | Turn a text into a plain chunk, without any styling
@@ -125,46 +170,70 @@
 chunk t =
   Chunk
     { chunkText = t,
-      chunkItalic = Nothing,
-      chunkConsoleIntensity = Nothing,
-      chunkUnderlining = Nothing,
-      chunkBlinking = Nothing,
-      chunkForeground = Nothing,
-      chunkBackground = Nothing
+      chunkStyle = noStyle
     }
 
+-- | The empty style, without any styling
+noStyle :: ChunkStyle
+noStyle =
+  ChunkStyle
+    { chunkStyleItalic = Nothing,
+      chunkStyleStrikethrough = Nothing,
+      chunkStyleSwapForegroundBackground = Nothing,
+      chunkStyleConcealed = Nothing,
+      chunkStyleOverlined = Nothing,
+      chunkStyleConsoleIntensity = Nothing,
+      chunkStyleUnderlining = Nothing,
+      chunkStyleBlinking = Nothing,
+      chunkStyleForeground = Nothing,
+      chunkStyleBackground = Nothing,
+      chunkStyleHyperlink = Nothing
+    }
+
 fore :: Colour -> Chunk -> Chunk
-fore col chu = chu {chunkForeground = Just col}
+fore col chu = chu {chunkStyle = (chunkStyle chu) {chunkStyleForeground = Just col}}
 
 back :: Colour -> Chunk -> Chunk
-back col chu = chu {chunkBackground = Just col}
+back col chu = chu {chunkStyle = (chunkStyle chu) {chunkStyleBackground = Just col}}
 
 bold :: Chunk -> Chunk
-bold chu = chu {chunkConsoleIntensity = Just BoldIntensity}
+bold chu = chu {chunkStyle = (chunkStyle chu) {chunkStyleConsoleIntensity = Just BoldIntensity}}
 
 faint :: Chunk -> Chunk
-faint chu = chu {chunkConsoleIntensity = Just FaintIntensity}
+faint chu = chu {chunkStyle = (chunkStyle chu) {chunkStyleConsoleIntensity = Just FaintIntensity}}
 
 italic :: Chunk -> Chunk
-italic chu = chu {chunkItalic = Just True}
+italic chu = chu {chunkStyle = (chunkStyle chu) {chunkStyleItalic = Just True}}
 
+strikethrough :: Chunk -> Chunk
+strikethrough chu = chu {chunkStyle = (chunkStyle chu) {chunkStyleStrikethrough = Just True}}
+
+swapForegroundBackground :: Chunk -> Chunk
+swapForegroundBackground chu = chu {chunkStyle = (chunkStyle chu) {chunkStyleSwapForegroundBackground = Just True}}
+
+concealed :: Chunk -> Chunk
+concealed chu = chu {chunkStyle = (chunkStyle chu) {chunkStyleConcealed = Just True}}
+
+overlined :: Chunk -> Chunk
+overlined chu = chu {chunkStyle = (chunkStyle chu) {chunkStyleOverlined = Just True}}
+
 underline :: Chunk -> Chunk
-underline chu = chu {chunkUnderlining = Just SingleUnderline}
+underline chu = chu {chunkStyle = (chunkStyle chu) {chunkStyleUnderlining = Just SingleUnderline}}
 
 doubleUnderline :: Chunk -> Chunk
-doubleUnderline chu = chu {chunkUnderlining = Just DoubleUnderline}
+doubleUnderline chu = chu {chunkStyle = (chunkStyle chu) {chunkStyleUnderlining = Just DoubleUnderline}}
 
 noUnderline :: Chunk -> Chunk
-noUnderline chu = chu {chunkUnderlining = Just NoUnderline}
+noUnderline chu = chu {chunkStyle = (chunkStyle chu) {chunkStyleUnderlining = Just NoUnderline}}
 
 slowBlinking :: Chunk -> Chunk
-slowBlinking chu = chu {chunkBlinking = Just SlowBlinking}
+slowBlinking chu = chu {chunkStyle = (chunkStyle chu) {chunkStyleBlinking = Just SlowBlinking}}
 
 rapidBlinking :: Chunk -> Chunk
-rapidBlinking chu = chu {chunkBlinking = Just RapidBlinking}
+rapidBlinking chu = chu {chunkStyle = (chunkStyle chu) {chunkStyleBlinking = Just RapidBlinking}}
 
 noBlinking :: Chunk -> Chunk
-noBlinking chu = chu {chunkBlinking = Just NoBlinking}
+noBlinking chu = chu {chunkStyle = (chunkStyle chu) {chunkStyleBlinking = Just NoBlinking}}
 
 -- TODO consider allowing an 8-colour alternative to a given 256-colour
 data Colour
diff --git a/src/Text/Colour/Code.hs b/src/Text/Colour/Code.hs
--- a/src/Text/Colour/Code.hs
+++ b/src/Text/Colour/Code.hs
@@ -71,6 +71,10 @@
 data SGR
   = Reset
   | SetItalic !Bool
+  | SetStrikethrough !Bool
+  | SetSwapForegroundBackground !Bool
+  | SetConcealed !Bool
+  | SetOverlined !Bool
   | SetUnderlining !Underlining
   | SetBlinking !Blinking
   | SetConsoleIntensity !ConsoleIntensity
@@ -95,6 +99,10 @@
 sgrToCSIParams = \case
   Reset -> [] -- [0] would be fine too
   SetItalic b -> [if b then 3 else 23]
+  SetStrikethrough b -> [if b then 9 else 29]
+  SetSwapForegroundBackground b -> [if b then 7 else 27]
+  SetConcealed b -> [if b then 8 else 28]
+  SetOverlined b -> [if b then 53 else 55]
   SetUnderlining u ->
     [ case u of
         SingleUnderline -> 4
