-
{BRAND_NAME}
+
{BRAND_NAME}
Always camelCase. Domain is always lowercase:{" "}
offon.dev
diff --git a/src/root.tsx b/src/root.tsx
index 55f5185a..dc7b237b 100644
--- a/src/root.tsx
+++ b/src/root.tsx
@@ -5,7 +5,7 @@ import "./index.css";
export const links: LinksFunction = () => [
// Preload fonts used above the fold on every page.
- // Inter 400–700: body text, semibold labels, bold headings used on every page.
+ // Inter 400–600: body text, semibold labels, and all button variants use at most font-semibold (600).
// Syne 700: all h1–h6 via the @layer base rule in index.css.
// Latin-only subsets are always needed for English content and never generate "preloaded but not used" warnings.
// font-display: optional requires preloads to succeed. Without them, the optional window expires
@@ -13,7 +13,6 @@ export const links: LinksFunction = () => [
{ rel: "preload", href: `${import.meta.env.BASE_URL}fonts/inter-latin-400-normal.woff2`, as: "font", type: "font/woff2", crossOrigin: "anonymous" },
{ rel: "preload", href: `${import.meta.env.BASE_URL}fonts/inter-latin-500-normal.woff2`, as: "font", type: "font/woff2", crossOrigin: "anonymous" },
{ rel: "preload", href: `${import.meta.env.BASE_URL}fonts/inter-latin-600-normal.woff2`, as: "font", type: "font/woff2", crossOrigin: "anonymous" },
- { rel: "preload", href: `${import.meta.env.BASE_URL}fonts/inter-latin-700-normal.woff2`, as: "font", type: "font/woff2", crossOrigin: "anonymous" },
{ rel: "preload", href: `${import.meta.env.BASE_URL}fonts/syne-latin-700-normal.woff2`, as: "font", type: "font/woff2", crossOrigin: "anonymous" },
];
diff --git a/src/test/navbar.test.tsx b/src/test/navbar.test.tsx
index 8314d6f5..1bab7e3a 100644
--- a/src/test/navbar.test.tsx
+++ b/src/test/navbar.test.tsx
@@ -56,13 +56,6 @@ describe("Navbar - desktop navigation", () => {
expect(screen.getByRole("navigation", { name: "Main" })).toBeTruthy();
});
- it("has a Home link", () => {
- renderNavbar();
- const nav = screen.getByRole("navigation", { name: "Main" });
- // There may be duplicates in mobile menu; at least one must be present
- expect(within(nav).getAllByRole("link", { name: /Home/i }).length).toBeGreaterThan(0);
- });
-
it("has an About link pointing to /about", () => {
renderNavbar();
const aboutLinks = screen.getAllByRole("link", { name: /About/i });
@@ -158,7 +151,6 @@ describe("Navbar - mobile menu", () => {
const mobileMenu = document.getElementById("mobile-menu");
expect(mobileMenu).toBeTruthy();
const mobileNav = within(mobileMenu!);
- expect(mobileNav.getByRole("link", { name: /Home/i })).toBeTruthy();
expect(mobileNav.getByRole("link", { name: /About/i })).toBeTruthy();
});
diff --git a/styleguide.md b/styleguide.md
index 2c1bd9b9..16e9cbf4 100644
--- a/styleguide.md
+++ b/styleguide.md
@@ -27,7 +27,7 @@ All brand copy constants live in `src/data/constants.ts`. Use them instead of ha
| Role | Family | Key weights | Format |
|---|---|---|---|
| Headings / display (`font-heading`) | Syne | 700 | WOFF2 only (`public/fonts/syne-*.woff2`) |
-| Body & UI (`font-sans`) | Inter | 400, 500, 600 primary (700 available) | WOFF2 only (`public/fonts/inter-*.woff2`) |
+| Body & UI (`font-sans`) | Inter | 400, 500, 600 | WOFF2 only (`public/fonts/inter-*.woff2`) |
| Code / mono (`font-mono`, `code`, `pre`) | JetBrains Mono | 400 primary (500, 600 available) | WOFF2 only (`public/fonts/jetbrains-mono-*.woff2`) |
All fonts are fully self-hosted as WOFF2. No TTF fallbacks. No external network requests.
@@ -48,7 +48,6 @@ Fonts are preloaded to avoid the three-level font discovery delay (HTML parse
- `inter-latin-400-normal.woff2`: body text (Navbar, paragraphs)
- `inter-latin-500-normal.woff2`: medium-weight body text (Navbar links)
- `inter-latin-600-normal.woff2`: semibold text (section labels, card titles)
-- `inter-latin-700-normal.woff2`: bold text (CTA buttons using `font-bold` on non-heading elements)
- `syne-latin-700-normal.woff2`: h1 and h2 elements (the `@layer base` rule in `src/index.css` applies `font-family: 'Syne'` to h1 and h2 only; h3–h6 use Inter)
Only Latin subset variants are preloaded. Other subsets are served from `public/fonts/` but are not preloaded. Update `src/root.tsx` whenever above-the-fold typography changes.
@@ -206,8 +205,8 @@ In light mode, `bg-primary` sections (PageHero, BottomCTA) stay amber. Do **not*
| `.btn-primary` | Filled amber, `rounded-md px-5 py-3 text-sm font-semibold`, `brightness-110` on hover | Default CTA on page background |
| `.btn-ghost` | Outlined, `border-foreground/35`, amber border and text on hover | Secondary CTA on page background |
| `.btn-soft` | Tinted `bg-primary/10 border-primary/30`, no glow | Tertiary / low-emphasis action |
-| `.btn-inverse` | White/background fill with primary border, primary text; inverts on hover to primary bg | Primary CTA inside a `bg-primary` section (e.g. `PageHero`, `BottomCTA`) |
-| `.btn-ghost-inverse` | Transparent with background-colored border and text; inverts on hover to background fill | Secondary CTA inside a `bg-primary` section |
+| `.btn-inverse` | White/background fill with primary border, primary text, `font-semibold`; inverts on hover to primary bg | Primary CTA inside a `bg-primary` section (e.g. `PageHero`, `BottomCTA`) |
+| `.btn-ghost-inverse` | Transparent with background-colored border and text, `font-semibold`; inverts on hover to background fill | Secondary CTA inside a `bg-primary` section |
#### Button contrast rule (light mode)