Skip to content
HUBIQ

01

Components.

The parts every page is built from, live. Scroll to see them move; switch theme to see the same part in another initiative's look.

02Live

The expressive parts.

Each is shown on a ground it belongs on, with its entry from KIT.md beneath. Every one finishes in its end state with reduced motion or the motion toggle on.

03Controls

Buttons, forms and toggles.

Each control reads its ground, so one set of rules serves every ground; here on paper and on ink, in each theme. Green is only ever a fill, with ink on it. An error is said in words, with an icon and a heavier border, never in a second colour.

Buttons

Text link

Form

So the right person replies.

Fields of interest
How should we reply?
We use your details only to reply.

Toggles

Disclosure

Read more

A native details element: it opens with no script, and search engines read what is inside.

Buttons

Text link

Form

So the right person replies.

Fields of interest
How should we reply?
We use your details only to reply.

Toggles

Disclosure

Read more

A native details element: it opens with no script, and search engines read what is inside.

Site head, in the HUBIQ theme

Fixed at the top of a real page; held in this box here. Narrow the window below 860px for the menu and drawer, and press Tab from the top of any page on this site for the skip link.

Motion toggle

This one is live: press it and everything on this site stops moving, and stays stopped on your next visit. The lost page is this site's own 404: try a page that is not there.

Controls (3.3.0): Controls.tsx, <PillButton>, <MotionToggle>, <SiteHead>, <Lost>

Added 26 October 2026, so no site builds its own again. Every control reads its ground's roles, so one set of rules serves every ground. Green is only a fill, always with ink on it. An error is said in words, with the error icon and a heavier border, never in a second colour. Each ground also sets --focus, the ring colour: ink on light grounds, house green on ink and forest. :where(.v2-page) :focus-visible gives anything in a v2 page without a ring of its own that ring, at one class of weight, so every kit or site ring still wins.

Part Component Classes Use
Skip link <SkipLink href> v2-skip First in the body, to <main id="main">. <SiteHead> renders it
Primary button <Pill href>, <PillButton type onClick disabled ring> v2-pill The one primary on a band. PillButton is the <button> form, for a form's send
Secondary button none: a <button> or <Link> with the class v2-btn, v2-btn-sm, v2-btn-icon Outline in the heading colour, fills on hover. v2-btn-icon is square for a lone icon and needs an aria-label. A third level is the text link, v2-textlink
Form <form className="v2-form"> v2-form, v2-form-wide, v2-form-foot, v2-form-status, v2-form-trap Two columns, one below 720px. v2-form-wide spans both; the foot holds the send and a note; the status box replaces the form once sent (or says it failed); the trap is the honeypot
Field <Field id label help error wide> v2-form-field, v2-form-label, v2-form-help, v2-form-error Label, control, help, error. The control carries the same id, aria-describedby naming the help and error, and aria-invalid when in error
Text, select, textarea none: the element with the class v2-input One class for all three. A select gets its chevron; a required select with an empty first option shows it in the label colour
Group of choices <fieldset className="v2-form-set"> with <legend className="v2-form-label"> v2-form-set Checkboxes or radios under one question
Checkbox, radio <Choice type name value checked onChange> v2-choice The native input, redrawn: checked fills house green with an ink mark and edge
Switch <Switch on onChange> v2-switch, v2-switch-track A setting that applies at once (not a form answer). role="switch"
Segmented control <Segmented label options value onChange> v2-segmented One view of several (Experience or Technology); the chosen one fills in the heading colour
Picks <Picks label options on onToggle> v2-picks, v2-pick, v2-pick-n Filter chips, any number on; a count beside each name if given. Hide them with no script if they only filter
Motion toggle <MotionToggle storageKey> v2-motion, v2-motion-dot WCAG 2.2.2's control. Writes data-motion="off" on <html>, pauses looping video, remembers the choice. Usually in the footer base line
Disclosure <Disclosure summary open> v2-more, v2-more-body A native <details>: opens with no script, read by search engines. The body grows open where the browser can animate it
Site head <SiteHead stem iq links drawer> v2-head, v2-head-in, v2-brand, v2-brand-iq, v2-head-nav, v2-head-link, v2-burger, v2-drawer, v2-drawer-in Wordmark, up to five links, a menu and drawer below 860px. Always on ink. A link's match lists other paths that light it; note is its mono line in the drawer. The live hubiq.co.uk header's look
Lost page <Lost title links> v2-lost, v2-lost-links What app/not-found.tsx renders: one ink band, a sentence, the ways back

