Stack TopBar brand and shorten nav labels

Long nav copy was squeezing the entity name into an
ellipsis inside max-w-5xl. Stack name over the tagline,
hide brand text below lg, and shorten the longest
topBar.nav strings so the brand stays readable.

Signed-off-by: Émile Ré <emile@probo.com>
This commit is contained in:
Émile Ré
2026-07-29 12:33:10 +02:00
parent b1b23988fc
commit 7c6ab85916
8 changed files with 34 additions and 27 deletions

View File

@@ -7,8 +7,8 @@
"menuTitle": "Menü",
"nav": {
"documents": "Dokumente",
"subprocessors": "Unterauftragsverarbeiter",
"updates": "Aktualisierungen",
"subprocessors": "Subprozessoren",
"updates": "Updates",
"requests": "Anfragen"
}
},

View File

@@ -8,7 +8,7 @@
"nav": {
"documents": "Documents",
"subprocessors": "Sous-traitants",
"updates": "Mises à jour",
"updates": "Actualités",
"requests": "Demandes"
}
},

View File

@@ -7,7 +7,7 @@
"menuTitle": "Menu",
"nav": {
"documents": "Documenti",
"subprocessors": "Sub-responsabili del trattamento",
"subprocessors": "Subprocessori",
"updates": "Aggiornamenti",
"requests": "Richieste"
}

View File

@@ -7,7 +7,7 @@
"menuTitle": "Menu",
"nav": {
"documents": "Documentos",
"subprocessors": "Subcontratantes",
"subprocessors": "Subprocessadores",
"updates": "Atualizações",
"requests": "Pedidos"
}

View File

@@ -7,8 +7,8 @@
"menuTitle": "Menü",
"nav": {
"documents": "Belgeler",
"subprocessors": "Alt İşleyiciler",
"updates": "Güncellemeler",
"subprocessors": "Alt işlemciler",
"updates": "Güncelleme",
"requests": "Talepler"
}
},

View File

@@ -75,9 +75,13 @@ export function TopBar({ queryKey }: TopBarProps) {
return (
<header className={slots.bar()}>
<div className={slots.inner()}>
<RouterLink to={homePath} className={slots.brand()}>
<RouterLink
to={homePath}
className={slots.brand()}
aria-label={`${entityName} ${t("topBar.tagline")}`}
>
<Avatar
size={1}
size={2}
variant="soft"
color="neutral"
radius="small"
@@ -85,16 +89,16 @@ export function TopBar({ queryKey }: TopBarProps) {
fallback={entityName.charAt(0) || "?"}
className={slots.logo()}
/>
<Text size={2} weight="medium" color="neutral" highContrast className={slots.brandName()}>
{entityName}
</Text>
<Text size={2} color="neutral" className={slots.tagline()}>
{t("topBar.tagline")}
</Text>
<span className={slots.brandText()}>
<Text size={2} weight="medium" color="neutral" highContrast className={slots.brandName()}>
{entityName}
</Text>
<Text size={1} color="neutral" className={slots.tagline()}>
{t("topBar.tagline")}
</Text>
</span>
</RouterLink>
<div className={slots.spacer()} />
<nav className={slots.nav()}>
{TOP_BAR_NAV_ITEMS.map((item) => {
const to = localizedPath(item.to);

View File

@@ -42,13 +42,13 @@ export function TopBarSkeleton() {
<div className={slots.bar()}>
<div className={slots.inner()}>
<div className={slots.brand()}>
<AvatarSkeleton size={1} radius="small" />
<TextSkeleton size={2} className={`w-24 ${slots.brandName()}`} />
<TextSkeleton size={2} className={`w-28 ${slots.tagline()}`} />
<AvatarSkeleton size={2} radius="small" />
<span className={slots.brandText()}>
<TextSkeleton size={2} className={`w-24 ${slots.brandName()}`} />
<TextSkeleton size={1} className={`w-28 ${slots.tagline()}`} />
</span>
</div>
<div className={slots.spacer()} />
<nav className={slots.nav()}>
{NAV_ITEMS.map(item => (
<TextSkeleton key={item.key} size={2} className={`mx-3 ${item.width}`} />

View File

@@ -22,17 +22,20 @@ import { tv } from "tailwind-variants/lite";
// Compliance Portal top navigation bar. Slots are shared by the live TopBar and its
// skeleton so the loading placeholder is structurally identical. Desktop-first:
// unprefixed classes are the desktop layout; max-md: collapses into the burger.
// unprefixed classes are the desktop layout; max-md (<768px) collapses into the
// burger. Below lg (<1024px) the brand shows logo only — name + tagline return
// at lg+, where they fit beside the nav without ellipsis. justify-between keeps
// nav right-aligned without a flex-grow spacer competing with the brand.
export const topBar = tv({
slots: {
bar: "flex h-14 items-center bg-sand-1 px-8 max-md:px-4",
inner: "mx-auto flex w-full max-w-5xl items-center gap-10 max-md:gap-3",
inner: "mx-auto flex w-full max-w-5xl items-center justify-between gap-6 max-md:gap-3",
brand: "flex min-w-0 items-center gap-2",
brandText: "flex min-w-0 flex-col max-lg:hidden",
brandName: "truncate",
tagline: "max-md:hidden",
tagline: "truncate",
logo: "shrink-0",
spacer: "h-px flex-1",
nav: "flex items-center gap-1 max-md:hidden",
nav: "flex shrink-0 items-center gap-1 max-md:hidden",
// Wrapper (not the IconButton) so kit `inline-flex` cannot override `hidden`.
menuTrigger: "hidden max-md:block",
},