diff --git a/components/Header.tsx b/components/Header.tsx
index bfccf32..fc44a55 100644
--- a/components/Header.tsx
+++ b/components/Header.tsx
@@ -1,9 +1,28 @@
-import { Container, Group, Image } from '@mantine/core'
+import { Container, Group } from '@mantine/core'
import classes from '@/styles/Header.module.css'
import { pageConfig } from '@/uptime.config'
import { PageConfigLink } from '@/types/config'
import { useTranslation } from 'react-i18next'
+// OSG brand mark — same two-dot "connect" glyph as the wordmark on
+// openshopgraph.org (BaseLayout.astro .top-brand .mark svg).
+function OsgMark() {
+ return (
+
+
+
+ )
+}
+
export default function Header({ style }: { style?: React.CSSProperties }) {
const { t } = useTranslation('common')
const linkToElement = (link: PageConfigLink, i: number) => {
@@ -26,17 +45,10 @@ export default function Header({ style }: { style?: React.CSSProperties }) {
diff --git a/pages/_app.tsx b/pages/_app.tsx
index 1521da4..5c9b04b 100644
--- a/pages/_app.tsx
+++ b/pages/_app.tsx
@@ -1,4 +1,6 @@
import '@mantine/core/styles.css'
+import '@/styles/osg-fonts.css'
+import '@/styles/osg-theme.css'
import type { AppProps } from 'next/app'
import { MantineProvider } from '@mantine/core'
import NoSsr from '@/components/NoSsr'
diff --git a/pages/incidents.tsx b/pages/incidents.tsx
index 480e5e4..8f00821 100644
--- a/pages/incidents.tsx
+++ b/pages/incidents.tsx
@@ -1,6 +1,5 @@
import Head from 'next/head'
-import { Inter } from 'next/font/google'
import { MaintenanceConfig, MonitorTarget } from '@/types/config'
import { maintenances, pageConfig } from '@/uptime.config'
import Header from '@/components/Header'
@@ -12,7 +11,6 @@ import NoIncidentsAlert from '@/components/NoIncidents'
import { useTranslation } from 'react-i18next'
export const runtime = 'experimental-edge'
-const inter = Inter({ subsets: ['latin'] })
function getSelectedMonth() {
const hash = window.location.hash.replace('#', '')
@@ -87,7 +85,7 @@ export default function IncidentsPage({ monitors }: { monitors: MonitorTarget[]
-
+
-
+
{state.lastUpdate === 0 ? (
diff --git a/public/fonts/cabinet-grotesk-700.woff2 b/public/fonts/cabinet-grotesk-700.woff2
new file mode 100644
index 0000000..fc4f32d
Binary files /dev/null and b/public/fonts/cabinet-grotesk-700.woff2 differ
diff --git a/public/fonts/cabinet-grotesk-800.woff2 b/public/fonts/cabinet-grotesk-800.woff2
new file mode 100644
index 0000000..b490cff
Binary files /dev/null and b/public/fonts/cabinet-grotesk-800.woff2 differ
diff --git a/public/fonts/martian-mono-400.woff2 b/public/fonts/martian-mono-400.woff2
new file mode 100644
index 0000000..952bb37
Binary files /dev/null and b/public/fonts/martian-mono-400.woff2 differ
diff --git a/public/fonts/martian-mono-600.woff2 b/public/fonts/martian-mono-600.woff2
new file mode 100644
index 0000000..dc8f7c1
Binary files /dev/null and b/public/fonts/martian-mono-600.woff2 differ
diff --git a/public/fonts/switzer-400.woff2 b/public/fonts/switzer-400.woff2
new file mode 100644
index 0000000..df335d6
Binary files /dev/null and b/public/fonts/switzer-400.woff2 differ
diff --git a/public/fonts/switzer-500.woff2 b/public/fonts/switzer-500.woff2
new file mode 100644
index 0000000..c6ccae4
Binary files /dev/null and b/public/fonts/switzer-500.woff2 differ
diff --git a/public/fonts/switzer-600.woff2 b/public/fonts/switzer-600.woff2
new file mode 100644
index 0000000..67d8639
Binary files /dev/null and b/public/fonts/switzer-600.woff2 differ
diff --git a/styles/Header.module.css b/styles/Header.module.css
index 45257cd..b171d0c 100644
--- a/styles/Header.module.css
+++ b/styles/Header.module.css
@@ -2,7 +2,7 @@
height: rem(56px);
margin-bottom: rem(100px);
background-color: var(--mantine-color-body);
- border-bottom: rem(1px) solid light-dark(var(--mantine-color-gray-3), var(--mantine-color-dark-4));
+ border-bottom: rem(1px) solid var(--mantine-color-default-border);
}
.inner {
@@ -27,7 +27,7 @@
}
[data-mantine-color-scheme] &[data-active] {
- background-color: var(--mantine-color-blue-filled);
- color: var(--mantine-color-white);
+ background-color: var(--mantine-primary-color-filled);
+ color: var(--mantine-color-body);
}
}
diff --git a/styles/osg-fonts.css b/styles/osg-fonts.css
new file mode 100644
index 0000000..b9567e4
--- /dev/null
+++ b/styles/osg-fonts.css
@@ -0,0 +1,65 @@
+/*
+ * osg-fonts.css — self-hosted brand faces, copied verbatim (same woff2
+ * files) from openshopgraph-frontend-v2 src/styles/site-fonts.css so the
+ * status page renders with the same type system as openshopgraph.org.
+ * No font CDNs at runtime — files live in /public/fonts/.
+ */
+
+@font-face {
+ font-family: 'Cabinet Grotesk';
+ font-weight: 700;
+ font-style: normal;
+ font-display: swap;
+ src: url('/fonts/cabinet-grotesk-700.woff2') format('woff2');
+}
+@font-face {
+ font-family: 'Cabinet Grotesk';
+ font-weight: 800;
+ font-style: normal;
+ font-display: swap;
+ src: url('/fonts/cabinet-grotesk-800.woff2') format('woff2');
+}
+@font-face {
+ font-family: 'Switzer';
+ font-weight: 400;
+ font-style: normal;
+ font-display: swap;
+ src: url('/fonts/switzer-400.woff2') format('woff2');
+}
+@font-face {
+ font-family: 'Switzer';
+ font-weight: 500;
+ font-style: normal;
+ font-display: swap;
+ src: url('/fonts/switzer-500.woff2') format('woff2');
+}
+@font-face {
+ font-family: 'Switzer';
+ font-weight: 600;
+ font-style: normal;
+ font-display: swap;
+ src: url('/fonts/switzer-600.woff2') format('woff2');
+}
+@font-face {
+ font-family: 'Martian Mono';
+ font-weight: 400;
+ font-style: normal;
+ font-display: swap;
+ src: url('/fonts/martian-mono-400.woff2') format('woff2');
+}
+@font-face {
+ font-family: 'Martian Mono';
+ font-weight: 600;
+ font-style: normal;
+ font-display: swap;
+ src: url('/fonts/martian-mono-600.woff2') format('woff2');
+}
+
+:root {
+ --font-display:
+ 'Cabinet Grotesk', 'Switzer', -apple-system, BlinkMacSystemFont, 'Segoe UI', 'Helvetica Neue',
+ Arial, sans-serif;
+ --font-body:
+ 'Switzer', -apple-system, BlinkMacSystemFont, 'Segoe UI', 'Helvetica Neue', Arial, sans-serif;
+ --font-facts: 'Martian Mono', 'SF Mono', SFMono-Regular, ui-monospace, Menlo, Consolas, monospace;
+}
diff --git a/styles/osg-theme.css b/styles/osg-theme.css
new file mode 100644
index 0000000..ee5f6bc
--- /dev/null
+++ b/styles/osg-theme.css
@@ -0,0 +1,105 @@
+/*
+ * osg-theme.css — remaps Mantine's CSS custom properties to the
+ * openshopgraph.org design tokens (see openshopgraph-frontend-v2
+ * src/styles/site-tokens.css, "source of truth"). Scoped to the
+ * [data-mantine-color-scheme] attribute Mantine already sets, so this
+ * keeps following prefers-color-scheme via ColorSchemeScript
+ * defaultColorScheme="auto" — same behaviour as the main site.
+ *
+ * Semantic monitor-state colors (operational green / down red used by
+ * Mantine's own IconCircleCheck/IconAlertCircle + accordion chevrons) are
+ * left untouched on purpose — only chrome (surfaces, borders, text,
+ * type, radius) is re-themed.
+ */
+
+:root {
+ --font-display:
+ 'Cabinet Grotesk', 'Switzer', -apple-system, BlinkMacSystemFont, 'Segoe UI', 'Helvetica Neue',
+ Arial, sans-serif;
+ --font-body:
+ 'Switzer', -apple-system, BlinkMacSystemFont, 'Segoe UI', 'Helvetica Neue', Arial, sans-serif;
+ --font-facts: 'Martian Mono', 'SF Mono', SFMono-Regular, ui-monospace, Menlo, Consolas, monospace;
+
+ --mantine-font-family: var(--font-body);
+ --mantine-font-family-headings: var(--font-display);
+ --mantine-font-family-monospace: var(--font-facts);
+
+ --mantine-radius-xs: 4px;
+ --mantine-radius-sm: 8px;
+ --mantine-radius-md: 12px;
+ --mantine-radius-lg: 16px;
+}
+
+:root[data-mantine-color-scheme='light'] {
+ --mantine-color-body: #f7f6f3; /* --paper */
+ --mantine-color-text: #141412; /* --ink */
+ --mantine-color-white: #ffffff; /* --card, Card/Paper surfaces */
+ --mantine-color-anchor: #141412; /* --ink; chrome links read as brand, not generic blue */
+ --mantine-color-dimmed: #6a6862; /* --muted */
+ --mantine-color-default-border: #e7e5df; /* --hair */
+ --mantine-color-gray-3: #e7e5df; /* --hair; Card.Section border */
+ --mantine-primary-color-filled: #141412; /* --ink; matches .btn-dark on the main site */
+ --mantine-primary-color-filled-hover: #2a2a26;
+}
+
+:root[data-mantine-color-scheme='dark'] {
+ --mantine-color-body: #161512; /* --paper (dark) */
+ --mantine-color-text: #edeae3; /* --ink (dark) */
+ --mantine-color-dark-6: #1e1d1a; /* --card (dark); Card surface */
+ --mantine-color-dark-4: #2e2c27; /* --hair (dark); Card.Section border */
+ --mantine-color-anchor: #edeae3;
+ --mantine-color-dimmed: #9a978e; /* --muted (dark) */
+ --mantine-color-default-border: #2e2c27;
+ --mantine-primary-color-filled: #edeae3;
+ --mantine-primary-color-filled-hover: #d9d5cc;
+}
+
+body {
+ -webkit-font-smoothing: antialiased;
+}
+
+/* ---------- OSG brand header (replaces the generic UptimeFlare logo) ---------- */
+.osg-brand {
+ display: flex;
+ align-items: center;
+ gap: 9px;
+ font-family: var(--font-display);
+ font-weight: 700;
+ font-size: 16px;
+ color: var(--mantine-color-text);
+ text-decoration: none;
+}
+.osg-brand:hover {
+ opacity: 0.85;
+}
+.osg-brand .osg-mark {
+ width: 19px;
+ height: 19px;
+ border-radius: 6px;
+ background: var(--mantine-color-text);
+ display: inline-flex;
+ align-items: center;
+ justify-content: center;
+ flex: 0 0 auto;
+}
+.osg-brand .osg-mark svg {
+ display: block;
+}
+.osg-status-label {
+ font-weight: 500;
+ color: var(--mantine-color-dimmed);
+}
+
+/* ---------- OSG footer line (Footer.tsx customFooter) ---------- */
+.osg-footer {
+ text-align: center;
+ font-size: 12.5px;
+ color: var(--mantine-color-dimmed);
+ margin-top: 10px;
+ line-height: 1.6;
+}
+.osg-footer a {
+ color: var(--mantine-color-text);
+ text-decoration: underline;
+ text-underline-offset: 2px;
+}
diff --git a/uptime.config.ts b/uptime.config.ts
index 1c329c2..da0f0db 100644
--- a/uptime.config.ts
+++ b/uptime.config.ts
@@ -10,6 +10,11 @@ const pageConfig: PageConfig = {
links: [
{ link: 'https://openshopgraph.org', label: 'openshopgraph.org', highlight: true },
],
+ // Chrome/copy only — swaps the default "made with UptimeFlare" line for
+ // one matching openshopgraph.org's footer tone ("Verified data, not
+ // ads."). Monitor semantics below are untouched.
+ customFooter:
+ '',
}
const workerConfig: WorkerConfig = {