A form, put together:

<form className="v2-form" onSubmit={send}>
  <Field id="name" label="Name"><input id="name" className="v2-input" autoComplete="name" required /></Field>
  <Field id="email" label="Email" error={bad && "That is not an email address."}>
    <input id="email" type="email" className="v2-input" aria-invalid={bad} aria-describedby={bad ? "email-error" : undefined} required />
  </Field>
  <Field id="note" label="What would you like to talk about?" wide><textarea id="note" className="v2-input" /></Field>
  <div className="v2-form-foot"><PillButton type="submit">Send</PillButton><span className="v2-small">We use your details only to reply.</span></div>
</form>

04Everything else

The full list.

6. Components

Each entry: what it is for, the markup, the grounds it works on, its motion and what it does on a phone (720px and below, one column).

Hero (v2-hero, v2-hero-lg)

The first band. <Band ground="paper" n="01" label="..." className="v2-hero" arrive={false} id="top"> with an <h1 className="v2-h1"> and a v2-hero-lede or v2-lead. v2-hero-lg sets the H1 a size up (Our story). Any ground. Nothing on the headline moves.

Pill CTA (7.22): <Pill href>

The one primary action. v2-pill, v2-pill-label, v2-pill-ring. A house green pill, ink text, the label and a ringed arrow side by side; the arrow nudges forward on hover or focus and the pill gives on press. Ink on house green. Any ground. For a pill that is a <button> (a play control), use the classes on the button and <PillRing> with your own glyph in a 74 by 74 box. Redrawn 10 October 2026 (Gideon), from a Uiverse button by alexmaracinaru; it replaced the detached arrow that jumped across.

Icon (rulebook 8): <Icon name>, v2-icon

Material Symbols Outlined, weight 300, from the approved subset in rulebook section 8 and nothing else; ICONS holds the paths, IconName the names. Sizes 16, 20, 24 or 40, colour currentColor, so it takes the text colour of whatever it sits in. Beside a label it is aria-hidden; an icon on its own takes label, which becomes its accessible name. Gap to its text: 8px at 16, 10px at 20, 12px at 24. A site lays out the icon and its text itself. Moved into the kit 25 October 2026; hubiq.co.uk's StageIcon predates it and draws the same four stage paths.

Text link: v2-textlink

Every link that is not the one primary: underlined text, the underline drops on hover. Several together go in a v2-links row.

Filling lead (7.24): <FillLead text="..." />

A v2-lead whose words fill grey to ink as it is read, finishing as its last line reaches 30% from the top. One per band, on paper or mist. Motion off: ink.

Display word and drift (7.25): v2-word, v2-word-1, v2-word-2, v2-drift, v2-stage, v2-figure

Poppins 800 decoration at --type-word, aria-hidden, drifting sideways as the band crosses the screen. Put data-scrub="drift" on the band. v2-stage is the figure stage with words above (-1) and below (-2); v2-figure holds a drawn figure in house green (dark grounds). Its sentence must be real text nearby. Phones: no drift is needed; the words sit centred.

Column cards (7.23): v2-cards, v2-cards-4, v2-card and parts

The columns are the cards. v2-card-n, v2-card-body, v2-card-name, v2-card-iq, v2-card-sector, v2-card-desc (shown on hover where hovering exists), v2-card-stage, v2-dot. Hover and focus invert to ink; the initiative colour appears on ink only. v2-cards-4 starts four cards in the content columns. Light grounds. Phones: two up.

