Components

Things to build with. Each has a main class, classes for its parts, and classes for its variations. They draw everything from the tokens, so they follow the theme, the Appearance page and the density.

Button

An action: a <button>, an <a> or an <input type="submit">. A secondary button by default.

ClassWhat it does
fz-btnA secondary button.
fz-btn--primaryThe main action. Usually one per area.
fz-btn--dangerA destructive action, such as delete.
fz-btn--ghostNo border or background until hovered, for less important actions.
fz-btn--{sm,lg}Smaller or larger.
fz-btn--iconSquare, for an icon on its own. Give it an aria-label.
fz-btn--blockThe full width of its container.
  • Use a <button> for an action on the page and an <a> for going somewhere else; they look the same.
  • A disabled button, or one with aria-disabled="true", is faded.

Example

<div class="fz-cluster">
  <button type="button" class="fz-btn fz-btn--primary">Save</button>
  <button type="button" class="fz-btn">Cancel</button>
  <a href="#" class="fz-btn fz-btn--ghost">View history</a>
  <button type="button" class="fz-btn fz-btn--danger">Delete</button>
  <button type="button" class="fz-btn fz-btn--sm">Small</button>
  <button type="button" class="fz-btn fz-btn--lg">Large</button>
  <button type="button" class="fz-btn fz-btn--icon" aria-label="Settings">&#9881;</button>
  <button type="button" class="fz-btn" disabled>Disabled</button>
</div>

Form field

A label, a control and its help text.

ClassWhat it does
fz-fieldThe field: its label above its control.
fz-field__labelThe label: a <label for="…">, or a <legend> on a <fieldset>.
fz-field__reqThe required marker, inside the label.
fz-field__bodyThe control and its help text.
fz-field__helpHelp text, or an error message.
fz-field--horizontalThe label beside the control, stacking when there isn't room.
  • For a group of choices, use fz-field on a <fieldset>, with a <legend class="fz-field__label">.
  • Connect help text to its control with aria-describedby, so screen readers read it too.

Example

<div class="fz-stack">
  <div class="fz-field">
    <label class="fz-field__label" for="sg-name">Student name <span class="fz-field__req" aria-hidden="true">*</span></label>
    <div class="fz-field__body">
      <input class="fz-input" id="sg-name" required aria-describedby="sg-name-help">
      <p class="fz-field__help" id="sg-name-help">As it appears on the student's report card.</p>
    </div>
  </div>
  <div class="fz-field fz-field--horizontal">
    <label class="fz-field__label" for="sg-school">School</label>
    <div class="fz-field__body"><input class="fz-input" id="sg-school"></div>
  </div>
</div>

Inputs, dropdowns and text areas

Text-like inputs, dropdowns and text areas, sharing one look. Their height follows the density.

ClassWhat it does
fz-inputAn <input>: text, email, number, date and the like.
fz-selectA <select>, with its own chevron.
fz-textareaA <textarea>, several lines, taller when dragged.
  • aria-invalid="true" marks a control as invalid. Say what is wrong in the field's help text too, since the colour alone doesn't.

Example

<div class="fz-auto-grid fz-auto-grid--max-2 fz-auto-grid--wide">
  <input class="fz-input" placeholder="A text input" aria-label="A text input">
  <select class="fz-select" aria-label="A dropdown"><option>Grade 6</option><option>Grade 7</option></select>
  <input class="fz-input" value="not-an-email" aria-invalid="true" aria-label="An invalid input">
  <input class="fz-input" value="Disabled" disabled aria-label="A disabled input">
  <textarea class="fz-textarea" placeholder="A text area" aria-label="A text area"></textarea>
</div>

Input group

An input with text or an icon attached before or after it, such as a currency or a unit.

ClassWhat it does
fz-input-groupWraps an fz-input and its add-ons.
fz-input-group__addonThe attached text or icon.

Example

<div class="fz-input-group" style="max-width: 20rem">
  <span class="fz-input-group__addon">$</span>
  <input class="fz-input" inputmode="decimal" value="120.00" aria-label="Program fee">
  <span class="fz-input-group__addon">CAD</span>
</div>

Checkboxes, radios and toggles

Real checkboxes and radio buttons, drawn in the theme's colours; a toggle is a checkbox drawn as an on/off switch.

