Skip to content
HUBIQ

01

Get started.

How a site wears the system: name a theme, sync a release, import it as code, and let the build check the rest.

From KIT.md, sections 0, 1 and 10, rendered at every build.

02

0. Themes

Every HUBIQ site shares one core (grid, rail, type scale, motion, components, guards) and wears one theme, which owns what makes it look like itself: its grounds, ink, text roles, hairlines, accent and type families. hubiq.co.uk and atomiq.digital wear hubiq. An initiative that needs its own look (TenantIQ first) gets its own theme. A cousin, not a copy: the skeleton is shared, the skin is not. Added 23 October 2026; the reasoning is in THEMES-PLAN.md.

Where a theme lives. themes/<name>/theme.css (the values) and themes/<name>/THEME.md (its laws and ratios), optionally themes/<name>/components/ (below). A site names its theme in one word in design/.hiq-theme; no file means hubiq. sync.sh copies the theme into design/theme/ and hashes it, so an edit in the site fails the build.

The contract. A theme defines every one of these on :root, or the build fails.

Group Variables
Dark text and surfaces --ink, --panel, --paper, --muted, --muted2
Grounds --ground-paper, --ground-mist, --ground-grey, --ground-grey-deep, --ground-ink, --ground-panel, --ground-forest
Text on light grounds --ink-body, --ink-label, --lead-start
Hairlines --line, --line2, --rule-light, --rule-dark
Accent --house (the theme's leased hue), --house-2 (a second highlight; set it to var(--house) if the theme has none)
Type, by role --f-head, --f-text, --f-display, --f-mono

The names are the system's, not the theme's: --ground-forest is HUBIQ's green chapter and another theme's coloured dark chapter. The theme's THEME.md says what each role is in that theme. --ac stays core: it aliases --house and is overridden per surface as before.

Type families. The site loads its faces with next/font as CSS variables on <html>, and the theme maps them to the four roles. The kit reads only the roles, never a face. HUBIQ: --f-head and --f-text Inter Tight, --f-display Poppins, --f-mono Space Mono.

Contrast. The build computes, from the theme's own hex values, every pairing the kit's ground classes set: each ground's heading, running text and label against the ground at 4.5:1; --lead-start on paper and mist at 3:1; the accent as a line on ink and forest at 3:1, and ink on the accent fill at 4.5:1. A value that is not a solid hex where a ratio is needed fails rather than being skipped.

Adding a theme.

  1. Copy themes/hubiq/ to themes/<name>/. Change the values, keeping every name.
  2. Set --house to the initiative's leased hue (hiq-core-design.md, palette and leases). Keep only the palette hues the theme uses.
  3. Write its THEME.md: what each ground is for in this theme, its laws, its ratios.
  4. In the site, write <name> into design/.hiq-theme, sync, load its faces, and build. The guard tells you what is missing or unreadable.

Signature components. A component only one theme uses lives in themes/<name>/components/, is synced into components/theme/ only on sites wearing that theme, and is documented in that theme's THEME.md. When a second theme wants it, it moves into kit/ and this file, written against the contract, never a hex.


1. Adopting the kit in a site

  1. The site is Next.js with output: "export", hand-written CSS, the same stack as hubiq-web-v2.
  2. Write v2 into design/.hiq-branch, and the theme's name into design/.hiq-theme (leave it out for hubiq). Then from the site run bash ../hiq-design-v2/sync.sh 3.1.0, naming the release it should wear (see CHANGELOG.md); the site records it in design/.hiq-version. Without a version it takes the worktree, which is fine on a preview and not for a live site.
  3. Import the core as code, on the line after the theme's, at the top of app/globals.css: @import "../design/theme/theme.css"; then @import "../design/tokens.css";. Never copy theme or token values there: a copy silently wins or loses depending on order, and drifts. A site that must differ from the core says so in a :root block in globals.css, with a comment saying why.
  4. Load the faces the theme names with next/font as CSS variables on <html>. For hubiq: --font-display (Poppins 700 and 800), --font-grot (Inter Tight, variable) and --font-mono (Space Mono 400 and 700).
  5. In the root layout, import ../design/theme/theme.css, then ./globals.css, then ../design/kit/v2.css, then the site's own ./site.css, in that order.
  6. Add the inline head script that puts js on <html> before first paint, and the house arrival (.reveal / .arrive, the <Reveal /> observer). Both are in hubiq-web-v2's app/layout.tsx and app/globals.css today; they join the kit when the second site adopts it. Every hidden state in the kit is gated on .js, so without the script nothing is hidden, and nothing arrives either.
  7. Add node scripts/check-kit.mjs to the build script after next build.
  8. Add MotionToggle (writes data-motion="off" on <html>). The kit honours it and prefers-reduced-motion everywhere.

10. Changing the kit

  1. Edit kit/v2.css, kit/components/ or this file here, in hiq-design-v2 on the v2 branch. A new rule also goes in hiq-core-design.md.
  2. A new class gets an entry in section 6 or a line in an existing one, or every site's build fails.
  3. Commit and push here. To release: raise VERSION (minor for a change a site must look at, patch for a fix), add the entry to CHANGELOG.md, commit, tag v<version> and push the tag. Then run bash ../hiq-design-v2/sync.sh <version> from each site, check it, and commit there. A live site only ever wears a release.