A field report on the visual language and engineering stack behind 2026 AI SaaS blogs, docs, and changelogs, plus the CJK layer needed to make the pattern work in Chinese.

Over the past six months I have been studying the blogs, changelogs, and documentation sites of leading AI SaaS companies. The question I kept coming back to was simple: why do they look so similar, yet still feel one level above ordinary SaaS sites?
When Anthropic, Vercel, Linear, Resend, Cursor, Stripe, and shadcn are compared side by side, the 2026 pattern becomes clear. Silicon Valley AI SaaS publishing has converged around a “Swiss modernism meets engineering taste” stack: semantic OKLCH tokens, Tailwind v4 @theme, shadcn/Radix component contracts, Next.js App Router, MDX / Velite / Fumadocs content layers, Shiki dual-theme code blocks, dynamic OG with @vercel/og, and soft route motion through the View Transitions API.
Visually, these sites have moved away from pure #000 and obvious skeuomorphic gradients. They now favor warm near-black surfaces, restrained monochrome systems, and one carefully rationed accent color. Typography has become identity itself. Vercel has Geist. OpenAI has OpenAI Sans. Anthropic has Anthropic Sans / Serif / Mono. Linear uses Inter Display.
This essay connects the visual language, engineering decisions, design-system contracts, and Chinese localization layer into one practical map. The goal is that an experienced front-end engineer or designer can read it and understand how these companies build this feeling, why it works, and how to reproduce it in a Chinese-language context.
When Tailwind v4 shipped on January 22, 2025, the announcement said the quiet part out loud:
We've upgraded the entire default color palette from rgb to oklch, taking advantage of the wider gamut to make the colors more vivid in places where we were previously limited by the sRGB color space.
Source: Tailwind CSS v4.0 announcement.
shadcn/ui followed. Since March 2025, new projects default to the new-york style, and the color system moved from HSL to OKLCH as a non-breaking change. Radix Themes, Vercel Geist, and Linear's color tooling have all moved in the same direction.
OKLCH matters for three reasons:
@supports (color: oklch(...)) gives a fallback path.Anthropic's website no longer feels like a #000 site. Refero's breakdown of Anthropic's palette says it well:
Anthropic's site runs on warm ivory parchment — not white, not gray, but the color of aged paper under good light.
Anthropic's public Brand Guidelines skill lists #141413 for deep surfaces, #faf9f5 for ivory, #d97757 for Clay, #788c5d for Olive, and #6a9bcc for Blue.
Linear made the same shift from the opposite direction. In How we redesigned the Linear UI part II, the team wrote:
We continued polishing the new color theme … by limiting how much chrome (blue in our case) was used in the calculations applied to our color system.
LogRocket's 2025 Linear Design review makes the point even more directly: Linear itself reduced glass and complex gradients, moving away from monochrome blue toward monochrome black and white.
Whether you look at Anthropic, Vercel, Linear, or their imitators, semantic tokens have mostly converged on the shadcn theme contract:
Every color has a matching -foreground. Components consume variables rather than raw values. Switching :root and .dark becomes the theme system.
Radix Colors' 12-step scale is the shared mental model: steps 1-2 are backgrounds, 3-5 are component states, 6-8 are borders, 9-10 are solid fills, and 11-12 are text.
This is the most important design shift. In 2025 and 2026, leading AI SaaS companies treat typography as product identity.
Vercel Geist launched in October 2023, created with Basement Studio. Google Fonts credits Andrés Briganti, Mateo Zaragoza, Guillermo Rauch, Evil Rabbit, José Rago, and Facundo Santana. The official README is explicit:
Geist has been influenced and inspired by the following typefaces: Inter, Univers, SF Mono, SF Pro, Suisse International, ABC Diatype Mono, and ABC Diatype.
Vercel describes Geist as a typeface that embodies simplicity, minimalism, and speed, drawing from the Swiss design movement. It is SIL OFL 1.1, available as the `geist` npm package, and can be self-hosted through import { GeistSans, GeistMono } from "geist/font" with no external font request and no layout shift.
OpenAI Sans was part of OpenAI's first major rebrand in February 2025, created with ABC Dinamo. CXO Digitalpulse's write-up describes it as blending geometric precision and functionality with a rounded, approachable character. The family unified several typefaces previously used across OpenAI's product surfaces and tied them to the shared “emotive point” motif that appears in ChatGPT's cursor and brand system.
Anthropic's type trio is explained clearly by Refero. Anthropic Serif is used for dark editorial display moments. Anthropic Sans handles light-surface headings. Anthropic Mono marks metadata such as dates and categories. The most interesting detail is that emphasis is not mostly color-based. It is a thick double underline, replacing accent color as the primary decorative emphasis mechanism.
Linear wrote in its redesign notes that it started using Inter Display to add expression to headings while keeping regular Inter for the rest of the interface. Inter is free, open, and created by Figma designer Rasmus Andersson. That choice reflects the broader engineering taste shared by Linear, Tailwind, and Resend: premium feel without luxury-font dependency.
Resend wrote in Rebranding Resend that Domaine became the editorial headline typeface, Favorit stayed for subheadings, and Inter remained the primary body typeface. Resend also says directly that it is dark-mode first.
The stable 2026 SaaS blog pairing is therefore: Domaine Display or Tiempos for editorial headings, Inter for body text, and Geist Mono / JetBrains Mono / Sohne Mono for code.
The dominant layout is a 640-720px content column with full-width or bleed media when needed. Western body text tends to sit around 1.5-1.65 line-height. CJK text needs more air, typically 1.7-1.8. Typotheque's CJK typography article puts it this way:
For CJK text, which tends to have a higher density of information per character, a leading value of around 1.7 improves both readability and aesthetic balance.
Responsive type is usually handled with clamp() and a modular scale.
This design language is not decoration-free. The decoration has moved into the system layer.
At React Conf 2025, React moved <ViewTransition> from experimental to canary. Chrome DevRel's 2025 update says:
They announced react@experimental support back in April and this week, at React Conf, they moved support of it into react@canary which means the design is close to final.
Firefox 144 brought same-document view transitions into Baseline status, and web.dev now treats them as newly available. Next.js exposes `experimental.viewTransition` and documents App Router patterns in its View transitions guide.
The common use cases are list-to-detail shared element morphs, soft Suspense reveal, directional navigation animation, and scroll-driven reading progress.
Always honor reduced motion:
Vercel's Next.js docs, Astro, Anthony Fu's antfu.me, and Fumadocs all default to Shiki.
Shiki matters for three reasons:
codeToHtml(code, { themes: { light: "github-light", dark: "github-dark" } }) generates both theme variables server-side. CSS switches between light and dark without client-side highlighting JavaScript. See the implementations from Afnizar and Nikolai.The modern code block usually includes filename chrome, line numbers, highlighted lines, diff markers, copy button, and language badge. Anthropic keeps it in the ivory editorial system. Vercel and Linear use mono precision. Resend uses dark-first cards with a restrained blue accent.
Contentlayer is effectively stalled. In Migrating from Contentlayer to Content Collections, the Dub.co team writes:
ever since their main sponsor, Stackbit, was acquired by Netlify, Contentlayer has been effectively unmaintained.
The original author also acknowledged in GitHub issue #429 that reduced sponsorship left him with only limited time for the project.
The 2026 choice matrix looks like this:
@next/mdx: minimal MDX compilation.PkgPulse's 2026 comparison compares Fumadocs, Nextra v4, and Starlight. The practical takeaway is that Fumadocs wins on headless composition, while Nextra wins on immediate defaults.
My default recommendation:
next/mdx.Tailwind v4 moves token definition from tailwind.config.js into CSS @theme. The shadcn theming docs show the shape:
@theme inline is the key. Tailwind utilities still reference CSS variables, so runtime theme changes work by changing :root. Style Dictionary and Radix Colors are best treated as scale-generation tools, with `@radix-ui/colors` remaining the most stable 12-step scale source.
The shadcn model is now the default React pattern: the CLI copies component source into components/ui, the team owns the code, and CVA handles variants.
In GitHub Discussion #9754, the recommendation is to edit the copied source rather than wrapping every primitive in another abstraction layer. Wrappers often break the token contract.
For MDX, the idiomatic pattern is a central mdx-components.tsx mapping:
PortableText is different because it is JSON. It is database-friendly and multi-surface by default, but it requires serializers for blocks, marks, lists, and custom types. Sanity recommends @portabletext/react. For code blocks, the clean pattern is to use a highlighter singleton, detect block._type === "code", call codeToHtml, and render the generated HTML.
OG images: Vercel introduced `@vercel/og` in 2022. It is powered by Satori. Vercel's benchmark claims:
Vercel OG (500KB) is 100x more lightweight than Chromium + Puppeteer (50MB), which allows functions to start almost instantly.
In App Router, import { ImageResponse } from "next/og" is enough. Vercel's OG docs note the important limitation: Satori supports flexbox, not grid, and the bundle must stay within limits.
Fonts: next/font/google and next/font/local self-host fonts, subset them, apply font-display: swap, and reduce CLS. Vercel's next/font article explains the performance rationale. CJK fonts need a separate strategy because full Chinese fonts are much heavier.
Dark mode: next-themes, class="dark", and <html suppressHydrationWarning> remain the simple default.
Search and comments: use Pagefind for static search, Algolia DocSearch for larger docs, Fumadocs' built-in search when already using Fumadocs, and Giscus for GitHub Discussions-backed comments.
Philosophy: Swiss modernism, engineering precision, black-and-white clarity.
Practical takeaways:
next/font and the geist package.Philosophy: 12 semantic scale steps with explicit jobs. Steps 1-2 are backgrounds, 3-5 are component states, 6-8 are borders, 9-10 are solid fills, and 11-12 are text. DeepWiki's breakdown adds the APCA-oriented reading of those roles.
Practical takeaways:
Philosophy: you own the code. It is not a black-box npm package.
Practical takeaways:
Linear Method is opinionated software thinking applied to product operations. The page says:
There is a lost art of building true quality software. To bring back the right focus, here are the foundational ideas Linear is built on.
Practical takeaways:
The Silicon Valley visual system is easy to copy. The hard part is making it work for Chinese.
vinta/pangu.js is the de facto tool for spacing between CJK and Latin text:
Do not run it over raw Markdown. It can break links and code blocks. Apply it after HTML render or only to plain text nodes.
Chinese article typography needs this layer:
The problem with Chinese fonts is size. Full Source Han Sans or Noto Sans CJK files can be multiple megabytes. The solution is Unicode-range subsetting through a CDN.
guangzhengli's template is currently one of the most complete Chinese-community replications of the Silicon Valley engineering blog pattern: content under src/content/blog, config in src/lib/config.ts, Giscus, RSS / Atom / JSON Feed, Xiaohongshu / WeChat / Buy Me a Coffee links, and edge/runtime options.
Chinese developers on Jike, V2EX, and Juejin have largely absorbed shadcn/ui, Tailwind v4, Geist, and Linear design as a shared taste layer. At the same time, the criticism is fair: LogRocket's Linear design review points out that this style can make SaaS sites feel identical.
The strongest Chinese adaptation combines engineering minimalism with Chinese editorial texture: LXGW WenKai body text, Geist Mono code, Anthropic-style ivory surfaces, and a denser link tradition closer to Ruan Yifeng or SSPAI.
The practical obstacles are:
font-display: swap and compatible fallbacks.@import "tailwindcss" and @custom-variant dark (&:is(.dark *)).:root and .dark.@theme inline.@radix-ui/colors as the scale source.next/font/local.font-display: swap.new-york, neutral base color, and CSS variables.cn() as clsx + tailwind-merge.@portabletext/react + Shiki.@vercel/og for dynamic OG.next-themes and hydration-safe dark mode.experimental.viewTransition or a local document.startViewTransition wrapper.word-break: keep-all, line-break: strict, overflow-wrap: break-word, text-wrap: balance, and line-height: 1.75.#000 dark mode; use warm near-black.pangu.js against raw Markdown.If this was useful, I would love to hear how your own blog is built and which stack you ended up choosing.