mirror of
https://github.com/hanzo-apps/tabs.git
synced 2026-09-15 19:32:29 +00:00
The export declared no icon and the bucket had none to serve, so /favicon.ico answered 404 and every Tabs pane sat behind a blank tab — in a product whose whole premise is telling one tab from another. public/ carries the Hanzo mark from @hanzo/brand as .svg and .ico, and the layout declares both. The .ico is there because a browser asks for it whether or not a page names one, and a bucket has no server to answer with anything else.
50 lines
2.0 KiB
TypeScript
50 lines
2.0 KiB
TypeScript
import type { ReactNode } from 'react';
|
|
import { colors } from '@hanzo/design';
|
|
import './globals.css';
|
|
|
|
export const metadata = {
|
|
metadataBase: new URL('https://tabs.hanzo.ai'),
|
|
title: { default: 'Hanzo Tabs', template: '%s — Hanzo Tabs' },
|
|
description: 'Keep tabs on your agents. A browser terminal workspace for machines you have linked.',
|
|
// Both files are the Hanzo mark from @hanzo/brand, copied into public/. The
|
|
// .ico is here because a browser asks for /favicon.ico whether or not a page
|
|
// declares one, and the bucket has no server to answer that with anything
|
|
// else — an undeclared icon is a 404 and a blank tab.
|
|
icons: {
|
|
icon: [
|
|
{ url: '/favicon.svg', type: 'image/svg+xml' },
|
|
{ url: '/favicon.ico', sizes: '48x48' },
|
|
],
|
|
},
|
|
openGraph: {
|
|
title: 'Hanzo Tabs — keep tabs on your agents',
|
|
description: 'Every shell your coding agents work in, split and tiled, from anywhere.',
|
|
url: 'https://tabs.hanzo.ai',
|
|
siteName: 'Hanzo Tabs',
|
|
},
|
|
};
|
|
|
|
export const viewport = {
|
|
// The browser chrome paints this before any stylesheet loads, so it is the one
|
|
// colour that cannot be a var() — it has to be a literal. Taking it from the
|
|
// token module rather than typing one keeps it the SAME literal the page then
|
|
// paints, which is what stops the address bar and the page disagreeing.
|
|
themeColor: colors.background,
|
|
// The workspace is full-bleed and the terminal owns the bottom edge.
|
|
viewportFit: 'cover' as const,
|
|
width: 'device-width',
|
|
initialScale: 1,
|
|
};
|
|
|
|
// No theme class on <html>: the tokens ARE the dark values at :root, and
|
|
// `.light` is what inverts them. A `dark` class selects nothing in either the
|
|
// design system or Tailwind here, so carrying one only suggests a switch that
|
|
// does not exist.
|
|
export default function RootLayout({ children }: { children: ReactNode }) {
|
|
return (
|
|
<html lang="en">
|
|
<body className="min-h-dvh bg-background text-foreground antialiased">{children}</body>
|
|
</html>
|
|
);
|
|
}
|