ClassWhat it does
fz-checkboxAn <input type="checkbox">.
fz-radioAn <input type="radio">.
fz-toggleAn <input type="checkbox"> drawn as a switch.
fz-choiceA <label> around a checkbox, radio or toggle and its text, all of it clickable.
fz-choice-groupA set of choices, one below the other.

Example

<div class="fz-switcher">
  <fieldset class="fz-field">
    <legend class="fz-field__label">Transportation</legend>
    <div class="fz-choice-group">
      <label class="fz-choice"><input type="radio" class="fz-radio" name="sg-t" checked> Bus</label>
      <label class="fz-choice"><input type="radio" class="fz-radio" name="sg-t"> Picked up by a parent</label>
    </div>
  </fieldset>
  <div class="fz-choice-group">
    <label class="fz-choice"><input type="checkbox" class="fz-checkbox" checked> Photo consent</label>
    <label class="fz-choice"><input type="checkbox" class="fz-toggle" checked> Email updates</label>
  </div>
</div>

Card

A surface for one thing: an entry, a summary, a group of fields. Its children are stacked 3 steps apart.

ClassWhat it does
fz-cardThe card.
fz-card__headerA row for the title and any actions, wrapping when out of room.
fz-card__titleThe title, on a heading that fits the page (h2, h3…).
fz-card__subtitleA line of secondary text under the title.
fz-card__footerA row at the bottom, separated by a line.
fz-card--flushNo padding: for a table or an image that should reach the edges.
fz-card--interactiveThe whole card is clickable, through its fz-card__link.
fz-card__linkThe one link the whole card clicks through to: on the link, or on an element around it when the link is generated for you, such as by viewEntryLink() in a list template.
  • In an interactive card, other links and buttons still work on their own.

Example

<div class="fz-auto-grid fz-auto-grid--max-2 fz-auto-grid--wide">
  <article class="fz-card">
    <div class="fz-card__header">
      <div><h3 class="fz-card__title">Robotics club</h3><p class="fz-card__subtitle">Thursdays, 3:30 to 5pm</p></div>
      <span class="fz-badge fz-badge--success">Open</span>
    </div>
    <p>An after-school program for students in grades 6 to 8.</p>
    <div class="fz-card__footer"><span class="fz-text-muted fz-text-sm">18 of 24 places taken</span><button type="button" class="fz-btn fz-btn--sm fz-ms-auto">Register</button></div>
  </article>
  <article class="fz-card fz-card--interactive">
    <h3 class="fz-card__title"><a href="#" class="fz-card__link">Coding camp</a></h3>
    <p class="fz-text-muted">The whole card is a link.</p>
    <div class="fz-cluster"><span class="fz-badge fz-badge--warning">Waitlist</span></div>
  </article>
</div>

Card list and grid list

A list of entries shown as cards instead of table rows: one below the other, or in columns.

ClassWhat it does
fz-card-listOn a <ul> or <ol>: cards one below the other.
fz-grid-listOn a <ul> or <ol>: cards in columns, like fz-auto-grid.
fz-grid-list--max-{2-6}At most this many columns.
fz-grid-list--{narrow,wide}Columns as narrow as 8rem, or at least 18rem.
  • Give each <li> the fz-card class.

Example

<ul class="fz-grid-list fz-grid-list--max-3">
  <li class="fz-card fz-card--interactive"><h3 class="fz-card__title fz-card__link"><a href="#">Amira Haddad</a></h3><div class="fz-cluster"><span class="fz-badge fz-badge--success">Approved</span><span class="fz-badge">Grade 7</span></div></li>
  <li class="fz-card fz-card--interactive"><h3 class="fz-card__title fz-card__link"><a href="#">Liam Chen</a></h3><div class="fz-cluster"><span class="fz-badge fz-badge--warning">Under review</span><span class="fz-badge">Grade 8</span></div></li>
  <li class="fz-card fz-card--interactive"><h3 class="fz-card__title fz-card__link"><a href="#">Sofia Rossi</a></h3><div class="fz-cluster"><span class="fz-badge fz-badge--info">Submitted</span><span class="fz-badge">Grade 6</span></div></li>
</ul>

Table

A plain data table: a header row, a line under each row, and rows the row height, which follows the density.

