diff --git a/src/assets/icons/arrow-down-left.svg b/src/assets/icons/arrow-down-left.svg
new file mode 100644
index 0000000000..2bb4c0ea3e
--- /dev/null
+++ b/src/assets/icons/arrow-down-left.svg
@@ -0,0 +1,3 @@
+
+
+
diff --git a/src/assets/icons/arrow-up-right.svg b/src/assets/icons/arrow-up-right.svg
new file mode 100644
index 0000000000..7bd7561cb1
--- /dev/null
+++ b/src/assets/icons/arrow-up-right.svg
@@ -0,0 +1,3 @@
+
+
+
diff --git a/src/assets/icons/pen-line.svg b/src/assets/icons/pen-line.svg
new file mode 100644
index 0000000000..e0eeac96dc
--- /dev/null
+++ b/src/assets/icons/pen-line.svg
@@ -0,0 +1,3 @@
+
+
+
diff --git a/src/assets/icons/xmark.svg b/src/assets/icons/xmark.svg
new file mode 100644
index 0000000000..4cd569406a
--- /dev/null
+++ b/src/assets/icons/xmark.svg
@@ -0,0 +1,3 @@
+
+
+
diff --git a/src/pages/components.mdx b/src/pages/components.mdx
index cdbd4b1fd7..813eb4e103 100644
--- a/src/pages/components.mdx
+++ b/src/pages/components.mdx
@@ -250,6 +250,60 @@ Two of them sit side by side below, each with its own menu, so it is clear that
+### API method badge
+
+A badge marks a piece of documentation with the HTTP method it describes. Each
+method carries its own icon and colour, in both light and dark themes.
+
+There is no component to import. The styles live in `src/styles/api.css`, which
+every page loads, so this works in `.md` as well as `.mdx`.
+
+One class does the work: `api-get`, `api-post`, `api-delete` or `api-put`. It
+carries the colours and draws the icon from a `::before`, so the only thing to
+write is the label.
+
+
+
+ Get
+ Post
+ Delete
+ Put
+
+
+ ```html
+ Get
+ Post
+ Delete
+ Put
+ ```
+
+
+
+#### Icon only
+
+Add `api-icon-only` for the icon on its own. There is no text left to read, so
+name it with `role="img"` and an `aria-label`.
+
+
+
+
+
+
+
+
+
+ ```html
+
+
+
+
+ ```
+
+
+
+The badge is `inline-flex`, so it sits inside a heading or a paragraph as well
+as it does on its own.
+
### TopNav
Temporary showcase for the new, work-in-progress TopNav component.
diff --git a/src/styles/api.css b/src/styles/api.css
new file mode 100644
index 0000000000..db2a269d7d
--- /dev/null
+++ b/src/styles/api.css
@@ -0,0 +1,82 @@
+:is(.api-get, .api-post, .api-delete, .api-put) {
+ box-sizing: border-box;
+ display: inline-flex;
+ align-items: center;
+ justify-content: center;
+ gap: var(--space4);
+ padding-block: calc(var(--space2) - var(--borderWidth1));
+ padding-inline: calc(var(--space2) - var(--borderWidth1))
+ calc(var(--space4) - var(--borderWidth1));
+ border: var(--borderWidth1) solid;
+ border-radius: var(--borderRadiusSmall);
+ max-width: fit-content;
+ font-family: var(--fontFamilySystem-ui-monospace);
+ font-size: var(--fontSizeXSmall);
+ font-weight: 400;
+ line-height: var(--lineHeightXSmall);
+ letter-spacing: var(--letterSpacingNone);
+ vertical-align: middle;
+ white-space: nowrap;
+}
+
+:is(.api-get, .api-post, .api-delete, .api-put)::before {
+ content: '';
+ flex-shrink: 0;
+ width: 1rem;
+ height: 1rem;
+ background-color: currentColor;
+ mask-position: center;
+ mask-repeat: no-repeat;
+}
+
+.api-icon-only {
+ padding-inline-end: calc(var(--space2) - var(--borderWidth1));
+}
+
+.api-get {
+ border-color: var(--colorApiBadgeBorderGet);
+ background: var(--colorApiBadgeBackgroundGet);
+ color: var(--colorApiBadgeTextGet);
+}
+
+.api-get::before {
+ background-color: var(--colorApiBadgeIconGet);
+ mask-image: url('../assets/icons/arrow-down-left.svg');
+ mask-size: 60%;
+}
+
+.api-post {
+ border-color: var(--colorApiBadgeBorderPost);
+ background: var(--colorApiBadgeBackgroundPost);
+ color: var(--colorApiBadgeTextPost);
+}
+
+.api-post::before {
+ background-color: var(--colorApiBadgeIconPost);
+ mask-image: url('../assets/icons/arrow-up-right.svg');
+ mask-size: 60%;
+}
+
+.api-delete {
+ border-color: var(--colorApiBadgeBorderDelete);
+ background: var(--colorApiBadgeBackgroundDelete);
+ color: var(--colorApiBadgeTextDelete);
+}
+
+.api-delete::before {
+ background-color: var(--colorApiBadgeIconDelete);
+ mask-image: url('../assets/icons/xmark.svg');
+ mask-size: 50%;
+}
+
+.api-put {
+ border-color: var(--colorApiBadgeBorderPut);
+ background: var(--colorApiBadgeBackgroundPut);
+ color: var(--colorApiBadgeTextPut);
+}
+
+.api-put::before {
+ background-color: var(--colorApiBadgeIconPut);
+ mask-image: url('../assets/icons/pen-line.svg');
+ mask-size: 90% 80%;
+}
diff --git a/src/styles/vars.css b/src/styles/vars.css
index 575ed8560d..86b91d5989 100644
--- a/src/styles/vars.css
+++ b/src/styles/vars.css
@@ -228,10 +228,29 @@
--standard-radius: 0.5rem;
- /* TODO: drop these once color.nav.background.* are available in design-system-tokens */
--colorNavBackgroundRest: rgb(from var(--colorScalesBlue500) r g b / 0);
--colorNavBackgroundHover: var(--colorScalesSlate100);
--colorNavBackgroundActive: rgb(from var(--colorScalesBlue500) r g b / 0.06);
+
+ --colorApiBadgeBackgroundGet: var(--colorScalesGreen100);
+ --colorApiBadgeBorderGet: var(--colorScalesGreen200);
+ --colorApiBadgeIconGet: var(--colorScalesGreen600);
+ --colorApiBadgeTextGet: var(--colorScalesGreen600);
+
+ --colorApiBadgeBackgroundPost: var(--colorScalesBlue100);
+ --colorApiBadgeBorderPost: var(--colorScalesBlue200);
+ --colorApiBadgeIconPost: var(--colorScalesBlue600);
+ --colorApiBadgeTextPost: var(--colorScalesBlue600);
+
+ --colorApiBadgeBackgroundDelete: var(--colorScalesRed100);
+ --colorApiBadgeBorderDelete: var(--colorScalesRed200);
+ --colorApiBadgeIconDelete: var(--colorScalesRed600);
+ --colorApiBadgeTextDelete: var(--colorScalesRed600);
+
+ --colorApiBadgeBackgroundPut: var(--colorScalesYellow100);
+ --colorApiBadgeBorderPut: var(--colorScalesYellow200);
+ --colorApiBadgeIconPut: var(--colorScalesYellow600);
+ --colorApiBadgeTextPut: var(--colorScalesYellow600);
}
:root[data-theme-transition] {
@@ -274,6 +293,25 @@ html[data-theme='dark'] {
/* Tiles sit one step above the page so hover has somewhere lighter to go */
--icon-tile-background-hover: var(--colorBackgroundTertiary);
- /* TODO: drop once color.nav.background.* are available in design-system-tokens */
--colorNavBackgroundHover: var(--colorScalesNavy800);
+
+ --colorApiBadgeBackgroundGet: var(--colorScalesGreen900);
+ --colorApiBadgeBorderGet: var(--colorScalesGreen700);
+ --colorApiBadgeIconGet: var(--colorScalesGreen300);
+ --colorApiBadgeTextGet: var(--colorScalesGreen300);
+
+ --colorApiBadgeBackgroundPost: var(--colorScalesBlue900);
+ --colorApiBadgeBorderPost: var(--colorScalesBlue700);
+ --colorApiBadgeIconPost: var(--colorScalesBlue300);
+ --colorApiBadgeTextPost: var(--colorScalesBlue300);
+
+ --colorApiBadgeBackgroundDelete: var(--colorScalesRed900);
+ --colorApiBadgeBorderDelete: var(--colorScalesRed700);
+ --colorApiBadgeIconDelete: var(--colorScalesRed300);
+ --colorApiBadgeTextDelete: var(--colorScalesRed300);
+
+ --colorApiBadgeBackgroundPut: var(--colorScalesYellow900);
+ --colorApiBadgeBorderPut: var(--colorScalesYellow700);
+ --colorApiBadgeIconPut: var(--colorScalesYellow300);
+ --colorApiBadgeTextPut: var(--colorScalesYellow300);
}
diff --git a/src/themes/octopus/components/HtmlHead.astro b/src/themes/octopus/components/HtmlHead.astro
index 0bec4b49d4..0c9a835a86 100644
--- a/src/themes/octopus/components/HtmlHead.astro
+++ b/src/themes/octopus/components/HtmlHead.astro
@@ -21,6 +21,7 @@ import '@octopusdeploy/design-system-tokens/css/darkTheme.css';
// cached across deploys.
import '../../../styles/vars.css';
import '../../../styles/main.css';
+import '../../../styles/api.css';
const stats = new accelerator.statistics('octopus/components/HtmlHead.astro');
stats.start();