Initiative names: v2-iname, v2-iq

A name as stem plus IQ: <span className="v2-iname">TENANT<span className="v2-iq">IQ</span></span>. The IQ takes --ac only on ink or on hover.

Rows: v2-rows, v2-row, v2-row-head, v2-row-block, v2-row-stage, v2-row-tag, v2-row-go

A list where the whole row is a link and inverts to ink on hover: head in two columns, two blocks of two. Light grounds. Phones: stacked.

Stat row (7.27): <Stat value label>, v2-stats, v2-stats-5, v2-stat, v2-stat-n, v2-stat-l

Space Mono numerals that count up once at the trigger line; the final value is in the HTML. Four up, or five with v2-stats-5. Phones: two up.

Lattice (7.26): <Lattice />, v2-lattice, v2-lattice-band

House green on a light ground as light: a dot field building from its base on scroll. On the closing call only: <section className="v2-band g-grey-deep v2-lattice-band"> with <Lattice /> first.

Scroll story (7.28): v2-story-grid, v2-story-steps, v2-step, v2-step-n, v2-story-stage, v2-story-pin, v2-diagram, v2-d-fill, v2-d-line, v2-story-static, v2-story-thumb

A diagram pinned beside steps of text; each step's top crossing 55% of the viewport sets data-focus on the element marked data-focus-host. Mark the story root data-story, each step data-step="name". Diagram parts carry data-part; the dim rule is in the kit, the highlight rules for a particular diagram's parts belong with that diagram (site CSS). v2-story-static sets the same diagram statically with one highlight per thumb. Phones: the diagram pins under the nav and the steps scroll beneath.

Pinned scrub (7.30): v2-pin, v2-pin-stage, v2-seg, v2-rise, v2-swap

A chapter told across a stretch of scroll: the band holds still while its parts build, scrubbed by the reader. See section 7 for the mechanics.

<section className="v2-band g-ink v2-pin" data-scrub="pin" style={{ "--len": 4 } as CSSProperties}>
  <Lines tone="house" />
  <div className="v2-pin-stage">
    ...
    <p className="v2-h2 v2-seg v2-rise" style={{ "--a": 0.1, "--b": 0.25 } as CSSProperties}>Arrives over the first quarter</p>
  </div>
</section>

Pinned only with motion on and above 720px; otherwise it is a normal band at its finished state with every word in order, which is the version to design first.

Statement (7.29): v2-statement, v2-mark

Section 5 above.

Strike and replace (7.31): v2-sr, v2-sr-from, v2-sr-to