ClassWhat it does
fz-tableOn a <table>.
fz-table--stripedEvery other row shaded.
  • For a table wider than its container, wrap it in an element with fz-overflow-x-auto.

Example

<div class="fz-card fz-card--flush fz-overflow-x-auto">
  <table class="fz-table">
    <thead><tr><th>Student</th><th>School</th><th class="fz-text-end">Grade</th><th>Status</th></tr></thead>
    <tbody>
      <tr><td>Amira Haddad</td><td>Riverside Public School</td><td class="fz-text-end fz-tabular-nums">7</td><td><span class="fz-badge fz-badge--success">Approved</span></td></tr>
      <tr><td>Liam Chen</td><td>Lakeview Middle School</td><td class="fz-text-end fz-tabular-nums">8</td><td><span class="fz-badge fz-badge--warning">Under review</span></td></tr>
    </tbody>
  </table>
</div>

Badge

A short label: a status, a category, a count.

ClassWhat it does
fz-badgeA neutral badge, with a grey dot.
fz-badge--{accent,info,success,warning,danger}A coloured tint and dot.
fz-badge--plainNo dot.
  • The colour is in the tint and the dot; the text stays the normal text colour, so it is readable in every theme. The word should say what the status is: don't rely on the colour alone.

Example

<div class="fz-cluster">
  <span class="fz-badge">Draft</span>
  <span class="fz-badge fz-badge--info">Submitted</span>
  <span class="fz-badge fz-badge--warning">Under review</span>
  <span class="fz-badge fz-badge--success">Approved</span>
  <span class="fz-badge fz-badge--danger">Rejected</span>
  <span class="fz-badge fz-badge--accent fz-badge--plain">12 new</span>
</div>

Callout

A message set apart from the content around it: instructions, a warning, the result of an action.

ClassWhat it does
fz-calloutA callout, in the accent colour.
fz-callout--{info,success,warning,danger}A status callout.
fz-callout__titleA bold first line.
  • Add role="status" to a callout that appears because of something the user just did, so screen readers announce it.

Example

<div class="fz-stack fz-gap-3">
  <div class="fz-callout"><p class="fz-callout__title">Before you start</p><p>Have your student number and your school's address ready.</p></div>
  <div class="fz-callout fz-callout--success" role="status"><p>Your application was submitted.</p></div>
  <div class="fz-callout fz-callout--warning"><p>This entry has not been reviewed yet.</p></div>
  <div class="fz-callout fz-callout--danger"><p>The due date has passed.</p></div>
</div>

Toolbar

A row with a group at each end, such as a heading and its buttons, wrapping when it runs out of room.

ClassWhat it does
fz-toolbarThe row.
fz-toolbar__startThe group at the start.
fz-toolbar__endThe group at the end.

Example

<div class="fz-toolbar">
  <div class="fz-toolbar__start"><h2 class="fz-text-xl fz-font-semibold">Applications</h2><span class="fz-badge fz-badge--plain">48</span></div>
  <div class="fz-toolbar__end"><button type="button" class="fz-btn">Export</button><button type="button" class="fz-btn fz-btn--primary">New application</button></div>
</div>

Description list

Labelled values, such as an entry's fields in a card. On a <dl>; each <dt> and <dd> pair may be wrapped in a <div>.

ClassWhat it does
fz-dlTerms and values side by side.
fz-dl--stackedEach term above its value.

Example

<div class="fz-switcher">
  <dl class="fz-dl">
    <dt>Student</dt><dd>Amira Haddad</dd>
    <dt>School</dt><dd>Riverside Public School</dd>
    <dt>Grade</dt><dd>7</dd>
  </dl>
  <dl class="fz-dl fz-dl--stacked">
    <div><dt>Submitted</dt><dd>September 12, 2026</dd></div>
    <div><dt>Status</dt><dd><span class="fz-badge fz-badge--success">Approved</span></dd></div>
  </dl>
</div>

Empty state

What to show where there is nothing to show yet, and what to do about it.

ClassWhat it does
fz-emptyA centred, outlined area.
fz-empty__titleIts heading.

Example

<div class="fz-empty">
  <p class="fz-empty__title">No applications yet</p>
  <p>They will appear here once students start submitting them.</p>
  <button type="button" class="fz-btn fz-btn--primary">Share the form</button>
</div>