From b333d8f4cb1b83a0fac1b334ab95ba25f60de4c4 Mon Sep 17 00:00:00 2001 From: MartinS-git Date: Mon, 8 Jun 2026 14:54:51 +0200 Subject: [PATCH 01/21] =?UTF-8?q?feat(ui):=20add=20h1=E2=80=93h6=20base=20?= =?UTF-8?q?typography=20styles=20to=20global.css?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Implements the Juno typography scale for heading elements h1–h6 in the @layer base section of global.css. Styles follow the defined spec: IBM Plex Sans, weight 700, with rem-based font sizes and leading values aligned to Tailwind's leading-snug (h1–h3), leading-relaxed (h4–h5), and leading-normal (h6). Closes #1737 Signed-off-by: MartinS-git --- packages/ui-components/src/global.css | 40 +++++++++++++++++++++++++++ 1 file changed, 40 insertions(+) diff --git a/packages/ui-components/src/global.css b/packages/ui-components/src/global.css index 0765870951..78a2ddb80a 100644 --- a/packages/ui-components/src/global.css +++ b/packages/ui-components/src/global.css @@ -1052,6 +1052,46 @@ @apply jn:text-theme-link; } + h1, + h2, + h3, + h4, + h5, + h6 { + @apply jn:font-sans; + font-weight: 700; + } + + h1 { + font-size: 1.69rem; + line-height: 1.375; + } + + h2 { + font-size: 1.56rem; + line-height: 1.375; + } + + h3 { + font-size: 1.44rem; + line-height: 1.375; + } + + h4 { + font-size: 1.28rem; + line-height: 1.625; + } + + h5 { + font-size: 1.125rem; + line-height: 1.625; + } + + h6 { + font-size: 1rem; + line-height: 1.5; + } + /* adds pointer cursor to buttons to restore tw3 behavior */ button:not(:disabled), [role="button"]:not(:disabled) { From 6c58a32e9be7f142726c24b8e39b998319cff246 Mon Sep 17 00:00:00 2001 From: MartinS-git Date: Mon, 8 Jun 2026 15:05:15 +0200 Subject: [PATCH 02/21] =?UTF-8?q?feat(ui):=20add=20h1=E2=80=93h6=20base=20?= =?UTF-8?q?typography=20styles=20to=20theme.css?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: MartinS-git --- packages/ui-components/src/theme.css | 40 ++++++++++++++++++++++++++++ 1 file changed, 40 insertions(+) diff --git a/packages/ui-components/src/theme.css b/packages/ui-components/src/theme.css index f81b5234c0..71e0fb8c79 100644 --- a/packages/ui-components/src/theme.css +++ b/packages/ui-components/src/theme.css @@ -1122,3 +1122,43 @@ --tw-content: ""; } } + +h1, +h2, +h3, +h4, +h5, +h6 { + font-family: "IBM Plex Sans", ui-sans-serif, Arial, system-ui, sans-serif; + font-weight: 700; +} + +h1 { + font-size: 1.69rem; + line-height: 1.375; +} + +h2 { + font-size: 1.56rem; + line-height: 1.375; +} + +h3 { + font-size: 1.44rem; + line-height: 1.375; +} + +h4 { + font-size: 1.28rem; + line-height: 1.625; +} + +h5 { + font-size: 1.125rem; + line-height: 1.625; +} + +h6 { + font-size: 1rem; + line-height: 1.5; +} From 26d2e5884947b14fdf638f1c7d4e7405cf73cf46 Mon Sep 17 00:00:00 2001 From: MartinS-git Date: Mon, 8 Jun 2026 15:10:32 +0200 Subject: [PATCH 03/21] =?UTF-8?q?refactor(ui):=20replace=20line-height=20v?= =?UTF-8?q?alues=20with=20Tailwind=20leading=20utilities=20in=20h1?= =?UTF-8?q?=E2=80=93h6?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: MartinS-git --- packages/ui-components/src/global.css | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/packages/ui-components/src/global.css b/packages/ui-components/src/global.css index 78a2ddb80a..3c780a5c2f 100644 --- a/packages/ui-components/src/global.css +++ b/packages/ui-components/src/global.css @@ -1064,32 +1064,32 @@ h1 { font-size: 1.69rem; - line-height: 1.375; + @apply jn:leading-snug; } h2 { font-size: 1.56rem; - line-height: 1.375; + @apply jn:leading-snug; } h3 { font-size: 1.44rem; - line-height: 1.375; + @apply jn:leading-snug; } h4 { font-size: 1.28rem; - line-height: 1.625; + @apply jn:leading-relaxed; } h5 { font-size: 1.125rem; - line-height: 1.625; + @apply jn:leading-relaxed; } h6 { font-size: 1rem; - line-height: 1.5; + @apply jn:leading-normal; } /* adds pointer cursor to buttons to restore tw3 behavior */ From 11434dcd9859eee003c9f449505ccb274b57b25a Mon Sep 17 00:00:00 2001 From: MartinS-git Date: Mon, 8 Jun 2026 15:20:01 +0200 Subject: [PATCH 04/21] feat(ui): align FormattedText heading styles with typography scale MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Update h1–h6 in formatted-text.css to match the defined typography scale: - Align font-size and line-height with global.css values - Fix h5 font-size (1.03rem → 1.125rem) - Remove redundant font-weight and font-style declarations - Add missing h6 style Closes #1737 Signed-off-by: MartinS-git --- .../FormattedText/formatted-text.css | 24 +++++++++---------- 1 file changed, 11 insertions(+), 13 deletions(-) diff --git a/packages/ui-components/src/components/FormattedText/formatted-text.css b/packages/ui-components/src/components/FormattedText/formatted-text.css index 68d5bddfec..e742863f5d 100644 --- a/packages/ui-components/src/components/FormattedText/formatted-text.css +++ b/packages/ui-components/src/components/FormattedText/formatted-text.css @@ -36,42 +36,40 @@ h1 { font-size: 1.69rem; - font-weight: 700; - line-height: 1.11; /* round(40 / 36) */ + line-height: 1.375; /* leading-snug */ margin-top: 0; margin-bottom: 2rem; /* rem(32) */ } h2 { font-size: 1.56rem; - font-weight: 700; - line-height: 160%; + line-height: 1.375; /* leading-snug */ margin-top: 3rem; /* rem(48) */ margin-bottom: 1.5rem; /* rem(24) */ } h3 { font-size: 1.44rem; - font-weight: 700; - line-height: 160%; + line-height: 1.375; /* leading-snug */ margin-top: 1rem; margin-bottom: 0.75rem; /* rem(12) */ } h4 { font-size: 1.28rem; - font-style: normal; - font-weight: 700; - line-height: 160%; + line-height: 1.625; /* leading-relaxed */ margin-top: 1.5rem; /* rem(24) */ margin-bottom: 0.5rem; /* rem(8) */ } h5 { - font-size: 1.03rem; - font-style: normal; - font-weight: 700; - line-height: 160%; + font-size: 1.125rem; + line-height: 1.625; /* leading-relaxed */ + } + + h6 { + font-size: 1rem; + line-height: 1.5; /* leading-normal */ } img, From 72c66a44d0f93a4f8f9262a1963f1a3a48cf8bc6 Mon Sep 17 00:00:00 2001 From: MartinS-git Date: Mon, 8 Jun 2026 15:22:19 +0200 Subject: [PATCH 05/21] chore: add changeset for typography scale headings Signed-off-by: MartinS-git --- .changeset/typography-scale-headings.md | 5 +++++ 1 file changed, 5 insertions(+) create mode 100644 .changeset/typography-scale-headings.md diff --git a/.changeset/typography-scale-headings.md b/.changeset/typography-scale-headings.md new file mode 100644 index 0000000000..49879d43bd --- /dev/null +++ b/.changeset/typography-scale-headings.md @@ -0,0 +1,5 @@ +--- +"@cloudoperators/juno-ui-components": minor +--- + +Add h1–h6 base typography styles aligned with the Juno design system scale. Headings now have defined font-size and line-height values in `@layer base` (global.css), theme.css, and FormattedText. From 1d6fc704aae6cbae48bebe15d0508fcd6572d406 Mon Sep 17 00:00:00 2001 From: MartinS-git Date: Mon, 8 Jun 2026 16:33:30 +0200 Subject: [PATCH 06/21] =?UTF-8?q?refactor(ui):=20move=20h1=E2=80=93h6=20in?= =?UTF-8?q?to=20@layer=20base=20and=20use=20var(--font-sans)=20in=20theme.?= =?UTF-8?q?css?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: MartinS-git --- packages/ui-components/src/theme.css | 66 ++++++++++++++-------------- 1 file changed, 34 insertions(+), 32 deletions(-) diff --git a/packages/ui-components/src/theme.css b/packages/ui-components/src/theme.css index 71e0fb8c79..b7a81d5b6d 100644 --- a/packages/ui-components/src/theme.css +++ b/packages/ui-components/src/theme.css @@ -1123,42 +1123,44 @@ } } -h1, -h2, -h3, -h4, -h5, -h6 { - font-family: "IBM Plex Sans", ui-sans-serif, Arial, system-ui, sans-serif; - font-weight: 700; -} +@layer base { + h1, + h2, + h3, + h4, + h5, + h6 { + font-family: var(--font-sans); + font-weight: 700; + } -h1 { - font-size: 1.69rem; - line-height: 1.375; -} + h1 { + font-size: 1.69rem; + line-height: 1.375; + } -h2 { - font-size: 1.56rem; - line-height: 1.375; -} + h2 { + font-size: 1.56rem; + line-height: 1.375; + } -h3 { - font-size: 1.44rem; - line-height: 1.375; -} + h3 { + font-size: 1.44rem; + line-height: 1.375; + } -h4 { - font-size: 1.28rem; - line-height: 1.625; -} + h4 { + font-size: 1.28rem; + line-height: 1.625; + } -h5 { - font-size: 1.125rem; - line-height: 1.625; -} + h5 { + font-size: 1.125rem; + line-height: 1.625; + } -h6 { - font-size: 1rem; - line-height: 1.5; + h6 { + font-size: 1rem; + line-height: 1.5; + } } From 4a60bfeeb43c7269cfade6b3a193bf513123a03d Mon Sep 17 00:00:00 2001 From: MartinS-git Date: Wed, 10 Jun 2026 11:06:55 +0200 Subject: [PATCH 07/21] fix(ui): remove font-bold and text-lg overrides from ContentHeading MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ContentHeading renders an h1 — now that h1–h6 base styles are defined in @layer base (global.css), the explicit jn:text-lg (1.125rem) was overriding the intended h1 size (1.69rem). Removing both overrides lets the base typography scale apply correctly. Signed-off-by: MartinS-git --- .../src/components/ContentHeading/ContentHeading.component.tsx | 2 -- 1 file changed, 2 deletions(-) diff --git a/packages/ui-components/src/components/ContentHeading/ContentHeading.component.tsx b/packages/ui-components/src/components/ContentHeading/ContentHeading.component.tsx index 87aaf3a080..cf22f9c7d1 100644 --- a/packages/ui-components/src/components/ContentHeading/ContentHeading.component.tsx +++ b/packages/ui-components/src/components/ContentHeading/ContentHeading.component.tsx @@ -6,8 +6,6 @@ import React, { HTMLAttributes, ReactNode } from "react" const baseHeadingStyles = ` - jn:font-bold - jn:text-lg jn:text-theme-high jn:pb-2 ` From 90adb97fb13830b61a9798321eb7ccfceed4da4d Mon Sep 17 00:00:00 2001 From: MartinS-git Date: Wed, 10 Jun 2026 11:12:15 +0200 Subject: [PATCH 08/21] chore: update changeset with full list of typography changes Signed-off-by: MartinS-git --- .changeset/typography-scale-headings.md | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/.changeset/typography-scale-headings.md b/.changeset/typography-scale-headings.md index 49879d43bd..9ec5cb66aa 100644 --- a/.changeset/typography-scale-headings.md +++ b/.changeset/typography-scale-headings.md @@ -2,4 +2,8 @@ "@cloudoperators/juno-ui-components": minor --- -Add h1–h6 base typography styles aligned with the Juno design system scale. Headings now have defined font-size and line-height values in `@layer base` (global.css), theme.css, and FormattedText. +Add h1–h6 base typography styles aligned with the Juno design system scale. + +- `global.css` and `theme.css`: h1–h6 defined in `@layer base` with IBM Plex Sans Bold, rem font sizes, and Tailwind leading utilities. `theme.css` uses `var(--font-sans)` instead of a hardcoded font stack. +- `FormattedText`: heading sizes and line-heights aligned with the scale; h5 corrected (1.03rem → 1.125rem); h6 added; redundant `font-weight`/`font-style` declarations removed. +- `ContentHeading`: removed `jn:font-bold` and `jn:text-lg` overrides that were overriding the h1 base style with a smaller size. From 7aac8879afc222033c058ad2fd88a44605adff71 Mon Sep 17 00:00:00 2001 From: MartinS-git Date: Wed, 10 Jun 2026 12:11:29 +0200 Subject: [PATCH 09/21] =?UTF-8?q?refactor(ui):=20replace=20@apply=20leadin?= =?UTF-8?q?g=20utilities=20with=20plain=20CSS=20in=20global.css=20h1?= =?UTF-8?q?=E2=80=93h6?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Consistent with theme.css and formatted-text.css which also use plain CSS values. Tailwind equivalent noted as comments. Signed-off-by: MartinS-git --- packages/ui-components/src/global.css | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/packages/ui-components/src/global.css b/packages/ui-components/src/global.css index 3c780a5c2f..d57a845c07 100644 --- a/packages/ui-components/src/global.css +++ b/packages/ui-components/src/global.css @@ -1064,32 +1064,32 @@ h1 { font-size: 1.69rem; - @apply jn:leading-snug; + line-height: 1.375; /* leading-snug */ } h2 { font-size: 1.56rem; - @apply jn:leading-snug; + line-height: 1.375; /* leading-snug */ } h3 { font-size: 1.44rem; - @apply jn:leading-snug; + line-height: 1.375; /* leading-snug */ } h4 { font-size: 1.28rem; - @apply jn:leading-relaxed; + line-height: 1.625; /* leading-relaxed */ } h5 { font-size: 1.125rem; - @apply jn:leading-relaxed; + line-height: 1.625; /* leading-relaxed */ } h6 { font-size: 1rem; - @apply jn:leading-normal; + line-height: 1.5; /* leading-normal */ } /* adds pointer cursor to buttons to restore tw3 behavior */ From 314d33024899cd6a8f72fb656a968c0afdee89e1 Mon Sep 17 00:00:00 2001 From: MartinS-git Date: Wed, 10 Jun 2026 12:21:55 +0200 Subject: [PATCH 10/21] =?UTF-8?q?chore(ui):=20remove=20Tailwind=20utility?= =?UTF-8?q?=20comments=20from=20h1=E2=80=93h6=20line-height=20values?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: MartinS-git --- .../src/components/FormattedText/formatted-text.css | 12 ++++++------ packages/ui-components/src/global.css | 12 ++++++------ 2 files changed, 12 insertions(+), 12 deletions(-) diff --git a/packages/ui-components/src/components/FormattedText/formatted-text.css b/packages/ui-components/src/components/FormattedText/formatted-text.css index e742863f5d..0ef051be29 100644 --- a/packages/ui-components/src/components/FormattedText/formatted-text.css +++ b/packages/ui-components/src/components/FormattedText/formatted-text.css @@ -36,40 +36,40 @@ h1 { font-size: 1.69rem; - line-height: 1.375; /* leading-snug */ + line-height: 1.375; margin-top: 0; margin-bottom: 2rem; /* rem(32) */ } h2 { font-size: 1.56rem; - line-height: 1.375; /* leading-snug */ + line-height: 1.375; margin-top: 3rem; /* rem(48) */ margin-bottom: 1.5rem; /* rem(24) */ } h3 { font-size: 1.44rem; - line-height: 1.375; /* leading-snug */ + line-height: 1.375; margin-top: 1rem; margin-bottom: 0.75rem; /* rem(12) */ } h4 { font-size: 1.28rem; - line-height: 1.625; /* leading-relaxed */ + line-height: 1.625; margin-top: 1.5rem; /* rem(24) */ margin-bottom: 0.5rem; /* rem(8) */ } h5 { font-size: 1.125rem; - line-height: 1.625; /* leading-relaxed */ + line-height: 1.625; } h6 { font-size: 1rem; - line-height: 1.5; /* leading-normal */ + line-height: 1.5; } img, diff --git a/packages/ui-components/src/global.css b/packages/ui-components/src/global.css index d57a845c07..78a2ddb80a 100644 --- a/packages/ui-components/src/global.css +++ b/packages/ui-components/src/global.css @@ -1064,32 +1064,32 @@ h1 { font-size: 1.69rem; - line-height: 1.375; /* leading-snug */ + line-height: 1.375; } h2 { font-size: 1.56rem; - line-height: 1.375; /* leading-snug */ + line-height: 1.375; } h3 { font-size: 1.44rem; - line-height: 1.375; /* leading-snug */ + line-height: 1.375; } h4 { font-size: 1.28rem; - line-height: 1.625; /* leading-relaxed */ + line-height: 1.625; } h5 { font-size: 1.125rem; - line-height: 1.625; /* leading-relaxed */ + line-height: 1.625; } h6 { font-size: 1rem; - line-height: 1.5; /* leading-normal */ + line-height: 1.5; } /* adds pointer cursor to buttons to restore tw3 behavior */ From 07a62e7b81cf3cc28a38e84dd0bfed442d2a3484 Mon Sep 17 00:00:00 2001 From: MartinS-git Date: Thu, 11 Jun 2026 07:59:41 +0200 Subject: [PATCH 11/21] fix(ui): replace h1 misuse in components with semantically correct elements MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Resolves accessibility regression caused by the global h1–h6 typography scale: components that used

