Home
Search

Design system

Generated from app/design-system/tokens. Every colour, size and chart value below is read from the token files at build time, so this page cannot drift from what the site actually uses. Two parts are hand-written and deliberately small: the register, and the notes at the bottom.

Source of truth is the live website, not the 2023 Figma library.

Palette

Raw ramps from the primitives layer. Blue is declared in main.css; neutral and amber are Tailwind's, which the site inherits; green and pink exist only in chart output. Every colour carries an empty CMYK slot.

blue

blue-50#f2f4ffCMYK pending
blue-100#e7e9ffCMYK pending
blue-200#d3d8ffCMYK pending
blue-300#b0b6ffCMYK pending
blue-400#8387ffCMYK pending
blue-500#5551ffCMYK pending
blue-600#3e2dfaCMYK pending
blue-700#2f1be6CMYK pending
blue-800#2716c0CMYK pending
blue-900#22149eCMYK pending
blue-950#100a6bCMYK pending

amber

amber-50#fffbebCMYK pending
amber-100#fef3c7CMYK pending
amber-200#fde68aCMYK pending
amber-300#fcd34dCMYK pending
amber-400#fbbf24CMYK pending
amber-500#f59e0bCMYK pending
amber-600#d97706CMYK pending
amber-700#b45309CMYK pending
amber-800#92400eCMYK pending
amber-900#78350fCMYK pending
amber-950#451a03CMYK pending

neutral

neutral-50#fafafaCMYK pending
neutral-100#f5f5f5CMYK pending
neutral-200#e5e5e5CMYK pending
neutral-300#d4d4d4CMYK pending
neutral-400#a3a3a3CMYK pending
neutral-500#737373CMYK pending
neutral-600#525252CMYK pending
neutral-700#404040CMYK pending
neutral-800#262626CMYK pending
neutral-900#171717CMYK pending
neutral-950#0a0a0aCMYK pending

green

green-50#f0f9f3CMYK pending
green-100#daf1e0CMYK pending
green-200#b8e2c7CMYK pending
green-300#89cca3CMYK pending
green-400#57b07dCMYK pending
green-500#338d5dCMYK pending
green-600#25764dCMYK pending
green-700#1e5e3fCMYK pending
green-800#1a4b33CMYK pending
green-900#163e2bCMYK pending
green-950#0b2318CMYK pending

pink

pink-50#fef2f2CMYK pending
pink-100#ffe1e2CMYK pending
pink-200#ffc8caCMYK pending
pink-300#ffb0b3CMYK pending
pink-400#fd6c72CMYK pending
pink-500#f53e45CMYK pending
pink-600#e22027CMYK pending
pink-700#be171dCMYK pending
pink-800#9d171cCMYK pending
pink-900#821a1eCMYK pending
pink-950#47080aCMYK pending

Semantic roles — web

Roles, not values. Read from measured usage across the app rather than invented. Each fill shows the ink derived for text placed on it, with the achieved contrast ratio.

Text

  • strongAlmost before we knew it, we had left the ground.#0a0a0a
  • primaryAlmost before we knew it, we had left the ground.#262626
  • bodyAlmost before we knew it, we had left the ground.#404040
  • mutedAlmost before we knew it, we had left the ground.#737373
  • inverseAlmost before we knew it, we had left the ground.#ffffff

Surface

Aa19.8:1
surface.page#ffffffon: #0a0a0a · AAACMYK pending
Aa18.97:1
surface.raised#fafafaon: #0a0a0a · AAACMYK pending
Aa18.16:1
surface.sunken#f5f5f5on: #0a0a0a · AAACMYK pending
Aa19.8:1
surface.inverse#0a0a0aon: #ffffff · AAACMYK pending

Brand

Aa5.24:1
brand.primary#5551ffon: #ffffff · AACMYK pending
Aa10.7:1
brand.deep#2716c0on: #ffffff · AAACMYK pending

Border

border.default#e5e5e5CMYK pending
border.strong#d4d4d4CMYK pending
border.inverse#404040CMYK pending

Type scale — web

Rendered at actual size, straight from the tokens. Sizes are Tailwind's steps, which the Figma library matches at all ten. Line heights are what the site renders, including two global overrides.

xs12/16px

Almost before we knew it, we had left the ground.

sm14/20px

Almost before we knew it, we had left the ground.

base16/24px

