1. Executive Summary
This plan aligns the visual design of the Calab.ai Handbook (Quartz 4.5.2 static site at handbook.calab.ai) with the Calab.ai company website (https://calab.ai/). The goal is brand cohesion — the handbook should look like it belongs to the same organization.
Scope: Visual design only. The handbook retains its own navigation structure (Explorer, Search, TOC, Backlinks, Graph) since it is a documentation site, not a marketing site. We do not replicate the main site’s navigation (Small Business, Enterprise links, etc.).
Key changes:
- Color palette: Replace both light and dark mode palettes with Calab.ai brand colors (deep navy, cyan accent, slate grays, pure black backgrounds)
- Typography: Switch all fonts to Space Grotesk (the brand typeface)
- PageTitle logo: Replace text-based “Calab.ai Handbook” with the SVG logo from calab.ai
- Favicon: Replace
icon.pngwith the Calab.ai logo mark - Component styling: Add custom SCSS for card borders, rounded corners, subtle backdrop effects, and gradient accents matching the main site’s design language
- Footer: Restyle to match calab.ai brand patterns
Branch strategy: Direct commits to main (deploys immediately via GitHub Actions → GitHub Pages).
2. Design System Reference (calab.ai)
2.1 Brand Colors
| Token | Value | Usage |
|---|---|---|
--brand-black | #000000 | Page backgrounds (dark mode) |
--brand-primary | #122c5f | Deep navy — links/accents in light mode |
--brand-primary-light | #254583 | Lighter navy — hover states in light mode |
--brand-secondary | #00ffd4 | Cyan/teal accent — links/CTAs in dark mode |
--brand-white | #ffffff | Text on dark, backgrounds in light mode |
2.2 Tailwind/Utility Colors Used on Main Site
- Backgrounds:
bg-black(#000),bg-white/5,bg-white/10,bg-neutral-950/50 - Text:
text-slate-100(#f1f5f9),text-slate-200(#e2e8f0),text-slate-300(#cbd5e1),text-slate-400(#94a3b8) - Accents:
text-brand-secondary(#00ffd4),text-cyan-300(#67e8f9) - Borders:
border-white/10(~#1a1a1e on black),border-white/15 - Gradients:
bg-gradient-to-r from-[#0A84FF] to-brand-secondary(blue → cyan for CTAs) - Card gradients:
bg-gradient-to-br from-[#0f172a] via-[#0b1c23] to-[#0b2e1f] - Accent lines:
from-sky-500 via-cyan-400 to-emerald-400
2.3 Typography
- Font family:
Space Grotesk(Google Fonts, weights 300–700) - Used for: All text (headings, body, UI elements)
2.4 Design Patterns
- Cards:
rounded-2xl/rounded-3xl,border border-white/10,bg-white/5 - Backdrop:
backdrop-blur-sm,backdrop-blur-xl - Header: Sticky,
bg-brand-black/80 backdrop-blur,border-b border-white/10 - Footer:
border-t border-white/10 bg-black - Selection:
background: #000; color: #fff
3. Color Mapping (calab.ai → Quartz Variables)
Quartz uses 9 CSS custom properties per mode, set via quartz.config.ts and emitted by joinStyles() in quartz/util/theme.ts.
3.1 Dark Mode (Primary — matches main site)
| Quartz Variable | New Value | Rationale |
|---|---|---|
light | #000000 | Pure black bg (bg-brand-black) |
lightgray | #1a1a2e | Borders/separators (≈ border-white/10) |
gray | #94a3b8 | Muted text (text-slate-400) |
darkgray | #cbd5e1 | Body text (text-slate-300) |
dark | #f1f5f9 | Headings/bold (text-slate-100) |
secondary | #00ffd4 | Links/accents (brand-secondary cyan) |
tertiary | #0A84FF | Hover/active states (brand blue) |
highlight | rgba(0, 255, 212, 0.08) | Subtle cyan highlight for internal links |
textHighlight | rgba(0, 255, 212, 0.2) | Text highlight/mark background |
3.2 Light Mode (Brand-adapted light theme)
| Quartz Variable | New Value | Rationale |
|---|---|---|
light | #f8fafc | Slate-50 background |
lightgray | #e2e8f0 | Slate-200 borders |
gray | #94a3b8 | Slate-400 muted text |
darkgray | #334155 | Slate-700 body text |
dark | #0f172a | Slate-900 headings |
secondary | #122c5f | Brand-primary navy for links |
tertiary | #0A84FF | Brand blue for hover states |
highlight | rgba(18, 44, 95, 0.08) | Subtle navy highlight |
textHighlight | rgba(10, 132, 255, 0.2) | Blue text highlight |
4. Implementation Plan
4.1 Phase 1: Static Assets
4.1.1 Download SVG Logo
- Source:
https://calab.ai/logo.svg - Destination:
quartz/static/logo.svg - Method:
curlorwebfetch→ save to file
4.1.2 Replace Favicon
- Source: Download favicon from
https://calab.ai/favicon.ico(or extract from logo) - Destination: Replace
quartz/static/icon.png - Note: Quartz expects
icon.png. If the source is.ico, convert to PNG.
4.1.3 OG Image (Deferred)
- Replace
quartz/static/og-image.pngwith a Calab.ai-branded version - This can be created separately (requires image design) — mark as deferred if no source available
4.2 Phase 2: Configuration Changes
4.2.1 Update quartz.config.ts — Colors
Replace the colors block with the mapped values from Section 3.
File: quartz.config.ts
Section: theme.colors
colors: {
lightMode: {
light: "#f8fafc",
lightgray: "#e2e8f0",
gray: "#94a3b8",
darkgray: "#334155",
dark: "#0f172a",
secondary: "#122c5f",
tertiary: "#0A84FF",
highlight: "rgba(18, 44, 95, 0.08)",
textHighlight: "rgba(10, 132, 255, 0.2)",
},
darkMode: {
light: "#000000",
lightgray: "#1a1a2e",
gray: "#94a3b8",
darkgray: "#cbd5e1",
dark: "#f1f5f9",
secondary: "#00ffd4",
tertiary: "#0A84FF",
highlight: "rgba(0, 255, 212, 0.08)",
textHighlight: "rgba(0, 255, 212, 0.2)",
},
},4.2.2 Update quartz.config.ts — Typography
Replace all three font slots with Space Grotesk (and a matching monospace font).
typography: {
header: { name: "Space Grotesk", weights: [400, 700] },
body: { name: "Space Grotesk", weights: [300, 400, 500, 600, 700], includeItalic: false },
code: "IBM Plex Mono",
},Note: Space Grotesk does not have true italics. includeItalic: false avoids requesting non-existent italic variants. IBM Plex Mono is retained for code — it pairs well and is already loaded.
4.2.3 Update Syntax Highlighting Theme
Change to themes that better match the brand palette:
Plugin.SyntaxHighlighting({
theme: {
light: "github-light",
dark: "github-dark-default",
},
keepBackground: false,
}),github-dark-default uses a darker background than github-dark and better matches the pure black palette.
4.3 Phase 3: Component Changes
4.3.1 PageTitle — SVG Logo (quartz/components/PageTitle.tsx)
Replace the text-only <a>{title}</a> with an <img> tag pointing to the SVG logo, keeping the link behavior and accessibility.
const PageTitle: QuartzComponent = ({
fileData,
cfg,
displayClass,
}: QuartzComponentProps) => {
const title = cfg?.pageTitle ?? i18n(cfg.locale).propertyDefaults.title;
const baseDir = pathToRoot(fileData.slug!);
return (
<h2 class={classNames(displayClass, "page-title")}>
<a href={baseDir}>
<img
class="logo-image"
src={`${baseDir}/static/logo.svg`}
alt={title}
/>
</a>
</h2>
);
};Update the CSS block:
.page-title {
font-size: 1.75rem;
margin: 0;
font-family: var(--titleFont);
}
.logo-image {
height: 2.5rem;
width: auto;
display: block;
}
:root[saved-theme="dark"] .logo-image {
filter: brightness(0) invert(1);
}Note: The filter: brightness(0) invert(1) makes a dark logo appear white in dark mode. If the SVG logo is already white, this may need adjustment after visual testing.
4.3.2 Footer — Restyle (quartz/components/Footer.tsx + footer.scss)
Add Calab.ai branding, copyright line, and a border-top matching the main site’s border-white/10 pattern.
Footer.tsx — Add structured markup:
<footer class={`${displayClass ?? ""}`}>
<hr class="footer-rule" />
<div class="footer-content">
<p class="footer-brand">
© {year} Calab.ai — All rights reserved.
</p>
<ul>
{Object.entries(links).map(([text, link]) => (
<li>
<a href={link}>{text}</a>
</li>
))}
</ul>
<p class="footer-powered">
{i18n(cfg.locale).components.footer.createdWith}{" "}
<a href="https://quartz.jzhao.xyz/">Quartz v{version}</a>
</p>
</div>
</footer>footer.scss — Brand-aligned styles:
footer {
text-align: left;
margin-bottom: 4rem;
& .footer-rule {
border: none;
height: 1px;
background: var(--lightgray);
margin: 2rem 0;
}
& .footer-content {
opacity: 0.7;
}
& .footer-brand {
font-weight: 600;
margin-bottom: 0.5rem;
}
& .footer-powered {
font-size: 0.85rem;
margin-top: 0.5rem;
}
& ul {
list-style: none;
margin: 0;
padding: 0;
display: flex;
flex-direction: row;
gap: 1rem;
}
}4.4 Phase 4: Custom SCSS (quartz/styles/custom.scss)
This is the primary injection point for brand-specific visual overrides that don’t require component changes.
@use "./base.scss";
// ==========================================================
// Calab.ai Brand Alignment — Custom Styles
// ==========================================================
// --- Selection colors (matches calab.ai) ---
::selection {
background: var(--secondary);
color: var(--light);
}
// --- Sidebar card-like sections (Graph, Backlinks, TOC) ---
:root[saved-theme="dark"] {
.graph > .graph-outer,
.search > .search-button,
pre,
.search-container .search-space > * {
border-color: rgba(255, 255, 255, 0.1);
}
}
// --- Rounded borders (brand uses rounded-2xl = 1rem) ---
.graph > .graph-outer,
.global-graph-container,
pre,
code,
img,
.search > .search-button,
.search-container .search-space > * {
border-radius: 0.75rem;
}
// --- Navigation progress bar accent ---
.navigation-progress {
background: linear-gradient(to right, #0a84ff, var(--secondary));
height: 2px;
}
// --- Blockquote accent ---
blockquote {
border-left-color: var(--secondary);
}
// --- Explorer folder hover ---
.folder-icon:hover {
color: var(--secondary);
}
// --- Internal link hover polish ---
a.internal {
border-radius: 0.25rem;
transition:
background-color 0.2s ease,
color 0.2s ease;
}
// --- Code block polish ---
pre {
background-color: var(--highlight);
}
// --- Table header bottom border uses secondary ---
th {
border-bottom-color: var(--secondary);
}5. Files Modified
| File | Change Type | Description |
|---|---|---|
quartz.config.ts | Edit | Colors, fonts, syntax highlighting theme |
quartz/components/PageTitle.tsx | Edit | SVG logo instead of text title |
quartz/components/Footer.tsx | Edit | Restructured brand footer |
quartz/components/styles/footer.scss | Edit | Brand-aligned footer styles |
quartz/styles/custom.scss | Edit | Brand CSS overrides (selection, borders, radius, accents) |
quartz/static/logo.svg | New | SVG logo from calab.ai |
quartz/static/icon.png | Replace | Calab.ai favicon |
quartz/static/og-image.png | Replace (deferred) | Branded OG image |
6. Files NOT Modified (and why)
| File | Reason |
|---|---|
quartz/util/theme.ts | No structural changes — only config values change |
quartz/components/Head.tsx | Font preconnect already handled dynamically |
quartz/styles/base.scss | Overrides go in custom.scss to minimize upstream merge conflicts |
quartz/styles/variables.scss | Layout grid unchanged |
quartz/components/styles/explorer.scss | Colors already use CSS variables — will inherit new palette |
quartz/components/styles/search.scss | Colors already use CSS variables — will inherit new palette |
quartz/components/styles/darkmode.scss | No visual changes needed |
quartz/components/styles/toc.scss | Colors already use CSS variables — will inherit new palette |
quartz/components/styles/backlinks.scss | Colors already use CSS variables — will inherit new palette |
quartz/components/styles/graph.scss | Colors already use CSS variables — will inherit new palette |
quartz/components/styles/breadcrumbs.scss | Colors already use CSS variables — will inherit new palette |
.github/workflows/deploy.yml | No deployment changes |
quartz.layout.ts | Component wiring unchanged |
7. Verification
After all changes:
- Local build:
npx quartz buildshould complete without errors - Visual check: Open
public/index.html— verify dark and light mode colors, logo rendering, font loading - Mobile check: Verify responsive behavior unchanged
- Git diff review: Confirm only intended files are modified
8. Rollback
All changes are in a small set of files. To rollback:
git checkout HEAD~1 -- quartz.config.ts quartz/components/PageTitle.tsx \
quartz/components/Footer.tsx quartz/components/styles/footer.scss \
quartz/styles/custom.scss quartz/static/icon.png quartz/static/logo.svgOr simply git revert <commit-sha> on the brand alignment commit.
9. Future Enhancements (Out of Scope)
- Custom OG image generation with brand template
- Gradient accent line at top of page (calab.ai header pattern)
- Card-style content blocks for landing page
- Custom 404 page with brand styling
- Animated transitions matching main site