Merge pull request #3714 from bluewave-labs/fix/status-page-styling

fix: status page styling
This commit is contained in:
Alexander Holliday authored and GitHub committed 2026-06-07 15:23:06 -07:00
commit 80d6868a1d
7 files changed
+218 -131

No files matched your search

@@ -99,9 +99,9 @@ export const boldStyles = (
},
top: {
display: "flex",
alignItems: "center",
alignItems: { xs: "flex-start", md: "center" },
justifyContent: "space-between",
gap: "12px",
mb: "36px",
},
brand: {
@@ -130,7 +130,7 @@ export const boldStyles = (
hero: {
position: "relative",
borderRadius: "22px",
padding: "36px 36px 32px",
padding: { xs: "24px 20px", md: "36px 36px 32px" },
mb: "28px",
background: isDark ? heroBgDark : heroBgLight,
border: `1px solid ${tokens.border}`,
@@ -149,13 +149,14 @@ export const boldStyles = (
},
heroTitle: {
m: 0,
fontSize: 34,
fontSize: { xs: 24, md: 34 },
fontWeight: 800,
letterSpacing: "-0.02em",
lineHeight: 1.1,
color: tokens.text,
display: "flex",
alignItems: "center",
alignItems: { xs: "flex-start", md: "center" },
flexWrap: "wrap",
gap: "10px",
},
heroCheck: (tone) => ({
@@ -171,9 +172,15 @@ export const boldStyles = (
}),
heroSub: { mt: "10px", mb: 0, color: tokens.textMuted, fontSize: 14 },
chartSwitchWrap: { display: "flex", justifyContent: "flex-end", mb: "16px" },
chartSwitchWrap: {
display: "flex",
justifyContent: { xs: "center", md: "flex-end" },
mb: "16px",
},
chartSwitch: {
display: "inline-flex",
width: { xs: "100%", md: "auto" },
maxWidth: "100%",
border: `1px solid ${tokens.border}`,
borderRadius: "999px",
background: tokens.surface,
@@ -181,16 +188,20 @@ export const boldStyles = (
gap: "2px",
},
chartSwitchButton: (active) => ({
flex: 1,
minWidth: 0,
whiteSpace: "nowrap",
textAlign: "center",
border: 0,
background: active ? tokens.upSoft : "transparent",
fontFamily: "inherit",
fontSize: 11,
padding: "8px 18px",
padding: { xs: "8px 6px", md: "8px 18px" },
cursor: "pointer",
color: active ? tokens.up : tokens.textMuted,
fontWeight: 700,
textTransform: "uppercase",
letterSpacing: "0.12em",
letterSpacing: { xs: "0.04em", md: "0.12em" },
transition: "background 0.2s, color 0.2s",
borderRadius: "999px",
"&:hover": { color: active ? tokens.up : tokens.text },
@@ -217,13 +228,21 @@ export const boldStyles = (
},
cardRow: {
display: "grid",
gridTemplateColumns: "1fr auto",
alignItems: "center",
gap: "24px",
alignItems: { xs: "start", md: "center" },
gridTemplateColumns: { xs: "minmax(0, 1fr)", md: "1fr auto" },
gridTemplateAreas: {
xs: `"name" "status" "meta"`,
md: `"name name" "meta status"`,
},
columnGap: { md: "24px" },
rowGap: { xs: "10px", md: "6px" },
p: "22px 28px",
},
cardLeft: { minWidth: 0 },
cardLeft: { minWidth: 0, flex: 1, width: { xs: "100%", md: "auto" } },
monitorName: {
gridArea: "name",
minWidth: 0,
width: { xs: "100%", md: "auto" },
fontWeight: 700,
fontSize: 17,
letterSpacing: "-0.01em",
@@ -233,10 +252,9 @@ export const boldStyles = (
whiteSpace: "nowrap",
},
monitorMeta: {
display: "flex",
gridArea: "meta",
gap: "10px",
alignItems: "center",
mt: "6px",
alignItems: { xs: "flex-start", md: "center" },
flexWrap: "wrap",
},
pill: {
@@ -273,6 +291,8 @@ export const boldStyles = (
},
badge: (tone) => ({
gridArea: "status",
justifySelf: "start",
fontSize: 11,
fontWeight: 800,
padding: "6px 14px",
@@ -296,10 +316,10 @@ export const boldStyles = (
}),
heatmap: {
padding: "0 28px 22px",
padding: { xs: "0 12px 18px", md: "0 28px 22px" },
display: "grid",
gridTemplateColumns: `repeat(${MAX_RECENT_CHECKS}, 1fr)`,
gap: "3px",
gap: { xs: "1px", md: "3px" },
height: 48,
},
heatmapCell: (kind) => ({
@@ -312,10 +332,10 @@ export const boldStyles = (
}),
histogram: {
padding: "0 28px",
padding: { xs: "0 12px", md: "0 28px" },
display: "grid",
gridTemplateColumns: `repeat(${MAX_RECENT_CHECKS}, 1fr)`,
gap: "3px",
gap: { xs: "1px", md: "3px" },
alignItems: "flex-end",
height: 48,
},
@@ -90,9 +90,9 @@ export const editorialStyles = (
},
top: {
display: "flex",
alignItems: "flex-end",
alignItems: { xs: "flex-start", md: "flex-end" },
justifyContent: "space-between",
gap: "12px",
mb: "48px",
borderBottom: `2px solid ${tokens.text}`,
pb: "18px",
@@ -119,7 +119,7 @@ export const editorialStyles = (
},
statusLine: {
fontSize: 22,
fontSize: { xs: 18, md: 22 },
fontWeight: 400,
m: 0,
mb: "8px",
@@ -144,26 +144,32 @@ export const editorialStyles = (
letterSpacing: "0.12em",
color: tokens.textMuted,
m: 0,
mb: "56px",
mb: { xs: "32px", md: "56px" },
},
chartSwitchWrap: {
display: "flex",
justifyContent: "flex-end",
justifyContent: { xs: "center", md: "flex-end" },
mb: "20px",
fontFamily: EDITORIAL_SECONDARY_SANS_STACK,
},
chartSwitch: {
display: "inline-flex",
width: { xs: "100%", md: "auto" },
maxWidth: "100%",
border: `1px solid ${tokens.text}`,
"& > button + button": { borderLeft: `1px solid ${tokens.text}` },
},
chartSwitchButton: (active) => ({
flex: 1,
minWidth: 0,
whiteSpace: "nowrap",
textAlign: "center",
fontFamily: "inherit",
fontSize: 10,
textTransform: "uppercase",
letterSpacing: "0.2em",
padding: "6px 14px",
letterSpacing: { xs: "0.05em", md: "0.2em" },
padding: { xs: "6px 6px", md: "6px 14px" },
border: 0,
background: active ? tokens.text : "transparent",
color: active ? tokens.bg : tokens.text,
@@ -188,12 +194,20 @@ export const editorialStyles = (
},
cardRow: {
display: "grid",
gridTemplateColumns: "1fr auto",
alignItems: "baseline",
gap: "20px",
alignItems: { xs: "start", md: "baseline" },
gridTemplateColumns: { xs: "minmax(0, 1fr)", md: "1fr auto" },
gridTemplateAreas: {
xs: `"name" "status" "meta"`,
md: `"name name" "meta status"`,
},
columnGap: { md: "20px" },
rowGap: { xs: "10px", md: "6px" },
},
cardLeft: { minWidth: 0 },
cardLeft: { minWidth: 0, flex: 1, width: { xs: "100%", md: "auto" } },
monitorName: {
gridArea: "name",
minWidth: 0,
width: { xs: "100%", md: "auto" },
fontSize: 20,
fontWeight: 700,
letterSpacing: "-0.015em",
@@ -203,14 +217,13 @@ export const editorialStyles = (
whiteSpace: "nowrap",
},
monitorMeta: {
gridArea: "meta",
fontFamily: EDITORIAL_SECONDARY_SANS_STACK,
fontSize: 12,
color: tokens.textMuted,
mt: "6px",
display: "flex",
gap: "12px",
flexWrap: "wrap",
alignItems: "center",
alignItems: { xs: "flex-start", md: "center" },
},
pill: {
textTransform: "uppercase",
@@ -234,6 +247,8 @@ export const editorialStyles = (
},
badge: (tone) => ({
gridArea: "status",
justifySelf: "start",
fontFamily: EDITORIAL_SECONDARY_SANS_STACK,
fontSize: 10,
fontWeight: 700,
@@ -250,7 +265,7 @@ export const editorialStyles = (
mt: "16px",
display: "grid",
gridTemplateColumns: `repeat(${MAX_RECENT_CHECKS}, 1fr)`,
gap: "2px",
gap: { xs: "1px", md: "2px" },
height: 40,
},
heatmapCell: (kind) => ({
@@ -262,7 +277,7 @@ export const editorialStyles = (
mt: "16px",
display: "grid",
gridTemplateColumns: `repeat(${MAX_RECENT_CHECKS}, 1fr)`,
gap: "2px",
gap: { xs: "1px", md: "2px" },
alignItems: "flex-end",
height: 40,
},
@@ -11,24 +11,24 @@ export const ModernHero = ({
const { t } = useTranslation();
return (
<Box sx={styles.hero}>
<Box sx={styles.pulse(overall.tone)} />
<Box sx={styles.statusCopy}>
<Box sx={styles.heroRow}>
<Box sx={styles.pulse(overall.tone)} />
<Box
component="h1"
sx={styles.heroTitle}
>
{overall.message}
</Box>
<Box
component="p"
sx={styles.heroSub}
>
{t("pages.statusPages.statusBar.monitoringSummary", {
count: monitorCount,
})}
</Box>
<Box sx={styles.heroIcon(overall.tone)}>{overall.icon}</Box>
</Box>
<Box
component="p"
sx={styles.heroSub}
>
{t("pages.statusPages.statusBar.monitoringSummary", {
count: monitorCount,
})}
</Box>
<Box sx={styles.heroIcon(overall.tone)}>{overall.icon}</Box>
</Box>
);
};
@@ -17,7 +17,7 @@ export interface ModernStyles {
logoImg: SxProps<Theme>;
hero: SxProps<Theme>;
pulse: (tone: OverallTone) => SxProps<Theme>;
statusCopy: SxProps<Theme>;
heroRow: SxProps<Theme>;
heroTitle: SxProps<Theme>;
heroSub: SxProps<Theme>;
heroIcon: (tone: OverallTone) => SxProps<Theme>;
@@ -117,9 +117,9 @@ export const modernStyles = (
},
top: {
display: "flex",
alignItems: "center",
alignItems: { xs: "flex-start", md: "center" },
justifyContent: "space-between",
gap: "12px",
mb: "32px",
},
brand: {
@@ -148,11 +148,11 @@ export const modernStyles = (
hero: {
position: "relative",
borderRadius: "20px",
padding: "28px 32px",
padding: { xs: "20px", md: "28px 32px" },
mb: "24px",
display: "flex",
alignItems: "center",
gap: "20px",
flexDirection: "column",
gap: "4px",
background: tokens.surface,
border: `1px solid ${tokens.border}`,
boxShadow: cardShadow,
@@ -182,25 +182,37 @@ export const modernStyles = (
},
};
},
statusCopy: { flex: 1, minWidth: 0 },
heroRow: {
display: "flex",
alignItems: "center",
gap: { xs: "14px", md: "20px" },
},
heroTitle: {
m: 0,
mb: "4px",
fontSize: 22,
flex: 1,
minWidth: 0,
fontSize: { xs: 18, md: 22 },
fontWeight: 700,
letterSpacing: "-0.02em",
color: tokens.text,
},
heroSub: { m: 0, color: tokens.textMuted, fontSize: 13 },
heroIcon: (tone) => ({
display: { xs: "none", md: "flex" },
color: toneColor(tone, tokens),
display: "flex",
alignItems: "center",
flexShrink: 0,
}),
chartSwitchWrap: { display: "flex", justifyContent: "flex-end", mb: "14px" },
chartSwitchWrap: {
display: "flex",
justifyContent: { xs: "center", md: "flex-end" },
mb: "14px",
},
chartSwitch: {
display: "inline-flex",
width: { xs: "100%", md: "auto" },
maxWidth: "100%",
border: `1px solid ${tokens.border}`,
borderRadius: "999px",
background: tokens.surface,
@@ -208,16 +220,20 @@ export const modernStyles = (
gap: "2px",
},
chartSwitchButton: (active) => ({
flex: 1,
minWidth: 0,
whiteSpace: "nowrap",
textAlign: "center",
border: 0,
background: active ? tokens.upSoft : "transparent",
fontFamily: "inherit",
fontSize: 11,
padding: "6px 16px",
padding: { xs: "6px 6px", md: "6px 16px" },
cursor: "pointer",
color: active ? tokens.up : tokens.textMuted,
fontWeight: 600,
textTransform: "uppercase",
letterSpacing: "0.08em",
letterSpacing: { xs: "0.04em", md: "0.08em" },
transition: "background 0.2s, color 0.2s",
borderRadius: "999px",
"&:hover": { color: active ? tokens.up : tokens.text },
@@ -256,13 +272,21 @@ export const modernStyles = (
},
cardRow: {
display: "grid",
gridTemplateColumns: "1fr auto",
alignItems: "center",
gap: "20px",
alignItems: { xs: "start", md: "center" },
gridTemplateColumns: { xs: "minmax(0, 1fr)", md: "1fr auto" },
gridTemplateAreas: {
xs: `"name" "status" "meta"`,
md: `"name name" "meta status"`,
},
columnGap: { md: "20px" },
rowGap: { xs: "10px", md: "6px" },
p: "18px 24px",
},
cardLeft: { minWidth: 0 },
cardLeft: { minWidth: 0, flex: 1, width: { xs: "100%", md: "auto" } },
monitorName: {
gridArea: "name",
minWidth: 0,
width: { xs: "100%", md: "auto" },
fontWeight: 600,
fontSize: 15,
letterSpacing: "-0.005em",
@@ -272,10 +296,9 @@ export const modernStyles = (
whiteSpace: "nowrap",
},
monitorMeta: {
display: "flex",
gridArea: "meta",
gap: "10px",
alignItems: "center",
mt: "6px",
alignItems: { xs: "flex-start", md: "center" },
flexWrap: "wrap",
},
pill: {
@@ -299,6 +322,8 @@ export const modernStyles = (
},
badge: (tone) => ({
gridArea: "status",
justifySelf: "start",
fontSize: 11,
fontWeight: 700,
padding: "5px 12px",
@@ -319,10 +344,10 @@ export const modernStyles = (
}),
heatmap: {
padding: "0 24px 20px",
padding: { xs: "0 12px 16px", md: "0 24px 20px" },
display: "grid",
gridTemplateColumns: `repeat(${MAX_RECENT_CHECKS}, 1fr)`,
gap: "3px",
gap: { xs: "1px", md: "3px" },
height: 46,
},
heatmapCell: (kind) => ({
@@ -334,10 +359,10 @@ export const modernStyles = (
}),
histogram: {
padding: "0 24px",
padding: { xs: "0 12px", md: "0 24px" },
display: "grid",
gridTemplateColumns: `repeat(${MAX_RECENT_CHECKS}, 1fr)`,
gap: "3px",
gap: { xs: "1px", md: "3px" },
alignItems: "flex-end",
height: 46,
},
@@ -11,24 +11,24 @@ export const RefinedHero = ({
const { t } = useTranslation();
return (
<Box sx={styles.hero}>
<Box sx={styles.statusDot(overall.tone)} />
<Box sx={styles.statusCopy}>
<Box sx={styles.heroRow}>
<Box sx={styles.statusDot(overall.tone)} />
<Box
component="h1"
sx={styles.heroTitle}
>
{overall.message}
</Box>
<Box
component="p"
sx={styles.heroSub}
>
{t("pages.statusPages.statusBar.monitoringSummary", {
count: monitorCount,
})}
</Box>
<Box sx={styles.heroIcon(overall.tone)}>{overall.icon}</Box>
</Box>
<Box
component="p"
sx={styles.heroSub}
>
{t("pages.statusPages.statusBar.monitoringSummary", {
count: monitorCount,
})}
</Box>
<Box sx={styles.heroIcon(overall.tone)}>{overall.icon}</Box>
</Box>
);
};
@@ -17,7 +17,7 @@ export interface RefinedStyles {
company: SxProps<Theme>;
hero: SxProps<Theme>;
statusDot: (tone: OverallTone) => SxProps<Theme>;
statusCopy: SxProps<Theme>;
heroRow: SxProps<Theme>;
heroTitle: SxProps<Theme>;
heroSub: SxProps<Theme>;
heroIcon: (tone: OverallTone) => SxProps<Theme>;
@@ -102,9 +102,9 @@ export const refinedStyles = (
},
top: {
display: "flex",
alignItems: "center",
alignItems: { xs: "flex-start", md: "center" },
justifyContent: "space-between",
gap: "12px",
mb: "28px",
},
brand: {
@@ -133,10 +133,10 @@ export const refinedStyles = (
background: tokens.surface,
border: `1px solid ${tokens.border}`,
borderRadius: tokens.radius,
padding: "22px 24px",
padding: { xs: "18px 20px", md: "22px 24px" },
display: "flex",
alignItems: "center",
gap: "16px",
flexDirection: "column",
gap: "4px",
boxShadow: cardShadow,
mb: "20px",
},
@@ -148,10 +148,15 @@ export const refinedStyles = (
boxShadow: `0 0 0 4px ${toneSoft(tone, tokens)}`,
flexShrink: 0,
}),
statusCopy: { flex: 1, minWidth: 0 },
heroRow: {
display: "flex",
alignItems: "center",
gap: { xs: "12px", md: "16px" },
},
heroTitle: {
m: 0,
mb: "2px",
flex: 1,
minWidth: 0,
fontSize: 17,
fontWeight: 600,
letterSpacing: "-0.01em",
@@ -159,14 +164,21 @@ export const refinedStyles = (
},
heroSub: { m: 0, color: tokens.textMuted, fontSize: 13 },
heroIcon: (tone) => ({
display: { xs: "none", md: "flex" },
color: toneColor(tone, tokens),
display: "flex",
alignItems: "center",
flexShrink: 0,
}),
chartSwitchWrap: { display: "flex", justifyContent: "flex-end", mb: "12px" },
chartSwitchWrap: {
display: "flex",
justifyContent: { xs: "center", md: "flex-end" },
mb: "12px",
},
chartSwitch: {
display: "inline-flex",
width: { xs: "100%", md: "auto" },
maxWidth: "100%",
border: `1px solid ${tokens.border}`,
borderRadius: "8px",
background: tokens.surface,
@@ -174,11 +186,15 @@ export const refinedStyles = (
gap: "2px",
},
chartSwitchButton: (active) => ({
flex: 1,
minWidth: 0,
whiteSpace: "nowrap",
textAlign: "center",
border: 0,
background: active ? tokens.upSoft : "transparent",
fontFamily: "inherit",
fontSize: 11,
padding: "5px 14px",
padding: { xs: "5px 6px", md: "5px 14px" },
cursor: "pointer",
color: active ? tokens.up : tokens.textMuted,
borderRadius: "5px",
@@ -207,13 +223,21 @@ export const refinedStyles = (
},
cardRow: {
display: "grid",
gridTemplateColumns: "1fr auto",
alignItems: "center",
gap: "16px",
alignItems: { xs: "start", md: "center" },
gridTemplateColumns: { xs: "minmax(0, 1fr)", md: "1fr auto" },
gridTemplateAreas: {
xs: `"name" "status" "meta"`,
md: `"name name" "meta status"`,
},
columnGap: { md: "16px" },
rowGap: { xs: "10px", md: "4px" },
p: "16px 20px",
},
cardLeft: { minWidth: 0 },
cardLeft: { minWidth: 0, flex: 1, width: { xs: "100%", md: "auto" } },
monitorName: {
gridArea: "name",
minWidth: 0,
width: { xs: "100%", md: "auto" },
fontWeight: 600,
fontSize: 14,
letterSpacing: "-0.005em",
@@ -223,10 +247,9 @@ export const refinedStyles = (
whiteSpace: "nowrap",
},
monitorMeta: {
display: "flex",
gridArea: "meta",
gap: "10px",
alignItems: "center",
mt: "4px",
alignItems: { xs: "flex-start", md: "center" },
flexWrap: "wrap",
},
pill: {
@@ -251,6 +274,8 @@ export const refinedStyles = (
},
badge: (tone) => ({
gridArea: "status",
justifySelf: "start",
fontSize: 11,
fontWeight: 600,
padding: "4px 10px",
@@ -261,10 +286,10 @@ export const refinedStyles = (
}),
heatmap: {
padding: "0 20px 16px",
padding: { xs: "0 10px 14px", md: "0 20px 16px" },
display: "grid",
gridTemplateColumns: `repeat(${MAX_RECENT_CHECKS}, 1fr)`,
gap: "3px",
gap: { xs: "1px", md: "3px" },
height: 42,
},
heatmapCell: (kind) => ({
@@ -276,10 +301,10 @@ export const refinedStyles = (
}),
histogram: {
padding: "0 20px",
padding: { xs: "0 10px", md: "0 20px" },
display: "grid",
gridTemplateColumns: `repeat(${MAX_RECENT_CHECKS}, 1fr)`,
gap: "3px",
gap: { xs: "1px", md: "3px" },
alignItems: "flex-end",
height: 42,
},
@@ -102,8 +102,9 @@ export const BaseStatusPage = ({ statusPage, monitors, config }: Props) => {
return (
<Box sx={styles.page}>
<Box
<Stack
component="header"
direction={{ xs: "column", md: "row" }}
sx={styles.top}
>
<HeaderSlot
@@ -113,7 +114,7 @@ export const BaseStatusPage = ({ statusPage, monitors, config }: Props) => {
monitorCount={monitors.length}
styles={styles}
/>
</Box>
</Stack>
<HeroSlot
statusPage={statusPage}
@@ -171,38 +172,39 @@ export const BaseStatusPage = ({ statusPage, monitors, config }: Props) => {
sx={styles.card}
>
<Box sx={styles.cardRow}>
<Box sx={styles.cardLeft}>
<Box sx={styles.monitorName}>{monitor.name}</Box>
<Box sx={styles.monitorMeta}>
<Box
component="span"
sx={isHardware ? styles.pillHardware : styles.pill}
>
{getMonitorTypeLabel(monitor.type, t)}
</Box>
<Box
component="span"
sx={styles.pill}
>
{uptimePercentage}
</Box>
{monitor.url && (
<Box
component="span"
sx={styles.monitorUrl}
title={monitor.url}
>
{monitor.url}
</Box>
)}
</Box>
</Box>
<Box sx={styles.monitorName}>{monitor.name}</Box>
<Box
component="span"
sx={styles.badge(badgeTone)}
>
{t(statusBadgeKey[monitor.status])}
</Box>
<Stack
direction={{ xs: "column", md: "row" }}
sx={styles.monitorMeta}
>
<Box
component="span"
sx={isHardware ? styles.pillHardware : styles.pill}
>
{getMonitorTypeLabel(monitor.type, t)}
</Box>
<Box
component="span"
sx={{ ...styles.pill }}
>
{uptimePercentage}
</Box>
{monitor.url && (
<Box
component="span"
sx={styles.monitorUrl}
title={monitor.url}
>
{monitor.url}
</Box>
)}
</Stack>
</Box>
{showInfra && (