Skip to content

Commit f26a205

Browse files
committed
fix(docs): correct OG font, mobile logo, and footer stacking
- switch the docs OG image title font from Geist to the site's real brand font (Season Sans), instantiated as a static TTF weight since Satori can't parse WOFF2 or variable fonts; served from /static/ so the i18n proxy's matcher (which excludes static but not fonts) doesn't intercept it - fix DocsLayout's nav.title (fumadocs' own mobile menu slot) to show the wordmark instead of the icon mark - add an isolated stacking context + higher z-index to both the docs and sim app footers so fumadocs' sticky z-20 sidebar can't paint over the footer content or the peel reveal
1 parent 93a05cc commit f26a205

5 files changed

Lines changed: 27 additions & 28 deletions

File tree

apps/docs/app/[lang]/layout.tsx

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ import {
1111
} from '@/components/docs-layout/sidebar-components'
1212
import { Footer } from '@/components/footer/footer'
1313
import { Navbar } from '@/components/navbar/navbar'
14-
import { SimLogoIcon } from '@/components/ui/sim-logo'
14+
import { SimWordmark } from '@/components/ui/sim-logo'
1515
import { i18n } from '@/lib/i18n'
1616
import { serializeJsonLd } from '@/lib/json-ld'
1717
import { source } from '@/lib/source'
@@ -102,7 +102,7 @@ export default async function Layout({ children, params }: LayoutProps) {
102102
<DocsLayout
103103
tree={source.pageTree[lang]}
104104
nav={{
105-
title: <SimLogoIcon className='size-[22px]' />,
105+
title: <SimWordmark className='h-[18px]' />,
106106
}}
107107
sidebar={{
108108
tabs: false,

apps/docs/app/api/og/route.tsx

Lines changed: 21 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@ const OG_CONTAINER_STYLE = {
2222
justifyContent: 'space-between',
2323
padding: '56px 64px',
2424
background: '#c3c3c3',
25-
fontFamily: 'Geist',
25+
fontFamily: 'Season',
2626
} satisfies CSSProperties
2727
const OG_HEADER_STYLE = {
2828
display: 'flex',
@@ -82,31 +82,29 @@ function wrapTitleLines(title: string, fontSize: number): string[] {
8282
}
8383

8484
/**
85-
* Loads a Google Font dynamically by fetching the CSS and extracting the font URL.
85+
* Loads a static (600/semibold) TTF instance of the site's own Season Sans
86+
* font — the platform's real brand/body font, also used by the library/blog
87+
* cover template this OG image matches. Instantiated from the variable font
88+
* at `apps/docs/app/fonts/SeasonSansUprightsVF.woff2` (`fonttools
89+
* varLib.instancer wght=600`, then flavor-stripped to plain TTF) rather than
90+
* loading the variable WOFF2 directly: Satori (`next/og`'s renderer) can't
91+
* parse variable fonts without excessive memory use, and can't parse WOFF2
92+
* at all ("Unsupported OpenType signature wOF2") — it needs an uncompressed
93+
* TTF/OTF. Fetched over HTTP since the edge runtime has no filesystem access
94+
* — served from `/static/fonts/` (not `/fonts/`) so it isn't intercepted by
95+
* the site's i18n proxy (`proxy.ts`), whose matcher excludes `static` but
96+
* not `fonts`.
8697
*/
87-
async function loadGoogleFont(font: string, weights: string, text: string): Promise<ArrayBuffer> {
88-
const url = `https://fonts.googleapis.com/css2?family=${font}:wght@${weights}&text=${encodeURIComponent(text)}`
89-
const cssResponse = await fetch(url, {
98+
async function loadSeasonFont(baseUrl: string): Promise<ArrayBuffer> {
99+
const response = await fetch(new URL('/static/fonts/SeasonSans-600-static.ttf', baseUrl), {
90100
next: { revalidate: FONT_CACHE_REVALIDATE_SECONDS },
91101
})
92102

93-
if (!cssResponse.ok) {
94-
throw new Error(`Failed to load font CSS: ${cssResponse.status} ${cssResponse.statusText}`)
103+
if (!response.ok) {
104+
throw new Error(`Failed to load font data: ${response.status} ${response.statusText}`)
95105
}
96106

97-
const css = await cssResponse.text()
98-
const resource = css.match(/src: url\((.+)\) format\('(opentype|truetype)'\)/)
99-
100-
if (resource) {
101-
const response = await fetch(resource[1], {
102-
next: { revalidate: FONT_CACHE_REVALIDATE_SECONDS },
103-
})
104-
if (response.ok) {
105-
return await response.arrayBuffer()
106-
}
107-
}
108-
109-
throw new Error('Failed to load font data')
107+
return await response.arrayBuffer()
110108
}
111109

112110
/** "sim" wordmark, no icon — same brandbook workmark geometry as the docs navbar/landing OG cards. */
@@ -154,7 +152,7 @@ export async function GET(request: NextRequest) {
154152
const { searchParams } = new URL(request.url)
155153
const title = searchParams.get('title') || 'Documentation'
156154

157-
const fontData = await loadGoogleFont('Geist', '400;500;600', title)
155+
const fontData = await loadSeasonFont(request.url)
158156
const fontSize = getTitleFontSize(title)
159157
const titleLines = wrapTitleLines(title, fontSize)
160158

@@ -176,9 +174,10 @@ export async function GET(request: NextRequest) {
176174
height: 630,
177175
fonts: [
178176
{
179-
name: 'Geist',
177+
name: 'Season',
180178
data: fontData,
181179
style: 'normal',
180+
weight: 600,
182181
},
183182
],
184183
}

apps/docs/components/footer/footer.tsx

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -130,9 +130,9 @@ function FooterColumn({ title, items }: { title: string; items: FooterItem[] })
130130

131131
export function Footer() {
132132
return (
133-
<div className='relative mt-[120px] pb-[320px] max-sm:mt-16 max-sm:pb-[200px] max-lg:mt-[88px]'>
133+
<div className='relative isolate mt-[120px] pb-[320px] max-sm:mt-16 max-sm:pb-[200px] max-lg:mt-[88px]'>
134134
<FooterPeel />
135-
<footer className='-mt-[320px] max-sm:-mt-[200px] relative z-10 w-full border-[var(--border)] border-t bg-[var(--bg)]'>
135+
<footer className='-mt-[320px] max-sm:-mt-[200px] relative z-30 w-full border-[var(--border)] border-t bg-[var(--bg)]'>
136136
<div className='mx-auto w-full max-w-[1460px] px-20 pt-16 pb-16 max-sm:px-5 max-lg:px-8 max-lg:pt-12 max-lg:pb-12'>
137137
<nav
138138
aria-label='Footer navigation'
155 KB
Binary file not shown.

apps/sim/app/(landing)/components/footer/footer.tsx

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -135,9 +135,9 @@ export function Footer() {
135135
// The bottom padding here (matching FooterPeel's own height, `footer-peel.tsx`)
136136
// is the "reveal window": the extra scroll room, past the footer's own opaque
137137
// background, where the sticky-pinned peel image becomes visible.
138-
<div className='relative mt-[120px] pb-[320px] max-sm:mt-16 max-sm:pb-[200px] max-lg:mt-[88px]'>
138+
<div className='relative isolate mt-[120px] pb-[320px] max-sm:mt-16 max-sm:pb-[200px] max-lg:mt-[88px]'>
139139
<FooterPeel />
140-
<footer className='-mt-[320px] max-sm:-mt-[200px] relative z-10 w-full border-[var(--border)] border-t bg-[var(--bg)]'>
140+
<footer className='-mt-[320px] max-sm:-mt-[200px] relative z-30 w-full border-[var(--border)] border-t bg-[var(--bg)]'>
141141
<div className='mx-auto w-full max-w-[1460px] px-20 pt-16 pb-16 max-sm:px-5 max-lg:px-8 max-lg:pt-12 max-lg:pb-12'>
142142
<nav
143143
aria-label='Footer navigation'

0 commit comments

Comments
 (0)