- Theme toggle in the nav: follows the device until chosen, remembers the choice, sets data-theme before first paint (no flash). - Site search: Cmd/Ctrl+K command palette on every marketing page, opened by the shortcut, a nav Search button, or the Docs search field. Searches pages, docs topics and articles that have a page. - Docs topics move to content.ts so the page and the search index share one source. - next.config: allowedDevOrigins for private network ranges so a phone on the same Wi-Fi hydrates the dev site. Dev only. - Sun and moon icons added by hand (not Figma exports); noted in the icons README. Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
29 lines
1.1 KiB
TypeScript
29 lines
1.1 KiB
TypeScript
import { GeistMono } from 'geist/font/mono';
|
|
import { GeistSans } from 'geist/font/sans';
|
|
import type { Metadata } from 'next';
|
|
import type { ReactNode } from 'react';
|
|
import { CommandPaletteProvider } from '../../src/marketing/CommandPalette.tsx';
|
|
import { themeInitScript } from '../../src/marketing/theme.ts';
|
|
import '../../src/styles/tokens.css';
|
|
import '../../src/styles/marketing.css';
|
|
import '../../src/styles/product.css';
|
|
|
|
export const metadata: Metadata = {
|
|
title: { default: 'Wursor', template: '%s · Wursor' },
|
|
description: 'Your website, handled. Tell Wursor what to change. Watch it work. Approve what you like.',
|
|
};
|
|
|
|
export default function MarketingLayout({ children }: { children: ReactNode }) {
|
|
return (
|
|
// suppressHydrationWarning: the head script sets data-theme on <html> before React hydrates.
|
|
<html lang="en" className={`${GeistSans.variable} ${GeistMono.variable}`} suppressHydrationWarning>
|
|
<head>
|
|
<script dangerouslySetInnerHTML={{ __html: themeInitScript }} />
|
|
</head>
|
|
<body>
|
|
<CommandPaletteProvider>{children}</CommandPaletteProvider>
|
|
</body>
|
|
</html>
|
|
);
|
|
}
|