Hubbi & AI

Deep dive: Logos

What this covers

How the toolkit sizes and places your logo in the site header: the CSS behind it, the dials you can tune, and the presence tiers. It is for anyone who wants to understand or fine-tune the header, and it doubles as a reference an AI agent can act on.

The key constraint drives everything: the portal swaps your real logo into {{logo.src}} when the page is shown, so the toolkit never knows the exact image or its shape at build time. It cannot hardcode a width and height, it has to size the logo flexibly so any logo looks right.

The CSS that does it

Every logo is rendered by one rule in global.css:

.site-logo img {
  height: auto;
  width: auto;
  max-height: var(--logo-height);
  max-width: min(var(--logo-max-width, 22rem), 55vw);
  object-fit: contain;
}

This is what "ratio-agnostic" means:

The dials you can tune

Sizing is controlled by CSS custom properties in the :root block, tuned once per brand (never per page):

:root {
  --logo-height: 2.75rem;    /* prominent by default */
  --logo-max-width: 22rem;   /* wide wordmarks stay tall */
  --header-bg: var(--color-surface);
  --header-fg: var(--color-text);
}
/* the logo grows on wider screens: override the dial at the breakpoint */
@media (min-width: 1024px) { :root { --logo-height: 3.5rem; } }
Tune in :root, never on the page. Setting a size on .site-logo img on a single page breaks header consistency and the ratio-agnostic behaviour. Change the dials in :root and every page follows.

Presence tiers

The toolkit picks one of three presence levels for the logo, each a pair of --logo-height values (mobile, then desktop) and a --logo-max-width:

Tier--logo-height (mobile → desktop)--logo-max-widthRecommended when
Refined2.25rem → 2.5rem20remElegant or premium feel; a simple wordmark.
Prominent (default)2.75rem → 3.5rem22remMost brands, or when the feel is unclear.
Big & commanding4rem → 8rem30remBold or playful feel; a chunky or full-colour mark.

Roughly how the three heights look in a header:

Refined
Prominent
Big & commanding

Example, setting "Big & commanding":

:root { --logo-height: 4rem; --logo-max-width: 30rem; }
@media (min-width: 1024px) { :root { --logo-height: 8rem; } }

Header band and contrast

The header colours are two more dials, --header-bg and --header-fg, and the nav and button text follow --header-fg so they stay legible. Which band suits your logo depends on its colour mode (recorded in brand.md):

The toolkit reads the logo's colour mode, safe background colours, and a "never place on" list from brand.md to make this call, and keeps the neutral header by default.

Alt text and markup

The header logo is always this markup, with no size attributes:

<img src="{{logo.src}}" alt="{{logo.alt}}">

{{logo.src}} is the real logo the portal hydrates; {{logo.alt}} is the alt text (your brand name), added in v1.3.0. Sizing is CSS-only, via .site-logo img, so you never add width or height to the image.

How Claude handles it

When building your header, Claude reads the Logo block in brand.md (shape, colour mode, safe backgrounds), chooses a presence tier and, where it suits the logo, a header band, and sets the dials in :root. If no logo is set yet, it uses a high-contrast neutral header and flags it rather than guessing.

Example. "My logo is a wide white wordmark on transparent." Claude would set Big & commanding (so the wide mark stays tall), a coloured header band, and a light --header-fg, then confirm the band colour reads well against the mark.
New in v1.3.0. Before, the logo used a single fixed --logo-height: 2rem with a plain height: rule. v1.3.0 introduced the whole system: two sizing dials (--logo-height, --logo-max-width), the header-band tokens, the three-tier presence levels with mobile and desktop values, contrast-aware bands, the ratio-agnostic max-height/object-fit rule, and the {{logo.alt}} token.