Almost before we knew it, we had left the ground.

lg18/28px

Almost before we knew it, we had left the ground.

xl20/24px

Almost before we knew it, we had left the ground.

2xl24/32px

Almost before we knew it, we had left the ground.

3xl30/34px

Almost before we knew it, we had left the ground.

4xl36/40px

Almost before we knew it, we had left the ground.

5xl48/48px

Almost before we knew it, we had left the ground.

6xl60/60px

Almost before we knew it, we had left the ground.

Where the site departs from Tailwind

  • xl — renders at 24px, Tailwind's default is 28px.
    Set to 24px so 20px BOLD headings lead correctly. Applies globally, so 20px MEDIUM text — which the Figma library specifies at 28px — cannot be produced on the site. Tailwind ties line height to size alone, so one of the two variants must lose.
    app/app/assets/css/main.css --text-xl--line-height
  • 3xl — renders at 34px, Tailwind's default is 36px.
    Matches neither Tailwind (36px) nor the Figma library (36px). 2.125rem looks like a typo for 2.25rem. Recorded as rendered; not corrected, because correcting it would move every H2 and H3 on the site.
    app/app/assets/css/main.css --text-3xl--line-height

Serif — Newsreader

Almost before we knew it, we had left the ground.

Weights available: sans 400 / 500 / 700; serif 400 / 500. Nothing else is loaded, so asking for 600 gets a synthesised weight.

Type scale — print

Structure only. Values are null and units are pt, not px. They will be measured and typed in when the report pipeline is built, never converted from the web sizes.

xs— ptnot yet decided
sm— ptnot yet decided
base— ptnot yet decided
lg— ptnot yet decided
xl— ptnot yet decided
2xl— ptnot yet decided
3xl— ptnot yet decided
4xl— ptnot yet decided
5xl— ptnot yet decided
6xl— ptnot yet decided

Status: not-yet-decided. All 10 sizes, all line heights, all colour roles and the spacing base are unset.

Spacing

A single base unit times an integer step — Tailwind's model, used unmodified.

step 14px
step 28px
step 312px
step 416px
step 624px
step 832px
step 1248px
step 1664px

Chart colour

Three ways to address a series colour. Reach for a concept whenever the series name means something; the sequence is only for series with no inherent meaning.

Default sequence — positional

Aa5.24:1
sequence.1#5551ffon: #ffffff · AACMYK pending
Aa15.13:1
sequence.2#262626on: #ffffff · AAACMYK pending
Aa10.35:1
sequence.3#b0b6ffon: #0a0a0a · AAACMYK pending
Aa11.86:1
sequence.4#fbbf24on: #0a0a0a · AAACMYK pending
Aa4.82:1
sequence.5#338d5don: #0a0a0a · AACMYK pending
Aa7.13:1
sequence.6#fd6c72on: #0a0a0a · AAACMYK pending
Aa7.85:1
sequence.7#a3a3a3on: #0a0a0a · AAACMYK pending
Aa10.7:1
sequence.8#2716c0on: #ffffff · AAACMYK pending

Concept — fuel types, fixed meaning

Aa13.89:1
concept.solar#fed500on: #0a0a0a · AAACMYK pending
Aa5.63:1
concept.wind#2c7629on: #ffffff · AACMYK pending
Aa8.28:1
concept.gas#ff8813on: #0a0a0a · AAACMYK pending
Aa18.73:1
concept.coal#121212on: #ffffff · AAACMYK pending
Aa7.42:1
concept.allFuels#3245c9on: #ffffff · AAACMYK pending

Concept — sentiment, diverging

Aa16.44:1
sentiment.stronglyAgree#100a6bon: #ffffff · AAACMYK pending
Aa10.7:1
sentiment.agree#2716c0on: #ffffff · AAACMYK pending
Aa13.36:1
sentiment.unsure#d4d4d4on: #0a0a0a · AAACMYK pending
Aa7.13:1
sentiment.disagree#fd6c72on: #0a0a0a · AAACMYK pending
Aa8.16:1
sentiment.stronglyDisagree#9d171con: #ffffff · AAACMYK pending

Live charts

Rendered with the real theme through the real component. If the tokens change, these change.

Written against tokens — contains no colour literal
Migrated from the CMS — 167 lines down to 52
As published — annotation ink set by hand, white on both fills

