diff --git a/.changeset/old-trees-compare.md b/.changeset/old-trees-compare.md
new file mode 100644
index 000000000..067be8dc1
--- /dev/null
+++ b/.changeset/old-trees-compare.md
@@ -0,0 +1,5 @@
+---
+'@cloudfour/patterns': minor
+---
+
+Add CSS text utility classes
diff --git a/src/utilities/text/demo/color.twig b/src/utilities/text/demo/color.twig
new file mode 100644
index 000000000..cf19ccdd6
--- /dev/null
+++ b/src/utilities/text/demo/color.twig
@@ -0,0 +1,8 @@
+{% embed '@cloudfour/objects/container/container.twig' with {
+ class: 'o-container--pad'
+} only %}
+ {% block content %}
+
This is default text.
+ This is text that has the utility class applied.
+ {% endblock %}
+{% endembed %}
diff --git a/src/utilities/text/demo/nowrap.twig b/src/utilities/text/demo/nowrap.twig
new file mode 100644
index 000000000..7e3877183
--- /dev/null
+++ b/src/utilities/text/demo/nowrap.twig
@@ -0,0 +1,24 @@
+{% embed '@cloudfour/objects/container/container.twig' with {
+ class: 'o-container--pad'
+} only %}
+ {% block content %}
+
+
+
This text will wrap: The quick brown
+fox jumps over the lazy dog.
+
+
+ {% endblock %}
+{% endembed %}
+{% embed '@cloudfour/objects/container/container.twig' with {
+ class: 'o-container--pad'
+} only %}
+ {% block content %}
+
+
+
This text will not wrap: The quick brown
+fox jumps over the lazy dog.
+
+
+ {% endblock %}
+{% endembed %}
diff --git a/src/utilities/text/text.scss b/src/utilities/text/text.scss
new file mode 100644
index 000000000..51fe17cda
--- /dev/null
+++ b/src/utilities/text/text.scss
@@ -0,0 +1,9 @@
+@use "../../compiled/tokens/scss/color";
+
+.u-text-no-wrap {
+ white-space: nowrap !important;
+}
+
+.u-text-action {
+ color: var(--theme-color-text-action) !important;
+}
diff --git a/src/utilities/text/text.stories.mdx b/src/utilities/text/text.stories.mdx
new file mode 100644
index 000000000..50f84e886
--- /dev/null
+++ b/src/utilities/text/text.stories.mdx
@@ -0,0 +1,59 @@
+import { Story, Canvas, Meta } from '@storybook/addon-docs/blocks';
+// The '!!raw-loader!' syntax is a non-standard, Webpack-specific, syntax.
+// See: https://github.com/webpack-contrib/raw-loader#examples
+// For now, it seems likely Storybook is pretty tied to Webpack, therefore, we are
+// okay with the following Webpack-specific raw loader syntax. It's better to leave
+// the ESLint rule enabled globally, and only thoughtfully disable as needed (e.g.
+// within a Storybook docs page and not within an actual component).
+// This can be revisited in the future if Storybook no longer relies on Webpack.
+// eslint-disable-next-line @cloudfour/import/no-webpack-loader-syntax
+import noWrapDemoSource from '!!raw-loader!./demo/nowrap.twig';
+import noWrapDemo from './demo/nowrap.twig';
+// The '!!raw-loader!' syntax is a non-standard, Webpack-specific, syntax.
+// See: https://github.com/webpack-contrib/raw-loader#examples
+// For now, it seems likely Storybook is pretty tied to Webpack, therefore, we are
+// okay with the following Webpack-specific raw loader syntax. It's better to leave
+// the ESLint rule enabled globally, and only thoughtfully disable as needed (e.g.
+// within a Storybook docs page and not within an actual component).
+// This can be revisited in the future if Storybook no longer relies on Webpack.
+// eslint-disable-next-line @cloudfour/import/no-webpack-loader-syntax
+import colorDemoSource from '!!raw-loader!./demo/color.twig';
+import colorDemo from './demo/color.twig';
+
+
+
+# Text
+
+Utilities for controlling text properties.
+
+## White-space nowrap
+
+- `u-text-no-wrap`
+
+Utility for controlling the white-space wrapping of text, applies `white-space: nowrap`.
+
+Notice in the second example how the `some-long-text` text doesn't wrap.
+
+
+
+## Action text
+
+- `u-text-action`
+
+Utility that changes the text color to the "action" text color.
+
+