Structuring your head tag
Document skeleton for Zazz pages: head configuration, stylesheet linking, module resolution, and landmark structure.
Zazz uses standard HTML document conventions for style loading, script initialization, and view transitions.
Minimal head
Style-only pages require color-scheme declaration and one stylesheet link:
<head> <meta charset="utf-8"> <meta name="viewport" content="width=device-width, initial-scale=1"> <!-- Paint the right theme (background, form controls, scrollbars) before CSS loads --> <meta name="color-scheme" content="light dark"> <!-- Zazz styles: one bundle (index.css @imports every layer in cascade order) --> <link rel="stylesheet" href="./zazz/index.css"></head>Color scheme declaration
The <meta name="color-scheme" content="light dark"> tag tells the browser to render native UI (canvas background, scrollbars, inputs) in the correct theme before CSS loads.
Keep the meta tag and CSS :root { color-scheme: light dark; } in sync. The meta tag prevents initial paint flashes; the CSS property controls light-dark().
Stylesheet link
Point one <link> at index.css:
<link rel="stylesheet" href="./zazz/index.css" />A <link rel="preload" as="style"> for index.css is unnecessary. Same-document stylesheet links in <head> already block render at highest network priority.
Override stylesheet
Load custom overrides after index.css:
<link rel="stylesheet" href="./zazz/index.css" /> <link rel="stylesheet" href="./your-styles.css" />Loading Geist font
Zazz defaults to Geist via --font-family-body and --font-family-heading:
<link rel="preconnect" href="https://fonts.googleapis.com" />
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin />
<link
href="https://fonts.googleapis.com/css2?family=Geist+Mono:ital,wght@0,100..900;1,100..900&family=Geist:ital,wght@0,100..900;1,100..900&display=swap"
rel="stylesheet"
/>Inline theme script
If persisting user theme selections (see Dark mode), place an inline script in <head> without defer or type="module". It toggles .dark on <html> before first paint.
Full head template
Complete head configuration including import map, polyfills, module entry, and theme script:
<head> <meta charset="utf-8"> <meta name="viewport" content="width=device-width, initial-scale=1"> <!-- Paint the right theme (background, form controls, scrollbars) before CSS loads --> <meta name="color-scheme" content="light dark"> <!-- Google Fonts: Geist + Geist Mono (preconnect so the CSS request starts early) --> <link rel="preconnect" href="https://fonts.googleapis.com"> <link rel="preconnect" href="https://fonts.gstatic.com" crossorigin> <link rel="preload" as="font" type="font/woff2" crossorigin href="https://fonts.gstatic.com/s/geist/v5/gyByhwUxId8gMEwcGFWNOITd.woff2"> <link href="https://fonts.googleapis.com/css2?family=Geist+Mono:ital,wght@0,100..900;1,100..900&family=Geist:ital,wght@0,100..900;1,100..900&display=swap" rel="stylesheet"> <!-- Zazz styles: one bundle (index.css @imports every layer in cascade order) --> <link rel="stylesheet" href="./zazz/index.css"> <!-- Import map: bare specifiers in Zazz scripts resolve to pinned, SRI-checked files --> <script type="importmap"> { "imports": { "signal-polyfill": "https://cdn.jsdelivr.net/npm/signal-polyfill@0.2.2/dist/index.js", "embla-carousel": "https://cdn.jsdelivr.net/npm/embla-carousel@8.6.0/esm/embla-carousel.esm.js", "embla-carousel-autoplay": "https://cdn.jsdelivr.net/npm/embla-carousel-autoplay@8.6.0/esm/embla-carousel-autoplay.esm.js", "embla-carousel-auto-scroll": "https://cdn.jsdelivr.net/npm/embla-carousel-auto-scroll@8.6.0/esm/embla-carousel-auto-scroll.esm.js", "embla-carousel-class-names": "https://cdn.jsdelivr.net/npm/embla-carousel-class-names@8.6.0/esm/embla-carousel-class-names.esm.js" }, "integrity": { "https://cdn.jsdelivr.net/npm/signal-polyfill@0.2.2/dist/index.js": "sha384-0OqM7OXGT6Oz1z98u/geiFn/FUyz4iWexkXHCvbIGXRRDXl6bp6IKc0j78AQ6DEK", "https://cdn.jsdelivr.net/npm/embla-carousel@8.6.0/esm/embla-carousel.esm.js": "sha384-GXjfyU1fSHHeweoYd3rwo7OBKYtkq+JcsDoe8VDRc6znCty2ZTzyVvX1DwqCE+9t", "https://cdn.jsdelivr.net/npm/embla-carousel-autoplay@8.6.0/esm/embla-carousel-autoplay.esm.js": "sha384-AX49yBc7zd/CT8ZqNMRiiqqVSV9xfxb27VwEGziPioT3wL4k4C5BW2qwefdWuN4J", "https://cdn.jsdelivr.net/npm/embla-carousel-auto-scroll@8.6.0/esm/embla-carousel-auto-scroll.esm.js": "sha384-SPdnL1eic73WfM72zFEf0RJ5PdUC7TL3Yb5jOl1JC3/l4D7EsVxwO8wFnnezlMSu", "https://cdn.jsdelivr.net/npm/embla-carousel-class-names@8.6.0/esm/embla-carousel-class-names.esm.js": "sha384-ZWno/FqzYeWE5Ils19GIhep1AZ5bMl0mp9wmm6baTJE4+pjMjOdTnE55SjUQAdVh" } } </script> <link rel="modulepreload" href="./zazz/index.js"> <!-- Polyfills: Popover API + Invoker Commands (command/commandfor) --> <script src="https://cdn.jsdelivr.net/npm/@oddbird/popover-polyfill@0.7.2/dist/popover.min.js" integrity="sha384-pOVHoXRgxuaWHCRM4KSyfyfRTmdxgjVo1Ux78ZKJ+GjUz4zIzXiTa8XXuDF1R1Sd" crossorigin="anonymous" defer></script> <script type="module" src="https://cdn.jsdelivr.net/npm/invokers@2.2.2/dist/esm/production/compatible.js" integrity="sha384-7vRXDaS2mcW7LheGSA/rxBwIQNEqmWj0OLEOta/+mvw+9Uf5w1vplA5qg8kLQ99u" crossorigin="anonymous" defer></script> <!-- Zazz behavior: one ES module imports every component script in dependency order --> <script type="module" src="./zazz/index.js"></script> <!-- Theme: apply the persisted (or preferred) scheme before first paint --> <script> (() => { try { const storedTheme = localStorage.getItem("theme"); const prefersDark = matchMedia("(prefers-color-scheme: dark)").matches; const theme = storedTheme ?? (prefersDark ? "dark" : "light"); document.documentElement.classList.toggle("dark", theme === "dark"); } catch { document.documentElement.classList.toggle( "dark", matchMedia("(prefers-color-scheme: dark)").matches, ); } })(); </script></head>Landmark markup
<body>
<header data-transition-layer="global-header">
<!-- Navigation -->
</header>
<main>
<!-- Page content -->
</main>
<footer data-transition-layer="global-footer">
<!-- Footer -->
</footer>
</body>_reset.css applies container and layout contexts to <body>, <main>, and section landmarks.
Third-party modules and import map
Zazz scripts import dependencies (TC39 signals polyfill and Embla Carousel) using bare specifiers:
import { Signal } from "signal-polyfill";
import EmblaCarousel from "embla-carousel";The browser resolves specifiers through <script type="importmap">:
- Host: jsDelivr CDN URLs.
- Versions: Pinned exact versions.
- Integrity: SRI hashes on all entries.
Place the import map before index.js. To remove external network calls, vendor files locally and update import map paths.
Script load order
index.js imports component behaviors in dependency order:
- Import map: Parsed before module execution.
- Polyfills (optional): Popover API (
@oddbird/popover-polyfill), Invoker Commands. index.js(<script type="module">): Deferred by default; runs beforeDOMContentLoaded.- Inline theme script: Executed synchronously before paint.
View transition layers
For cross-document or SPA transitions via navigation.js, label persistent regions:
<header data-transition-layer="global-header">...</header>
<main>...</main>
<footer data-transition-layer="global-footer">...</footer><main> receives transition animation automatically while header and footer remain static.