From b0c87cb29e65917dc6b1112ead010d4303ea7c06 Mon Sep 17 00:00:00 2001 From: Mark Otto Date: Fri, 2 Oct 2026 16:33:30 -0700 Subject: [PATCH 1/3] docs(docs): graduate edit mode from beta Present edit mode as a supported Diffs capability across the landing page and guide. Remove the beta and experimental notices, and refresh the product summary to describe the current feature set. --- apps/docs/app/(diffs)/_edit/EditHero.tsx | 2 -- apps/docs/app/(diffs)/_home/AgentDemoSection.tsx | 1 - apps/docs/app/(diffs)/docs/Edit/content.mdx | 4 ---- apps/docs/lib/product-config.ts | 4 ++-- 4 files changed, 2 insertions(+), 9 deletions(-) diff --git a/apps/docs/app/(diffs)/_edit/EditHero.tsx b/apps/docs/app/(diffs)/_edit/EditHero.tsx index 265e0c779..634aa9113 100644 --- a/apps/docs/app/(diffs)/_edit/EditHero.tsx +++ b/apps/docs/app/(diffs)/_edit/EditHero.tsx @@ -3,14 +3,12 @@ import { IconArrowRight, IconBook } from '@pierre/icons'; import Link from 'next/link'; -import { BetaBadge } from '@/components/BetaBadge'; import { Button } from '@/components/ui/button'; export function EditHero() { return (
-

Edit files and diffs

diff --git a/apps/docs/app/(diffs)/_home/AgentDemoSection.tsx b/apps/docs/app/(diffs)/_home/AgentDemoSection.tsx index ef0c46d95..315f0eda6 100644 --- a/apps/docs/app/(diffs)/_home/AgentDemoSection.tsx +++ b/apps/docs/app/(diffs)/_home/AgentDemoSection.tsx @@ -12,7 +12,6 @@ export function AgentDemoSection({ prerenderedDiffs }: AgentDemoSectionProps) {
diff --git a/apps/docs/app/(diffs)/docs/Edit/content.mdx b/apps/docs/app/(diffs)/docs/Edit/content.mdx index 943fed469..90a63edb9 100644 --- a/apps/docs/app/(diffs)/docs/Edit/content.mdx +++ b/apps/docs/app/(diffs)/docs/Edit/content.mdx @@ -1,9 +1,5 @@ ## Edit mode -}> - Edit mode is experimental and subject to change. - - Edit mode adds text editing, multiple selections, undo and redo, search and replace, remote carets, markers, and custom selection actions to Pierre file and diff components. The existing component continues to own syntax highlighting, diff --git a/apps/docs/lib/product-config.ts b/apps/docs/lib/product-config.ts index 0a96a321c..578f7d2d4 100644 --- a/apps/docs/lib/product-config.ts +++ b/apps/docs/lib/product-config.ts @@ -26,9 +26,9 @@ export const PRODUCTS: Record = { name: 'Diffs', tagline: 'Render diffs and\u00A0code, now with edit', description: - '@pierre/diffs is an open source diff and code rendering library. Built on Shiki for syntax highlighting and theming, super customizable, and packed with features.', + '@pierre/diffs is an open source diff and code rendering library. Rich syntax highlighting, edit mode, support for custom and Shiki themes, virtualization, and more.', llmsDescription: - 'An open source diff and code rendering library for the web. Built on Shiki for syntax highlighting, with React and vanilla JS APIs, virtualization, SSR support, and extensive theming.', + 'An open source diff and code rendering library with rich syntax highlighting, edit mode, support for custom and Shiki themes, virtualization, and more. Available with React and vanilla JS APIs', basePath: '', docsPath: '/docs', themePath: '/theme', From 41069b87d7bf79a8aaf6f82aa6b949bde9a51094 Mon Sep 17 00:00:00 2001 From: Mark Otto Date: Fri, 2 Oct 2026 16:33:52 -0700 Subject: [PATCH 2/3] feat(docs): promote Highlights on Diffs home Show a focused Highlights promotion before the edit section, with a responsive benchmark preview and a direct call to action. Reuse the Highlights hero, card, bar, and benchmark data so the banner stays aligned with the dedicated product page. Center and cap the graph, then fade its intentional bottom crop across every viewport size. --- .../(diffs)/_home/HighlightsBanner.module.css | 73 ++++++++++++ .../app/(diffs)/_home/HighlightsBanner.tsx | 105 ++++++++++++++++++ apps/docs/app/(diffs)/_home/Home.tsx | 2 + .../HighlightsPerformanceBenchmarks.tsx | 67 ++++------- .../highlights/performanceBenchmarkData.ts | 27 +++++ 5 files changed, 230 insertions(+), 44 deletions(-) create mode 100644 apps/docs/app/(diffs)/_home/HighlightsBanner.module.css create mode 100644 apps/docs/app/(diffs)/_home/HighlightsBanner.tsx create mode 100644 apps/docs/app/(diffs)/highlights/performanceBenchmarkData.ts diff --git a/apps/docs/app/(diffs)/_home/HighlightsBanner.module.css b/apps/docs/app/(diffs)/_home/HighlightsBanner.module.css new file mode 100644 index 000000000..622bc5db9 --- /dev/null +++ b/apps/docs/app/(diffs)/_home/HighlightsBanner.module.css @@ -0,0 +1,73 @@ +.benchmarkStage { + position: relative; + isolation: isolate; + min-width: 0; + padding: 0.5rem; + overflow: hidden; + border-radius: var(--radius); +} + +.benchmarkStage::before { + position: absolute; + z-index: 0; + inset: -22% -18%; + pointer-events: none; + content: ''; + background: + radial-gradient(circle at 24% 68%, rgb(8 192 239 / 42%), transparent 45%), + radial-gradient(circle at 60% 35%, rgb(198 53 228 / 48%), transparent 48%), + radial-gradient(circle at 82% 68%, rgb(252 43 115 / 38%), transparent 44%), + radial-gradient(circle at 92% 38%, rgb(254 140 44 / 34%), transparent 40%); + filter: blur(1.75rem); + opacity: 0.95; + mix-blend-mode: screen; + mask-image: radial-gradient( + ellipse 54% 52% at center, + black 25%, + rgb(0 0 0 / 90%) 45%, + rgb(0 0 0 / 45%) 58%, + transparent 66% + ); +} + +.benchmarkCard { + position: relative; + z-index: 1; + inline-size: 100%; + max-inline-size: 33.75rem; + margin-inline: auto; + background-color: color-mix(in oklch, var(--background) 82%, transparent); + box-shadow: + 0 24px 48px -24px rgb(0 0 0 / 95%), + inset 0 1px 0 rgb(255 255 255 / 5%); +} + +.benchmarkStage::after { + position: absolute; + z-index: 2; + inset-inline: 0.5rem; + bottom: 0; + block-size: 10rem; + pointer-events: none; + content: ''; + background: linear-gradient( + to bottom, + transparent, + color-mix(in oklch, var(--background) 55%, transparent) 58%, + color-mix(in oklch, var(--background) 85%, transparent) 90% + ); + -webkit-backdrop-filter: blur(0.5rem); + backdrop-filter: blur(0.5rem); + -webkit-mask-image: linear-gradient( + to bottom, + transparent, + rgb(0 0 0 / 35%) 38%, + black 78% + ); + mask-image: linear-gradient( + to bottom, + transparent, + rgb(0 0 0 / 35%) 38%, + black 78% + ); +} diff --git a/apps/docs/app/(diffs)/_home/HighlightsBanner.tsx b/apps/docs/app/(diffs)/_home/HighlightsBanner.tsx new file mode 100644 index 000000000..9840f208c --- /dev/null +++ b/apps/docs/app/(diffs)/_home/HighlightsBanner.tsx @@ -0,0 +1,105 @@ +import { IconArrowRight } from '@pierre/icons'; +import Link from 'next/link'; + +import { BenchmarkBar } from '../highlights/BenchmarkBar'; +import cardStyles from '../highlights/HighlightsBenchmarkCard.module.css'; +import rainbowStyles from '../highlights/HighlightsRainbow.module.css'; +import { + HIGHLIGHTS_LARGE_FILE_RESULTS, + HIGHLIGHTS_THROUGHPUT_MAXIMUM, +} from '../highlights/performanceBenchmarkData'; +import styles from './HighlightsBanner.module.css'; +import { Button } from '@/components/ui/button'; + +export function HighlightsBanner() { + return ( +
+
+

+ Introducing +

+

+ + + + Highlights + + +

+

+ Super-fast syntax highlighting for code and diffs, written from the + ground up to be nearly 300× faster than Shiki. Now in beta. +

+ +
+ + +
+ ); +} + +// Keeps the benchmark recognizable while hiding duplicate chart data from +// assistive technology; the promo copy and button carry the actionable content. +function CompactPerformancePreview() { + return ( + + ); +} diff --git a/apps/docs/app/(diffs)/_home/Home.tsx b/apps/docs/app/(diffs)/_home/Home.tsx index b030fbb90..dd6825bb2 100644 --- a/apps/docs/app/(diffs)/_home/Home.tsx +++ b/apps/docs/app/(diffs)/_home/Home.tsx @@ -30,6 +30,7 @@ import { SplitUnified } from '../_examples/SplitUnified/SplitUnified'; import { TOKEN_HOVER_EXAMPLE } from '../_examples/TokenHover/constants'; import { TokenHover } from '../_examples/TokenHover/TokenHover'; import { AgentDemoSection } from './AgentDemoSection'; +import { HighlightsBanner } from './HighlightsBanner'; import { preloadAuiPrerenderedDiffs } from './preloadAuiDiffs'; import { HeadingAnchors } from '@/components/docs/HeadingAnchors'; import Footer from '@/components/Footer'; @@ -48,6 +49,7 @@ export default function Home() {
+ diff --git a/apps/docs/app/(diffs)/highlights/HighlightsPerformanceBenchmarks.tsx b/apps/docs/app/(diffs)/highlights/HighlightsPerformanceBenchmarks.tsx index 3343ecadb..6effa2a52 100644 --- a/apps/docs/app/(diffs)/highlights/HighlightsPerformanceBenchmarks.tsx +++ b/apps/docs/app/(diffs)/highlights/HighlightsPerformanceBenchmarks.tsx @@ -3,41 +3,18 @@ import type { ReactNode } from 'react'; import { BenchmarkBar } from './BenchmarkBar'; import styles from './HighlightsBenchmarkCard.module.css'; +import { + HIGHLIGHTS_LARGE_FILE_RESULTS, + HIGHLIGHTS_THROUGHPUT_MAXIMUM, +} from './performanceBenchmarkData'; import { cn } from '@/lib/utils'; -// Published string-I/O results from packages/highlights/benchmark/README.md, -// recorded September 25, 2026. Keep the reported ratios rather than deriving -// them from the table's independently rounded throughput values. -const largeFileResults = [ - { - language: 'TypeScript', - size: '517 KiB', - speedup: 294, - }, - { - language: 'HTML', - size: '474 KiB', - speedup: 237, - }, - { - language: 'CSS', - size: '379 KiB', - speedup: 248, - }, - { - language: 'JSONC', - size: '292 KiB', - speedup: 148, - }, -]; - const memoryResults = [ { name: 'Highlights', peakRss: 49 }, { name: 'Shiki JS', peakRss: 155 }, { name: 'Shiki Wasm', peakRss: 346 }, ]; -const throughputMaximum = 300; const memoryMaximum = 400; // Renders different benchmark units against an explicit zero-based maximum. @@ -117,24 +94,26 @@ export function HighlightsPerformanceBenchmarks() {

- {largeFileResults.map(({ language, size, speedup }) => ( -
- - - {language} + {HIGHLIGHTS_LARGE_FILE_RESULTS.map( + ({ language, size, speedup }) => ( +
+ + + {language} + + {size} - {size} - - } - value={speedup} - maximum={throughputMaximum} - formatValue={(value) => `${value}×`} - highlights - /> -
- ))} + } + value={speedup} + maximum={HIGHLIGHTS_THROUGHPUT_MAXIMUM} + formatValue={(value) => `${value}×`} + highlights + /> +
+ ) + )}
diff --git a/apps/docs/app/(diffs)/highlights/performanceBenchmarkData.ts b/apps/docs/app/(diffs)/highlights/performanceBenchmarkData.ts new file mode 100644 index 000000000..3d7104c84 --- /dev/null +++ b/apps/docs/app/(diffs)/highlights/performanceBenchmarkData.ts @@ -0,0 +1,27 @@ +// Published string-I/O results from packages/highlights/benchmark/README.md, +// recorded September 25, 2026. Keep the reported ratios rather than deriving +// them from the table's independently rounded throughput values. +export const HIGHLIGHTS_LARGE_FILE_RESULTS = [ + { + language: 'TypeScript', + size: '517 KiB', + speedup: 294, + }, + { + language: 'HTML', + size: '474 KiB', + speedup: 237, + }, + { + language: 'CSS', + size: '379 KiB', + speedup: 248, + }, + { + language: 'JSONC', + size: '292 KiB', + speedup: 148, + }, +] as const; + +export const HIGHLIGHTS_THROUGHPUT_MAXIMUM = 300; From e347f6fef43abd25e91c9d67667337468795d0aa Mon Sep 17 00:00:00 2001 From: Mark Otto Date: Tue, 6 Oct 2026 12:53:19 -0700 Subject: [PATCH 3/3] feat(docs): refine the Highlights banner surface Visitors now see a cleaner Highlights preview with responsive spacing, a surface-matched fade, and a consistently legible call-to-action. Move the banner layout into its CSS module, remove the decorative glow, and add a reusable inverse Button variant for dark promotional surfaces. --- .../(diffs)/_home/HighlightsBanner.module.css | 83 ++++++++++++------- .../app/(diffs)/_home/HighlightsBanner.tsx | 12 ++- apps/docs/components/ui/button.tsx | 2 + 3 files changed, 62 insertions(+), 35 deletions(-) diff --git a/apps/docs/app/(diffs)/_home/HighlightsBanner.module.css b/apps/docs/app/(diffs)/_home/HighlightsBanner.module.css index 622bc5db9..bb50e9dee 100644 --- a/apps/docs/app/(diffs)/_home/HighlightsBanner.module.css +++ b/apps/docs/app/(diffs)/_home/HighlightsBanner.module.css @@ -1,35 +1,62 @@ +.banner { + --highlights-banner-surface: var(--background); + + display: grid; + min-width: 0; + padding: calc(var(--spacing) * 6); + padding-bottom: 0; + margin-bottom: calc(var(--spacing) * 16); + overflow: hidden; + color: var(--color-foreground); + border-radius: var(--radius-xl); + box-shadow: + var(--tw-inset-shadow), var(--tw-inset-ring-shadow), + var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--shadow-sm); + gap: calc(var(--spacing) * 8); +} + +/* Match the shared card's translucent dark-page surface after compositing it. */ +/* stylelint-disable-next-line selector-pseudo-class-no-unknown */ +:global(:root.dark) .banner { + --highlights-banner-surface: color-mix( + in oklch, + var(--muted) 50%, + var(--background) + ); +} + +@media (width >= 640px) { + .banner { + padding: calc(var(--spacing) * 8); + padding-bottom: 0; + } +} + +@media (width >= 768px) { + .banner { + grid-template-columns: minmax(0, 0.9fr) minmax(0, 1.1fr); + align-items: center; + gap: calc(var(--spacing) * 6); + } +} + +@media (width >= 1024px) { + .banner { + grid-template-columns: minmax(0, 0.85fr) minmax(0, 1.15fr); + padding-top: calc(var(--spacing) * 12); + padding-inline: calc(var(--spacing) * 12); + gap: calc(var(--spacing) * 10); + } +} + .benchmarkStage { position: relative; - isolation: isolate; min-width: 0; padding: 0.5rem; overflow: hidden; border-radius: var(--radius); } -.benchmarkStage::before { - position: absolute; - z-index: 0; - inset: -22% -18%; - pointer-events: none; - content: ''; - background: - radial-gradient(circle at 24% 68%, rgb(8 192 239 / 42%), transparent 45%), - radial-gradient(circle at 60% 35%, rgb(198 53 228 / 48%), transparent 48%), - radial-gradient(circle at 82% 68%, rgb(252 43 115 / 38%), transparent 44%), - radial-gradient(circle at 92% 38%, rgb(254 140 44 / 34%), transparent 40%); - filter: blur(1.75rem); - opacity: 0.95; - mix-blend-mode: screen; - mask-image: radial-gradient( - ellipse 54% 52% at center, - black 25%, - rgb(0 0 0 / 90%) 45%, - rgb(0 0 0 / 45%) 58%, - transparent 66% - ); -} - .benchmarkCard { position: relative; z-index: 1; @@ -53,11 +80,11 @@ background: linear-gradient( to bottom, transparent, - color-mix(in oklch, var(--background) 55%, transparent) 58%, - color-mix(in oklch, var(--background) 85%, transparent) 90% + color-mix(in oklch, var(--highlights-banner-surface) 55%, transparent) 58%, + var(--highlights-banner-surface) 90% ); - -webkit-backdrop-filter: blur(0.5rem); - backdrop-filter: blur(0.5rem); + -webkit-backdrop-filter: blur(0.375rem); + backdrop-filter: blur(0.375rem); -webkit-mask-image: linear-gradient( to bottom, transparent, diff --git a/apps/docs/app/(diffs)/_home/HighlightsBanner.tsx b/apps/docs/app/(diffs)/_home/HighlightsBanner.tsx index 9840f208c..150400be4 100644 --- a/apps/docs/app/(diffs)/_home/HighlightsBanner.tsx +++ b/apps/docs/app/(diffs)/_home/HighlightsBanner.tsx @@ -13,10 +13,8 @@ import { Button } from '@/components/ui/button'; export function HighlightsBanner() { return ( -
-
+
+

Introducing

@@ -42,8 +40,8 @@ export function HighlightsBanner() {