for UI labels (titles, section headings) now rendered at 27px, which was not intended. Each element was reviewed for correct heading semantics: - Modal:

; removed jn:text-xl/font-bold overrides - Form:

; removed jn:text-2xl/font-bold overrides - FormSection:

; removed jn:text-lg/font-bold overrides - SignInForm:

; removed jn:text-xl/font-bold overrides - Message:

(alert title, not a navigable section) - IntroBox:

(info box, no heading outline needed) - PopupMenu:

(decorative menu section label) - ContentHeading:

unchanged (intentional page-level heading) Signed-off-by: MartinS-git --- .changeset/typography-scale-headings.md | 9 +++++++++ .../src/components/Form/Form.component.tsx | 4 +--- .../components/FormSection/FormSection.component.tsx | 4 +--- .../src/components/IntroBox/IntroBox.component.tsx | 2 +- .../src/components/Message/Message.component.tsx | 2 +- .../src/components/Modal/Modal.component.tsx | 11 +++-------- .../src/components/PopupMenu/PopupMenu.component.tsx | 2 +- .../components/SignInForm/SignInForm.component.tsx | 4 +--- 8 files changed, 18 insertions(+), 20 deletions(-) diff --git a/.changeset/typography-scale-headings.md b/.changeset/typography-scale-headings.md index 9ec5cb66aa..7f2fe0c8b0 100644 --- a/.changeset/typography-scale-headings.md +++ b/.changeset/typography-scale-headings.md @@ -7,3 +7,12 @@ Add h1–h6 base typography styles aligned with the Juno design system scale. - `global.css` and `theme.css`: h1–h6 defined in `@layer base` with IBM Plex Sans Bold, rem font sizes, and Tailwind leading utilities. `theme.css` uses `var(--font-sans)` instead of a hardcoded font stack. - `FormattedText`: heading sizes and line-heights aligned with the scale; h5 corrected (1.03rem → 1.125rem); h6 added; redundant `font-weight`/`font-style` declarations removed. - `ContentHeading`: removed `jn:font-bold` and `jn:text-lg` overrides that were overriding the h1 base style with a smaller size. + +Fix h1 misuse in components that rendered UI labels as `

`, which caused unintended size changes after the global h1 style was introduced. Heading levels were chosen to reflect both visual size and accessibility (correct heading outline for screen readers). + +- `Modal`: title changed from `

` to `

`. The modal has `role="dialog"` which creates an isolated landmark; the title is referenced via `aria-labelledby`. A heading inside a dialog is semantically correct and independent of the page outline. `

` matches the previous visual size (~20px). +- `Form`: title changed from `

` to `

`. A form is a named content section; a heading is appropriate. `

` matches the previous visual size (~24px). +- `FormSection`: title changed from `

` to `

`. One level below `Form` (`

`) in the heading hierarchy. `

` was chosen over `

` (visual match) to maintain correct nesting. +- `SignInForm`: title changed from `

` to `

`. The form is often the primary content of a page but may also be embedded; `

` is a safe default for both cases. +- `IntroBox`: title changed from `

` to `

`. An info box is not a navigable section; adding it to the heading outline would confuse screen reader users navigating by heading. Bold styling preserved via existing `introboxHeading` class. +- `PopupMenu`: section heading changed from `

` to ``. A dropdown menu label is purely decorative grouping — not a document section. Using a heading here would pollute the heading outline with menu internals. diff --git a/packages/ui-components/src/components/Form/Form.component.tsx b/packages/ui-components/src/components/Form/Form.component.tsx index e6b610b800..b252ede711 100644 --- a/packages/ui-components/src/components/Form/Form.component.tsx +++ b/packages/ui-components/src/components/Form/Form.component.tsx @@ -10,8 +10,6 @@ const formBaseStyles = ` ` const formTitleStyles = ` - jn:text-2xl - jn:font-bold jn:mb-4 ` @@ -45,7 +43,7 @@ export interface FormProps extends FormHTMLAttributes { export const Form = ({ title = "", className = "", children, ...props }: FormProps): ReactNode => { return (
- {title ?

{title}

: null} + {title ?

{title}

: null} {children}
) diff --git a/packages/ui-components/src/components/FormSection/FormSection.component.tsx b/packages/ui-components/src/components/FormSection/FormSection.component.tsx index 38f160985e..df39d46e60 100644 --- a/packages/ui-components/src/components/FormSection/FormSection.component.tsx +++ b/packages/ui-components/src/components/FormSection/FormSection.component.tsx @@ -11,8 +11,6 @@ const formSectionBaseStyles = ` ` const headingStyles = ` - jn:text-lg - jn:font-bold jn:mb-4 ` @@ -45,7 +43,7 @@ export interface FormSectionProps extends HTMLAttributes { export const FormSection = ({ title = "", children, className = "", ...props }: FormSectionProps): ReactNode => { return (
- {title ?

{title}

: null} + {title ?

{title}

: null} {children}
) diff --git a/packages/ui-components/src/components/IntroBox/IntroBox.component.tsx b/packages/ui-components/src/components/IntroBox/IntroBox.component.tsx index 0a719dddab..776519aa57 100644 --- a/packages/ui-components/src/components/IntroBox/IntroBox.component.tsx +++ b/packages/ui-components/src/components/IntroBox/IntroBox.component.tsx @@ -119,7 +119,7 @@ export const IntroBox = ({ >
- {title ?

{title}

: ""} + {title ?

{title}

: ""} {children ? children :

{text}

}
diff --git a/packages/ui-components/src/components/Message/Message.component.tsx b/packages/ui-components/src/components/Message/Message.component.tsx index 47294c3dbc..990406fcca 100644 --- a/packages/ui-components/src/components/Message/Message.component.tsx +++ b/packages/ui-components/src/components/Message/Message.component.tsx @@ -264,7 +264,7 @@ export const Message = ({
- {title &&

{title}

} + {title && {title}}
{children || text}
{dismissible && ( diff --git a/packages/ui-components/src/components/Modal/Modal.component.tsx b/packages/ui-components/src/components/Modal/Modal.component.tsx index 71839c3e5d..fa8e076698 100644 --- a/packages/ui-components/src/components/Modal/Modal.component.tsx +++ b/packages/ui-components/src/components/Modal/Modal.component.tsx @@ -56,11 +56,6 @@ const headerstyles = ` jn:h-[2.8125rem] ` -const titlestyles = ` - jn:text-xl - jn:font-bold -` - const contentstyles = ` jn:min-h-[5rem] ` @@ -177,13 +172,13 @@ export const Modal = ({ } if (typeof modalTitle === "string") { return ( -

+

{modalTitle} -

+

) } return ( -
+
{modalTitle}
) diff --git a/packages/ui-components/src/components/PopupMenu/PopupMenu.component.tsx b/packages/ui-components/src/components/PopupMenu/PopupMenu.component.tsx index ca657b0cfe..9199837f88 100644 --- a/packages/ui-components/src/components/PopupMenu/PopupMenu.component.tsx +++ b/packages/ui-components/src/components/PopupMenu/PopupMenu.component.tsx @@ -398,7 +398,7 @@ export const PopupMenuSectionHeading = ({ }: PopupMenuSectionHeadingProps): ReactNode => { return (
-

{label && label.length ? label : children}

+ {label && label.length ? label : children}
) } diff --git a/packages/ui-components/src/components/SignInForm/SignInForm.component.tsx b/packages/ui-components/src/components/SignInForm/SignInForm.component.tsx index 469ee20ce1..c813fae5d2 100644 --- a/packages/ui-components/src/components/SignInForm/SignInForm.component.tsx +++ b/packages/ui-components/src/components/SignInForm/SignInForm.component.tsx @@ -8,8 +8,6 @@ import { Message } from "../Message" import { Stack } from "../Stack" const signInFormTitleStyles = ` - jn:text-xl - jn:font-bold jn:text-theme-highest jn:mb-4 ` @@ -75,7 +73,7 @@ export const SignInForm = ({ return (
- {title !== false &&

{title}

} + {title !== false &&

{title}

} {errorMessage && } From 4c980640ef9522fe5f49eafef311782ae700494e Mon Sep 17 00:00:00 2001 From: MartinS-git Date: Thu, 11 Jun 2026 10:48:30 +0200 Subject: [PATCH 12/21] fix(ui): update SignInForm test to reflect removed text-xl/font-bold overrides Signed-off-by: MartinS-git --- .../ui-components/src/components/SignInForm/SignInForm.test.tsx | 2 -- 1 file changed, 2 deletions(-) diff --git a/packages/ui-components/src/components/SignInForm/SignInForm.test.tsx b/packages/ui-components/src/components/SignInForm/SignInForm.test.tsx index d371b13c0f..b2caeea38e 100644 --- a/packages/ui-components/src/components/SignInForm/SignInForm.test.tsx +++ b/packages/ui-components/src/components/SignInForm/SignInForm.test.tsx @@ -69,8 +69,6 @@ describe("SignInForm Component Tests", () => { test("applies correct styling to title", () => { render() const heading = screen.getByRole("heading") - expect(heading).toHaveClass("jn:text-xl") - expect(heading).toHaveClass("jn:font-bold") expect(heading).toHaveClass("jn:text-theme-highest") }) }) From 3805d857fec07ee9cf287b10fb0ab5e195dc182e Mon Sep 17 00:00:00 2001 From: MartinS-git Date: Thu, 11 Jun 2026 11:01:19 +0200 Subject: [PATCH 13/21] fix(ui): use h4 for ReactNode modal titles and add heading level assertions to SignInForm tests - Modal: render ReactNode titles as

instead of
so aria-labelledby always points to a semantic heading element - SignInForm tests: assert heading level 2 explicitly to prevent silent regressions in heading semantics Signed-off-by: MartinS-git --- .../src/components/Modal/Modal.component.tsx | 4 ++-- .../src/components/SignInForm/SignInForm.test.tsx | 14 +++++++------- 2 files changed, 9 insertions(+), 9 deletions(-) diff --git a/packages/ui-components/src/components/Modal/Modal.component.tsx b/packages/ui-components/src/components/Modal/Modal.component.tsx index fa8e076698..622dd3b89f 100644 --- a/packages/ui-components/src/components/Modal/Modal.component.tsx +++ b/packages/ui-components/src/components/Modal/Modal.component.tsx @@ -178,9 +178,9 @@ export const Modal = ({ ) } return ( -
+

{modalTitle} -

+

) } diff --git a/packages/ui-components/src/components/SignInForm/SignInForm.test.tsx b/packages/ui-components/src/components/SignInForm/SignInForm.test.tsx index b2caeea38e..31e4a26f75 100644 --- a/packages/ui-components/src/components/SignInForm/SignInForm.test.tsx +++ b/packages/ui-components/src/components/SignInForm/SignInForm.test.tsx @@ -43,15 +43,15 @@ describe("SignInForm Component Tests", () => { describe("Title Prop", () => { test("renders default title 'Sign In' when no title prop is passed", () => { render() - expect(screen.getByRole("heading")).toBeInTheDocument() - expect(screen.getByRole("heading")).toHaveClass("juno-sign-in-form-heading") - expect(screen.getByRole("heading")).toHaveTextContent("Sign In") + expect(screen.getByRole("heading", { level: 2 })).toBeInTheDocument() + expect(screen.getByRole("heading", { level: 2 })).toHaveClass("juno-sign-in-form-heading") + expect(screen.getByRole("heading", { level: 2 })).toHaveTextContent("Sign In") }) test("renders custom title when string is passed", () => { render() - expect(screen.getByRole("heading")).toBeInTheDocument() - expect(screen.getByRole("heading")).toHaveTextContent("Welcome Back") + expect(screen.getByRole("heading", { level: 2 })).toBeInTheDocument() + expect(screen.getByRole("heading", { level: 2 })).toHaveTextContent("Welcome Back") }) test("does not render title when title={false}", () => { @@ -61,14 +61,14 @@ describe("SignInForm Component Tests", () => { test("renders empty string title as empty heading", () => { render() - const heading = screen.queryByRole("heading") + const heading = screen.queryByRole("heading", { level: 2 }) expect(heading).toBeInTheDocument() expect(heading).toHaveTextContent("") }) test("applies correct styling to title", () => { render() - const heading = screen.getByRole("heading") + const heading = screen.getByRole("heading", { level: 2 }) expect(heading).toHaveClass("jn:text-theme-highest") }) }) From 713e76b466e93437b199c0c61d8384d678a99a93 Mon Sep 17 00:00:00 2001 From: MartinS-git Date: Thu, 11 Jun 2026 11:14:21 +0200 Subject: [PATCH 14/21] fix(ui): update Modal test to use heading level 4 instead of div for ReactNode title Signed-off-by: MartinS-git --- packages/ui-components/src/components/Modal/Modal.test.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/ui-components/src/components/Modal/Modal.test.tsx b/packages/ui-components/src/components/Modal/Modal.test.tsx index 30034466f9..f3b9306703 100644 --- a/packages/ui-components/src/components/Modal/Modal.test.tsx +++ b/packages/ui-components/src/components/Modal/Modal.test.tsx @@ -53,7 +53,7 @@ describe("Modal", () => { ) const dialog = screen.getByRole("dialog") - const titleWrapper = screen.getByText("Node Title").closest("div") + const titleWrapper = screen.getByRole("heading", { level: 4 }) expect(dialog).toBeInTheDocument() expect(titleWrapper).toBeInTheDocument() From be779267ea89e0392de5fcad3ec6e9ca25f09fdc Mon Sep 17 00:00:00 2001 From: MartinS-git Date: Fri, 12 Jun 2026 14:06:15 +0200 Subject: [PATCH 15/21] fix(ui): replace hardcoded font-weight with Tailwind utility and fix Modal ReactNode title HTML - global.css, theme.css: replace font-weight: 700 with @apply jn:font-bold - Modal: render ReactNode titles as
instead of

to avoid invalid HTML (block elements nested inside heading elements) Signed-off-by: MartinS-git --- .changeset/typography-scale-headings.md | 4 +++- .../ui-components/src/components/Modal/Modal.component.tsx | 4 ++-- packages/ui-components/src/global.css | 3 +-- packages/ui-components/src/theme.css | 2 +- 4 files changed, 7 insertions(+), 6 deletions(-) diff --git a/.changeset/typography-scale-headings.md b/.changeset/typography-scale-headings.md index 7f2fe0c8b0..bee933f837 100644 --- a/.changeset/typography-scale-headings.md +++ b/.changeset/typography-scale-headings.md @@ -15,4 +15,6 @@ Fix h1 misuse in components that rendered UI labels as `

`, which caused unin - `FormSection`: title changed from `

` to `

`. One level below `Form` (`

`) in the heading hierarchy. `

` was chosen over `

` (visual match) to maintain correct nesting. - `SignInForm`: title changed from `

` to `

`. The form is often the primary content of a page but may also be embedded; `

` is a safe default for both cases. - `IntroBox`: title changed from `

` to `

`. An info box is not a navigable section; adding it to the heading outline would confuse screen reader users navigating by heading. Bold styling preserved via existing `introboxHeading` class. -- `PopupMenu`: section heading changed from `

` to ``. A dropdown menu label is purely decorative grouping — not a document section. Using a heading here would pollute the heading outline with menu internals. +- `global.css`: replaced `font-weight: 700` with `@apply jn:font-bold` in h1–h6 base styles for consistency with Tailwind conventions. +- `theme.css`: same — replaced `font-weight: 700` with `@apply jn:font-bold`. +- `Modal`: ReactNode titles now render as `
` instead of `

` to avoid invalid HTML (block elements inside heading elements). String titles remain `

`. Both approaches are equivalent for assistive technologies. diff --git a/packages/ui-components/src/components/Modal/Modal.component.tsx b/packages/ui-components/src/components/Modal/Modal.component.tsx index 622dd3b89f..f38d6613c7 100644 --- a/packages/ui-components/src/components/Modal/Modal.component.tsx +++ b/packages/ui-components/src/components/Modal/Modal.component.tsx @@ -178,9 +178,9 @@ export const Modal = ({ ) } return ( -

+
{modalTitle} -

+
) } diff --git a/packages/ui-components/src/global.css b/packages/ui-components/src/global.css index 78a2ddb80a..c458c72043 100644 --- a/packages/ui-components/src/global.css +++ b/packages/ui-components/src/global.css @@ -1058,8 +1058,7 @@ h4, h5, h6 { - @apply jn:font-sans; - font-weight: 700; + @apply jn:font-sans jn:font-bold; } h1 { diff --git a/packages/ui-components/src/theme.css b/packages/ui-components/src/theme.css index b7a81d5b6d..b6a98afde4 100644 --- a/packages/ui-components/src/theme.css +++ b/packages/ui-components/src/theme.css @@ -1131,7 +1131,7 @@ h5, h6 { font-family: var(--font-sans); - font-weight: 700; + @apply jn:font-bold; } h1 { From 35bdb3379fb5e011a207e7b78816e1583c21e2c3 Mon Sep 17 00:00:00 2001 From: MartinS-git Date: Fri, 12 Jun 2026 14:07:35 +0200 Subject: [PATCH 16/21] fix(ui): remove jn: prefix from @apply font-bold in theme.css for consistency Signed-off-by: MartinS-git --- packages/ui-components/src/theme.css | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/ui-components/src/theme.css b/packages/ui-components/src/theme.css index b6a98afde4..3281b96937 100644 --- a/packages/ui-components/src/theme.css +++ b/packages/ui-components/src/theme.css @@ -1131,7 +1131,7 @@ h5, h6 { font-family: var(--font-sans); - @apply jn:font-bold; + @apply font-bold; } h1 { From 4af9079afae864498f5ba5fc22b20ad0de4adbcd Mon Sep 17 00:00:00 2001 From: MartinS-git Date: Fri, 12 Jun 2026 14:46:44 +0200 Subject: [PATCH 17/21] fix(ui): add typography styles to Modal ReactNode title div and correct changeset inaccuracies Signed-off-by: MartinS-git --- .changeset/typography-scale-headings.md | 4 ++-- .../ui-components/src/components/Modal/Modal.component.tsx | 7 ++++++- 2 files changed, 8 insertions(+), 3 deletions(-) diff --git a/.changeset/typography-scale-headings.md b/.changeset/typography-scale-headings.md index bee933f837..e3b3fc2567 100644 --- a/.changeset/typography-scale-headings.md +++ b/.changeset/typography-scale-headings.md @@ -4,7 +4,7 @@ Add h1–h6 base typography styles aligned with the Juno design system scale. -- `global.css` and `theme.css`: h1–h6 defined in `@layer base` with IBM Plex Sans Bold, rem font sizes, and Tailwind leading utilities. `theme.css` uses `var(--font-sans)` instead of a hardcoded font stack. +- `global.css` and `theme.css`: h1–h6 defined in `@layer base` with IBM Plex Sans Bold, rem font sizes, and plain CSS `line-height` values. `theme.css` uses `var(--font-sans)` instead of a hardcoded font stack. - `FormattedText`: heading sizes and line-heights aligned with the scale; h5 corrected (1.03rem → 1.125rem); h6 added; redundant `font-weight`/`font-style` declarations removed. - `ContentHeading`: removed `jn:font-bold` and `jn:text-lg` overrides that were overriding the h1 base style with a smaller size. @@ -16,5 +16,5 @@ Fix h1 misuse in components that rendered UI labels as `

`, which caused unin - `SignInForm`: title changed from `

` to `

`. The form is often the primary content of a page but may also be embedded; `

` is a safe default for both cases. - `IntroBox`: title changed from `

` to `

`. An info box is not a navigable section; adding it to the heading outline would confuse screen reader users navigating by heading. Bold styling preserved via existing `introboxHeading` class. - `global.css`: replaced `font-weight: 700` with `@apply jn:font-bold` in h1–h6 base styles for consistency with Tailwind conventions. -- `theme.css`: same — replaced `font-weight: 700` with `@apply jn:font-bold`. +- `theme.css`: same — replaced `font-weight: 700` with `@apply font-bold` (no `jn:` prefix, consistent with existing `@apply` usage in that file). - `Modal`: ReactNode titles now render as `

` instead of `

` to avoid invalid HTML (block elements inside heading elements). String titles remain `

`. Both approaches are equivalent for assistive technologies. diff --git a/packages/ui-components/src/components/Modal/Modal.component.tsx b/packages/ui-components/src/components/Modal/Modal.component.tsx index f38d6613c7..e277a27bcc 100644 --- a/packages/ui-components/src/components/Modal/Modal.component.tsx +++ b/packages/ui-components/src/components/Modal/Modal.component.tsx @@ -56,6 +56,11 @@ const headerstyles = ` jn:h-[2.8125rem] ` +const titlestyles = ` + jn:text-xl + jn:font-bold +` + const contentstyles = ` jn:min-h-[5rem] ` @@ -178,7 +183,7 @@ export const Modal = ({ ) } return ( -
+
{modalTitle}
) From f2aaa3fd549dc847a03fe7be1b353c2ea418ef15 Mon Sep 17 00:00:00 2001 From: MartinS-git Date: Fri, 12 Jun 2026 15:02:19 +0200 Subject: [PATCH 18/21] fix(ui): align Modal ReactNode title typography with h4 base styles (1.28rem, leading-relaxed, bold) Signed-off-by: MartinS-git --- .../ui-components/src/components/Modal/Modal.component.tsx | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/packages/ui-components/src/components/Modal/Modal.component.tsx b/packages/ui-components/src/components/Modal/Modal.component.tsx index e277a27bcc..4334a66432 100644 --- a/packages/ui-components/src/components/Modal/Modal.component.tsx +++ b/packages/ui-components/src/components/Modal/Modal.component.tsx @@ -57,7 +57,8 @@ const headerstyles = ` ` const titlestyles = ` - jn:text-xl + jn:text-[1.28rem] + jn:leading-relaxed jn:font-bold ` From c7eb1ab71a0d79977c28ffa3b05af977d7f4862d Mon Sep 17 00:00:00 2001 From: MartinS-git Date: Fri, 12 Jun 2026 15:14:22 +0200 Subject: [PATCH 19/21] fix(ui): add jn:font-sans to Modal ReactNode titlestyles for font-family consistency with h4 path Signed-off-by: MartinS-git --- packages/ui-components/src/components/Modal/Modal.component.tsx | 1 + 1 file changed, 1 insertion(+) diff --git a/packages/ui-components/src/components/Modal/Modal.component.tsx b/packages/ui-components/src/components/Modal/Modal.component.tsx index 4334a66432..3c4cda49a2 100644 --- a/packages/ui-components/src/components/Modal/Modal.component.tsx +++ b/packages/ui-components/src/components/Modal/Modal.component.tsx @@ -57,6 +57,7 @@ const headerstyles = ` ` const titlestyles = ` + jn:font-sans jn:text-[1.28rem] jn:leading-relaxed jn:font-bold From 77631d97c926813e979ca147dcdf52ef1cf68b4f Mon Sep 17 00:00:00 2001 From: MartinS-git Date: Fri, 12 Jun 2026 15:16:33 +0200 Subject: [PATCH 20/21] fix(ui): apply titlestyles to both h4 and div Modal title paths for full consistency Signed-off-by: MartinS-git --- packages/ui-components/src/components/Modal/Modal.component.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/ui-components/src/components/Modal/Modal.component.tsx b/packages/ui-components/src/components/Modal/Modal.component.tsx index 3c4cda49a2..327487bbe1 100644 --- a/packages/ui-components/src/components/Modal/Modal.component.tsx +++ b/packages/ui-components/src/components/Modal/Modal.component.tsx @@ -179,7 +179,7 @@ export const Modal = ({ } if (typeof modalTitle === "string") { return ( -

+

{modalTitle}

) From 05747d108c40e00a359c999f9b75c7c186def406 Mon Sep 17 00:00:00 2001 From: MartinS-git Date: Fri, 12 Jun 2026 15:25:46 +0200 Subject: [PATCH 21/21] fix(ui): remove redundant span wrapper in PopupMenuSectionHeading to prevent invalid HTML Signed-off-by: MartinS-git --- .../src/components/PopupMenu/PopupMenu.component.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/ui-components/src/components/PopupMenu/PopupMenu.component.tsx b/packages/ui-components/src/components/PopupMenu/PopupMenu.component.tsx index 9199837f88..9c40e50799 100644 --- a/packages/ui-components/src/components/PopupMenu/PopupMenu.component.tsx +++ b/packages/ui-components/src/components/PopupMenu/PopupMenu.component.tsx @@ -398,7 +398,7 @@ export const PopupMenuSectionHeading = ({ }: PopupMenuSectionHeadingProps): ReactNode => { return (
- {label && label.length ? label : children} + {label && label.length ? label : children}
) }