One claim struck through and its replacement rising beneath, at the statement size. Put a scrub on the parent (data-scrub="drift" in a normal band; a pin's own progress inside a pin) and a v2-seg window on each line; the replacement also takes v2-rise. On ink and forest the bar and the replacement are house green; on light grounds both are ink.

<p className="v2-sr" data-scrub="drift">
  <s className="v2-sr-from v2-seg" style={{ "--a": 0.22, "--b": 0.42 } as CSSProperties}>from building software</s>
  <span className="v2-sr-to v2-seg v2-rise" style={{ "--a": 0.34, "--b": 0.52 } as CSSProperties}>to building the right solution</span>
</p>

Use <s>: the struck claim is no longer accurate, which is what the element means.

Burst (7.34): <Burst />, v2-burst

A small ornament: eight rays of three dots around an empty centre, house green. Sized by font-size (it is 1em across), coloured by --burst (house green by default). On ink and forest it may sit anywhere as a mark; on a light ground green is a fill only, so keep it a decoration there, never the thing that carries meaning. On house green (g-house) it takes ink, as the mark inverts there. It is its own .reveal, so wherever it sits it builds as it reaches the trigger line: ring by ring from the centre out, each dot travelling out along its ray, overshooting and falling back to the static shape (23 October 2026). No wrapper needed. Added 10 October 2026 (Gideon).

Typed line (7.33): <TypedLine text="..." />, v2-typed

A short line, a tagline or a strapline, that types itself in character by character with a caret (v2-typed-w holds each word's characters; v2-typed-sr carries the real text for screen readers). Inside a pin pass w={{ a, b }} to type across that slice of the pin; on its own it scrubs itself as it crosses the screen, like a filling lead; load (v2-typed-load) types it once on arrival, for a hero line (never the H1). Use it for lines of a few words: a paragraph should fill (<FillLead>), not type. Finished with motion off, reduced motion and no script. Added for the Hub (Gideon, 8 October 2026: a page of words needs to feel alive).

Named and lit (7.32): v2-lit, v2-lit-fill

When a line names a part of the picture, the part turns house green as the line is read. Give the part v2-seg with the same window as its line. v2-lit turns text green (ink and forest only; set --lit-from for the colour it starts from, default the label colour). v2-lit-fill lights a chip or box as a fill, on any ground: green behind, ink on it, the border following. At rest, finished, every named part is lit. A 5Di part lights in the second highlight: set --lit-to: var(--house-2) on it (rulebook, "The second highlight").

Put the line where the eye is. The reader watches the part that is changing, so its line goes beside or directly under it, never across the stage. Mark the part being named (the Foundry's chapter 02 uses a second green bar along the cell's foot) until the next.

Rail aside: <Rail aside>, v2-rail-aside

A small piece of wayfinding under the rail label, such as a progress figure. Never a second label or a heading.

Owed and interim slots: <Owed who>, <Interim>, v2-owed, v2-owed-who, v2-owed-what, v2-interim, v2-member-owed

A real heading over a visibly empty dashed body saying who owes what (Colin by default), and a marker for real copy in a provisional place. Both must be gone before launch.

Ruled blocks: v2-points, v2-list3, v2-steps, v2-ways, v2-split, v2-dims, v2-dims-k

Text blocks each headed by a hairline, in a grid: two up (v2-points, v2-ways), three up (v2-list3, v2-steps, v2-split with a big mono figure), or a name-then-question list (v2-dims). Any ground. Phones: one column.

Routes: v2-routes, v2-route, v2-route-to

Links to other sections, two up, each ruled, the destination underlining on hover.

Pull quote (7.19): v2-pq

<figure className="v2-pq"><blockquote>...</blockquote><figcaption>...</figcaption></figure>. One per page, attributed. Quotation marks are drawn by CSS.

Still (7.20): v2-still

An atmosphere image in a fixed 21:9 frame, greyscale and darkened so nothing competes with house green.

Screens: v2-shots, v2-shot

Product screenshots two up, captioned, with a hairline frame.

People: v2-tribe, v2-member, v2-member-face

Equal cards for people or AI members, square photographs, no hierarchy. Four up, three at 1100px, two on phones.

Panels and facts: v2-panels, v2-panel, v2-kv, v2-chain

A bordered box, two up; inside, a key-value list (v2-kv), ruled between entries with v2-chain.

Chips: v2-chips

Mono facts in pills. is-on fills the chosen ones house green.

On-page nav: v2-subnav

Pill links to the parts of a long page, ruled above.

Bars: v2-bars, v2-bar, v2-bar-k, v2-bar-track, v2-bar-n

Counts by category. A quantity, so bars are right; ink on light.

Footer (7.11): v2-foot, v2-foot-mark, v2-foot-cols, v2-foot-col, v2-foot-link, v2-foot-legal, v2-foot-base

On ink with house-green column rules; a green bullet grows in beside a link on hover. The footer's content is the site's own component.

Controls (3.3.0): Controls.tsx, <PillButton>, <MotionToggle>, <SiteHead>, <Lost>

Added 26 October 2026, so no site builds its own again. Every control reads its ground's roles, so one set of rules serves every ground. Green is only a fill, always with ink on it. An error is said in words, with the error icon and a heavier border, never in a second colour. Each ground also sets --focus, the ring colour: ink on light grounds, house green on ink and forest. :where(.v2-page) :focus-visible gives anything in a v2 page without a ring of its own that ring, at one class of weight, so every kit or site ring still wins.

Part Component Classes Use
Skip link <SkipLink href> v2-skip First in the body, to <main id="main">. <SiteHead> renders it
Primary button <Pill href>, <PillButton type onClick disabled ring> v2-pill The one primary on a band. PillButton is the <button> form, for a form's send
Secondary button none: a <button> or <Link> with the class v2-btn, v2-btn-sm, v2-btn-icon Outline in the heading colour, fills on hover. v2-btn-icon is square for a lone icon and needs an aria-label. A third level is the text link, v2-textlink
Form <form className="v2-form"> v2-form, v2-form-wide, v2-form-foot, v2-form-status, v2-form-trap Two columns, one below 720px. v2-form-wide spans both; the foot holds the send and a note; the status box replaces the form once sent (or says it failed); the trap is the honeypot
Field <Field id label help error wide> v2-form-field, v2-form-label, v2-form-help, v2-form-error Label, control, help, error. The control carries the same id, aria-describedby naming the help and error, and aria-invalid when in error
Text, select, textarea none: the element with the class v2-input One class for all three. A select gets its chevron; a required select with an empty first option shows it in the label colour
Group of choices <fieldset className="v2-form-set"> with <legend className="v2-form-label"> v2-form-set Checkboxes or radios under one question
Checkbox, radio <Choice type name value checked onChange> v2-choice The native input, redrawn: checked fills house green with an ink mark and edge
Switch <Switch on onChange> v2-switch, v2-switch-track A setting that applies at once (not a form answer). role="switch"
Segmented control <Segmented label options value onChange> v2-segmented One view of several (Experience or Technology); the chosen one fills in the heading colour
Picks <Picks label options on onToggle> v2-picks, v2-pick, v2-pick-n Filter chips, any number on; a count beside each name if given. Hide them with no script if they only filter
Motion toggle <MotionToggle storageKey> v2-motion, v2-motion-dot WCAG 2.2.2's control. Writes data-motion="off" on <html>, pauses looping video, remembers the choice. Usually in the footer base line
Disclosure <Disclosure summary open> v2-more, v2-more-body A native <details>: opens with no script, read by search engines. The body grows open where the browser can animate it
Site head <SiteHead stem iq links drawer> v2-head, v2-head-in, v2-brand, v2-brand-iq, v2-head-nav, v2-head-link, v2-burger, v2-drawer, v2-drawer-in Wordmark, up to five links, a menu and drawer below 860px. Always on ink. A link's match lists other paths that light it; note is its mono line in the drawer. The live hubiq.co.uk header's look
Lost page <Lost title links> v2-lost, v2-lost-links What app/not-found.tsx renders: one ink band, a sentence, the ways back

A form, put together:

<form className="v2-form" onSubmit={send}>
  <Field id="name" label="Name"><input id="name" className="v2-input" autoComplete="name" required /></Field>
  <Field id="email" label="Email" error={bad && "That is not an email address."}>
    <input id="email" type="email" className="v2-input" aria-invalid={bad} aria-describedby={bad ? "email-error" : undefined} required />
  </Field>
  <Field id="note" label="What would you like to talk about?" wide><textarea id="note" className="v2-input" /></Field>
  <div className="v2-form-foot"><PillButton type="submit">Send</PillButton><span className="v2-small">We use your details only to reply.</span></div>
</form>

Arrival: <Reveal />, reveal, arrive, arrive-group, rise

The house arrival, in the kit since 3.2.0 (it was each site's own). Mount <Reveal /> once in the site's layout, and add the head script that puts js on <html> before first paint (document.documentElement.classList.add("js")). <Band> adds reveal arrive to its content: its children settle in, 70ms apart, as the band crosses a line 28% up from the bottom of the screen. arrive-group on a grid lets its children carry the gesture; reveal rise arrives one element on its own. With no script, reduced motion or motion off, nothing is hidden. A site that carried its own copy (hubiq-web-v2, atomiq-web) can delete it once it wears 3.2.0.