SPB Git

spb/ai-atlas

Public
3.9 KB · 79 lines tsx
1import { ImageResponse } from 'next/og';2import { api, safe } from '@/lib/api';3import { fmtInt, num } from '@/lib/format';4import { SITE_NAME, TAGLINE } from '@/lib/site';56export const runtime = 'nodejs';7export const alt = `${SITE_NAME} — ${TAGLINE}`;8export const size = { width: 1200, height: 630 };9export const contentType = 'image/png';1011/** Default Open Graph image: brand + live counters from /stats when the API is reachable (brand only otherwise). */12export default async function OpenGraphImage() {13  const stats = await safe(api.stats());14  const counters: [string, string][] = stats15    ? [16        ['Models', fmtInt(stats.entities?.model)],17        ['Companies', fmtInt(num(stats.entities?.company) ?? num(stats.entities?.organization))],18        ['Papers', fmtInt(stats.entities?.paper)],19        ['Change events', fmtInt(stats.change_events)],20        ['Sources', fmtInt(stats.sources)],21      ].filter((c) => c[1] !== '—') as [string, string][]22    : [];2324  return new ImageResponse(25    (26      <div27        style={{28          width: '100%',29          height: '100%',30          display: 'flex',31          flexDirection: 'column',32          justifyContent: 'space-between',33          padding: '64px 72px',34          background: 'linear-gradient(160deg, #12151b 0%, #0b0d11 55%, #0b0d11 100%)',35          color: '#e9ebf0',36          fontFamily: 'sans-serif',37          position: 'relative',38        }}39      >40        <div style={{ position: 'absolute', right: -140, top: -160, width: 640, height: 640, borderRadius: 999, background: 'radial-gradient(circle at 40% 40%, rgba(109,149,255,0.18), rgba(11,13,17,0) 70%)', display: 'flex' }} />41        <div style={{ display: 'flex', alignItems: 'center', gap: 20 }}>42          <svg width="64" height="64" viewBox="0 0 32 32" fill="none">43            <circle cx="16" cy="16" r="13" stroke="#e9ebf0" strokeWidth="1.6" />44            <path d="M16 3c-4.4 3.2-6.6 7.6-6.6 13s2.2 9.8 6.6 13M16 3c4.4 3.2 6.6 7.6 6.6 13s-2.2 9.8-6.6 13M3 16h26" stroke="#e9ebf0" strokeWidth="1.2" opacity="0.7" />45            <path d="M9.4 9.5L16 16l6.6-6.5M16 16l-5.2 8.4M16 16l7.4 5.6" stroke="#e9ebf0" strokeWidth="1.2" opacity="0.55" />46            <circle cx="16" cy="16" r="2.4" fill="#6d95ff" />47            <circle cx="9.4" cy="9.5" r="1.7" fill="#e9ebf0" />48            <circle cx="22.6" cy="9.5" r="1.7" fill="#e9ebf0" />49            <circle cx="10.8" cy="24.4" r="1.7" fill="#e9ebf0" />50            <circle cx="23.4" cy="21.6" r="1.7" fill="#e9ebf0" />51          </svg>52          <div style={{ display: 'flex', fontSize: 38, fontWeight: 600, letterSpacing: -1 }}>53            <span>AI</span>54            <span style={{ color: '#a3a9b8', marginLeft: 10, fontWeight: 500 }}>Atlas</span>55          </div>56        </div>57        <div style={{ display: 'flex', flexDirection: 'column', gap: 22 }}>58          <div style={{ fontSize: 68, fontWeight: 600, lineHeight: 1.02, letterSpacing: -2.5, maxWidth: 940, display: 'flex' }}>{TAGLINE}.</div>59          <div style={{ fontSize: 25, color: '#a3a9b8', display: 'flex' }}>Models · companies · research · providers & pricing · benchmarks · hardware — with provenance and history</div>60        </div>61        <div style={{ display: 'flex', justifyContent: 'space-between', alignItems: 'flex-end', color: '#6f7688', fontSize: 22 }}>62          <span>www.ai-atlas.co</span>63          {counters.length > 0 && (64            <div style={{ display: 'flex', gap: 40 }}>65              {counters.map(([label, value]) => (66                <div key={label} style={{ display: 'flex', flexDirection: 'column', alignItems: 'flex-end' }}>67                  <span style={{ fontSize: 34, fontWeight: 600, color: '#e9ebf0', letterSpacing: -1 }}>{value}</span>68                  <span style={{ fontSize: 15, letterSpacing: 2, textTransform: 'uppercase' }}>{label}</span>69                </div>70              ))}71            </div>72          )}73        </div>74      </div>75    ),76    { ...size },77  );78}79
Files · 0f064299de6124ef553ef1bf8a851ae63aeae373
Menu

Theme