The upper label measures 3.05:1 against its fill. AA needs 4.5:1.

The same chart from a validated spec — ink derived per label

Identical fills. The spec states no colour for either label; each one names the series it sits on and the resolver works the rest out, so the two labels end up with different ink.

Known exceptions

Recorded rather than resolved, so they stay visible. None of these are fixed by the token layer on its own.

Grey ramps in play

neutral is canonical. These are still live:

  • zinc — every Nuxt UI component. Nuxt UI resolves its own neutral to zinc, which is blue-tinted. Utility classes elsewhere resolve to Tailwind neutral. Two greys ship.
    app/app/app.config.ts — ui.colors.neutral
  • gray — 2 occurrences. bg-gray-50 and the literal #E5E7EB (gray-200, not neutral-200).
    app/app/components/Listing/NoResults.vue, Chart/HighchartsChart.vue

Unresolved colour

unresolved.chartZeroLine#333333CMYK pending

The y-axis zero line on every chart. Belongs to no ramp, and sits exactly midway between neutral-700 and neutral-800 — 13/255 from each — so there is no defensible automatic replacement. Needs a decision.

Hex the lint rule cannot reach

  • CMS chart configs. They are strings evaluated at runtime, so they cannot import tokens. A config needing black annotation text has no token-aware spelling today.
  • Inside <style> blocks. ESLint does not parse CSS, so those are invisible to the rule.
  • Brand marks. The Open Electricity logo is a third-party mark and should not be tokenised.

Register

Hand-maintained. Published reports, templates and brand assets. Adding one is one line in register.json.

report

brand asset

  • Typography library2023Figma. Last updated 2023-09-12. Sizes agree with the site; six line heights do not. Not authoritative — see Type scale.

typeface

  • SoehneLicensed. Self-hosted, three weights: 400 / 500 / 700.
  • NewsreaderGoogle Fonts. Subheads, captions, quotes.

Judgement calls

The parts that cannot be generated. Kept short on purpose.

Choosing an output

Three places a chart can end up, and they are not interchangeable.

Interactive chart (Highcharts, in the CMS)

The default for anything on the website. Readers can hover for values, the chart reflows on a phone, and the styling comes from the theme — so it stays correct when the theme changes.

Use it unless you have a specific reason not to.

Static SVG (in the CMS)

Only when a chart cannot be expressed in Highcharts — a hand-drawn schematic, an annotated diagram, something from a designer.

Be aware of what you give up. A static SVG is frozen: it will not restyle when tokens change, it will not reflow on a phone, and it carries no tooltips. The three static charts currently published also render in the wrong typeface, because the SVG stylesheet hardcodes Highcharts' default system stack rather than Soehne.

If you are reaching for static SVG because the interactive version is fiddly, fix the interactive version.

Report and deck (InDesign, Slides, PowerPoint)

Out of scope for this system today. The print token layer exists as structure for that work but holds no values yet.

Until it does, treat a chart in a deck as a separate artefact that happens to look similar — not as the same chart. Do not assume a colour picked on screen will reproduce on a page; that is exactly what the CMYK slots are for, and they are empty.

Captioning and sourcing charts

Every chart needs a source

Use the Source field on the chart block, not the chart title and not the body text. It renders beneath the chart at 10px and stays attached if the chart is moved.

Name the dataset and the year, not just the organisation. "AEMO" is not a source; "AEMO, Integrated System Plan 2024" is.

Titles carry the finding, not the variable

The title should say what the reader should take away. The axis already says what is plotted.

  • Weak: Liquid fuel demand by sector, 2026-2040
  • Better: Australia can achieve very high levels of fuel security by 2040

This is why titles live on the chart block rather than inside the config — they are editorial, and they get edited.

Attach the data

If the chart is based on a table you can publish, attach it with the Data File field. It costs nothing and it is the single most common request after a report lands.

Colour carries meaning, so do not pick it by eye

If a series is a fuel type, use the fuel concept colours — coal is always near-black, gas always orange. If a series is a level of agreement, use the sentiment scale. Readers learn these across figures, and a chart that breaks them is actively misleading.

Only reach for the default sequence when a series genuinely has no inherent meaning.

Do not choose annotation text colour by hand

Ask the theme for it. Judging legibility by eye is how a published chart ended up with white text at 3.05:1 on a light blue fill, which fails WCAG AA.