Charts & gauges

Widgets

The dashboard cards: the short form of a chart, and the tones and layouts their contents are built from.

Live React port

Try it

Sprayer Met — Delta-T
1m ago · 11:15 am
Live
4.6
Preferred for spraying
ΔT is within the optimal range
Air temp
21.8°C
Humidity
54%
Wind
11km/h
Preferred band 2 – 8 °CWind 3 – 15 km/h
Freshness
Freshness colours the meta line, adds a Late, Stale or Offline badge and greys the body. The head stays readable.

Readings over time

Each is the short form of a chart card: the latest reading, its verdict and the figures behind it. The chart view adds the trend.

Block 3 — Soil Moisture
15m ago · 11:00 am
Live
19.1%
Root zone · 30 cm
In range
Refill at 14 %, full at 26 %
10 cm · latest19.0%
30 cm · latest19.1%
60 cm · latest22.9%
Refill point
14%
Full point
26%
Last irrigated
Mon
Probe 3 depths · %VWCSet per block
Soil moisture · three depths
Dam 2 — Water Quality
16m ago · 11:00 am
7.4pH
Within the 6.5 – 8.5 compliance band
Turbidity elevated
18 NTU against a 40 NTU limit
Turbidity18NTU
pH range · 7d6.9 – 7.8
Turbidity max · 7d34NTU
Dissolved O₂
8.1mg/L
Water temp
17.4°C
Breaches
0
Water quality · two measures
Field C — Rainfall
1m ago · 10:30 am
Live
4.2mm
Today · Wed 9am – Thu 9am
YesterdayTue 9am – Wed 9am0.0mm
Last 7 days26.4mm
July58.1mm
2026412.6mm
Wettest day
7.5mm
Rain days
3
vs average
+18%
Rain day boundary 9 amBucket · 0.2 mm
Rainfall · totals per day
DAZ Beinke — Battery
1m ago · 11:15 am
Live
12.6V
Holding charge
Solar covered the last 7 nights
Overnight minimum12.1V
Solar charge · today4.8Ah
Cutoff threshold11.4V
Autonomy
6.2d
Panel
20W
Deep cycles
3
Pack 12 V · 7 Ah SLAInstalled Mar 2024
Battery · a slow decline
Sprayer Met — Fire Danger
1m ago · 11:15 am
Live
28FFDI
Forest fire danger index · rated High
Rated High until 4 pm
Hot-work permits suspended above 24
Peak · today33FFDI
Drought factor7.4
Permit threshold24FFDI
Air temp
31.2°C
Humidity
19%
Wind
27km/h
Scale McArthur Mk5Recomputed hourly
Fire danger · against a threshold

Instruments

A dial, compass or ring leads when the question is where a reading sits right now.

Field A — Wind
1m ago · 11:15 am
Live
NESWSSW210°
Latest speed14km/h
Strongest gust · 1h22km/h
Avg speed · 1h11km/h
Wind · bearing and speed
North Bore — Consumption
1m ago · 11:15 am
1,820
kL total
Day · 6:00 am – 6:00 pm1,165kL64%
Night · 6:00 pm – 6:00 am655kL36%
64% of water used during the day
Consumption · share of a budget

Flow and level

A hero number for one live value, with the stats and the table that explain it.

Bore Pump — Flow
1m ago · 11:15 am
Live
142kL/day
Daily total for the current 24-hour period
Maximum168kL
Average94kL
Total · 30 days2,818kL
Peak hour
11.4L/s
Runtime
14.2h
Starts
6
Meter factor 1 pulse = 10 LCalibrated 12 Jun
Bore pump · flow against last week
Flow Rate
1m ago · 11:15 am
Live
94L/s
Instantaneous rate at the last sample
PeriodAvg L/sPeak L/sTotal ML
24 h941688.1
7 d8818153.2
30 d91192235.9
90 d86204668.7
12 mo822312,586
Peak of record 231 L/sSampled every 5 min
Flow rate
Dam 2 — Water Temperature
48m ago · 10:28 am
17.4°C
Surface probe · 300 mm below waterline
Approaching the algal window
Bloom risk rises above 19 °C
Warmest · 7d19.8°C
Coolest · 7d14.1°C
Bloom threshold19.0°C
Daily range
3.2°C
Hours above
6.4h
Trend · 7d
+1.4°C
Water temperature · late

Schedules and forecasts

What is planned, what is running and what is coming, read against today.

Pivot 2 — Schedule
1m ago · 7:10 am
Live
48hrs
Total run time
Irrigation complete
No faults recorded
Started
Sun, 26 Jul
6:18 pm
Finished
Tue, 28 Jul
6:18 pm
ValveValve 2 — Main line
Scheduled byWestys · 26 Jul
Irrigation schedule
Channel 4 — Water Order
1m ago · 11:15 am
Live
42L/s
Current water order · next 8 hrs
Delivering on schedule
Order confirmed and active
PeriodTotal AFDuration hrs
Last 7 days217.3147
July 2026496.2360
June 2026437.8320
Ordered rate 42 L/sEnds Thu 6:00 pm
Water order · delivering
Evapotranspiration — Forecast
1h ago · 6:00 pm
4.8mm
Today's crop water demand
Yesterday5.1mm
Last 7 days4.8mm
July4.6mm
20263.9mm
Demand peaks Tue — 3.7 mm with no rain
7-day total
19.8mm
Wettest day
Fri
Deficit
-6.4mm
Model FAO-56 PenmanUpdated 6:00 pm
Evapotranspiration forecast

Six tones, five roles each

The status panel says what a reading means. Each tone sets its surface, ring, icon and two text colours, from the design system’s status tones.

Preferred for spraying
ΔT is within the optimal range
ok
Marginal for spraying
Proceed with caution
note
Action required
A valve is awaiting acknowledgement
act
Not optimal for spraying
Spraying is not recommended
bad
Currently irrigating
Pivot 1 started 42 minutes ago
live
No schedule set
This site runs on manual starts
idle
ok · note · act · bad · live · idle. act sits between note and bad: something needs a person, but nothing is wrong yet.

The canonical band

The grey one-line footer under a widget, in two shapes.

64% of water used during the day
spanel.one · idle
Preferred band 2 – 8 °CWind 3 – 15 km/h
wband · two-slot
Both use the neutral tone. Use the status panel for one line, and the band when a second value sits on the right.

Showing a reading

Three geometries, chosen by how many numbers the card has to carry at once.

12.4L/s
Latest reading · 11:15 am
hero
Air temp
21.8°C
Humidity
54%
Wind
11km/h
fact grid
Latest speed14km/h
Strongest gust · 1h22km/h
Avg speed · 1h11km/h
stat group
Hero for one number, fact grid for three, stat group for a short list.

Rows that carry state

Where a card has to show several things happening at once, it stops being a reading and becomes a list.

2 operations need attention
Zone B paused · Valve 2 alarm tripped
Zone A — DripActive
6:00 – 7:30 am62%
Zone B — DripPaused
7:45 – 10:35 am
Valve 2Alarm tripped
6:45 – 7:30 am
Valve 1Resuming
7:05 – 9:55 amAlarm cleared
Zone C — SprayUpcoming
9:00 – 9:50 am50 min
Each row names its state in a badge. The bar only fills once a run has started, so Upcoming and Paused rely on the badge.
PeriodMinAvgMax
Today4.111.819.2
Yesterday3.810.417.6
7 days2.911.122.4
A widget table is the system Table at compact density, with figures right-aligned in tabular numerals.

Tokens

TokenValueWhere it lands
--ok-surface / -ring / -icon / -title / -detail#E1FAEA · #C1F4D4 · #019939 · #004D1D · #016626One tone, five roles. The other five tones follow the same shape.
--live-*#D6F4FF · #BDEDFF · #1877F2 · #081B45 · #0C296AThe blue ramp, 200 / 300 / 1000 / 1200 / 1100. Mirrors TONE.live.
--note-*#FFF1DA · #FFE9BA · #9D6508 · #4F3304 · #764C06Squash 200 / 300 / 1000 / 1200 / 1100: the disc, title and detail each take the step that passes on the surface. Mirrors TONE.note.
--idle-surface#F5F5F5Resolves --color-grey-100. The canonical band surface.
--idle-ring#E6E6E6Resolves --color-grey-400. The band outline stroke that was called out.
--badge-ghost-bg#F1F1F1Two hops: --color-grey-200. The LATE badge.
--cat-violet#6E23C9Violet-800, mirrors CAT.violet. Categorical, not semantic.
--m-track#F5F5F5Meter track, via --idle-surface.

Charts

Area, bar, ring and state charts for sensor data that arrives at irregular intervals.

Live React portVue source: WildLineChart.vueStorybook story: Charts/Area ChartReact component: WAreaChart, WBarChartDc, WDonut, WStateTimeline

Try it

Change the range and the state, and hover the plot to read a reading.

Range
State
Answer
Band
<WAreaChart
  series={[{ data: soil30, name: '30 cm', color: SERIES_RAMP[0] }]}
  times={times}
  domain={[thu24, now]}
  yMin={10} yMax={40} unit="%"
  band={[22, 34]} bandLabel="Refill to full"
  thresholds={[{ value: 22, label: 'Refill 22%', short: '22', tone: 'warn' }]}
  answer={{
    value: latest, unit: '%', label: 'Now',
    delta: { value: change, period: 'vs 24 h ago', unit: 'pts' },
    verdict: { tone: 'ok', label: 'Above refill' },
  }}
  ariaLabel="Soil moisture at 30 cm, Block 4"
/>

When to use

  • Use an area or line chart for a level over time, such as soil moisture or tank level.
  • Use a bar chart for an amount per period, such as daily rainfall.
  • Use a state timeline for when something ran, such as irrigation zones.
  • Use stacked panels for measures in different units that share a time window.
Don’t use it
  • Never two y-axes: use stacked panels.
  • For one current reading. Use a Gauge.
  • For exact values to compare or export. Use a Table.

Series colours

Assign series in this order, and never skip a stop. Green, amber and red mean status, so keep them for verdicts and thresholds.

1 · #1877F2blue-1000
2 · #C33394magenta-700
3 · #6E23C9violet-800
4 · #0692BCteal-700
5 · #7B238Dpurple-900
Name two or more series in a Legend. A lone series needs none, because the card title names it.

Answer first

Lead with the latest reading, its change over a named period, and a verdict. The band and threshold are labelled in the right gutter, clear of the data.

<WAreaChart
  series={[{ data: soil30, name: '30 cm', color: SERIES_RAMP[0] }]}
  times={times}
  domain={[thu24, now]}
  yMin={10} yMax={40} unit="%"
  band={[22, 34]} bandLabel="Refill to full"
  thresholds={[{ value: 22, label: 'Refill 22%', short: '22', tone: 'warn' }]}
  answer={{
    value: latest, unit: '%', label: 'Now',
    delta: { value: change, period: 'vs 24 h ago', unit: 'pts' },
    verdict: { tone: 'ok', label: 'Above refill' },
  }}
  ariaLabel="Soil moisture at 30 cm, Block 4"
/>
The change arrow stays neutral, because down isn’t bad for a soil probe. Only the verdict chip carries status, with an icon and a word.

Several series

Draw soil moisture by depth as one chart, a line per probe, shallowest first.

10 cm30 cm60 cmLast 7 days
<Legend
  items={[{ label: '10 cm' }, { label: '30 cm' }, { label: '60 cm' }]}
  period="Last 7 days"
/>
<WLineChart
  series={[
    { name: '10 cm', data: soil10, times: t10 },
    { name: '30 cm', data: soil30, times: t30 },
    { name: '60 cm', data: soil60, times: t60 },
  ]}
  domain={[thu24, now]}
  minValue={10} maxValue={40} unit="%"
  height={260}
  endLabels
/>
No fill, so no line hides under another. Each line ends in its latest value, and the legend names the depths.

Gaps

Pass times, so readings sit where they happened. A missing reading breaks the line and reads n/a, never 0.

<WAreaChart
  series={[{ data: soil10, name: '10 cm', color: SERIES_RAMP[0] }]}
  times={times}       // null = a missed reading
  domain={[thu24, now]}
  yMin={0} yMax={40} unit="%"
/>
The grey band fills the plot from top to bottom and names the outage. Hover a missed reading to read n/a.

States

Set state so the chart says what it knows. A stale chart keeps its data, greyed, and says when it last heard.

loading
stale
empty
<WAreaChart … state="loading" />
<WAreaChart … state="stale" />
<WAreaChart … state="empty" />
Refetching holds the old data at 45% with a chip, so the plot never flashes a skeleton.

Bar

The scale starts at zero, so set only yMax. Lead with the total, because that’s what anyone asks of rain.

<WBarChartDc
  data={rain}          // null = the gauge missed that day
  times={days}
  yMax={12} unit="mm"
  state="partial"
  answer={{
    value: total, unit: 'mm',
    delta: { value: total - previous, period: 'vs previous 14 days' },
    verdict: { tone: 'idle', label: '1 day missing' },
  }}
/>
A missed day is an n/a column, not a 0 bar. Today’s bar is lighter and labelled so far.

Stacked panels

Give each measure its own panel on one time axis. One crosshair runs through every panel, and one readout lists them all.

Bore 2 flow fell from 2.1 to 1.4 L/s on Mon 28, so the pump ran 4.2 h on Tue, up from about 2.7 h a day.

Tank 3 · level %
Bore 2 · flow L/s
Pump runtime · h/day
2.7
2.6
2.6
2.7
3.0
4.2
<WChartStack
  domain={[thu24, wed30]}
  summary="Bore 2 flow fell from 2.1 to 1.4 L/s on Mon 28…"
  panels={[
    { key: 'tank', title: 'Tank 3 · level %', height: 130, chart: <WLineChart times={t} series={[{ name: 'Tank 3 level', data: level }]} unit="%" minValue={0} maxValue={100} thresholds={[{ value: 30, label: 'Pump on 30%', short: 'On', tone: 'neutral' }]} /> },
    { key: 'flow', title: 'Bore 2 · flow L/s', height: 80, chart: <WAreaChart times={t} series={[{ data: flow, name: 'Bore 2 flow', color: SERIES_RAMP[0] }]} yMax={2.5} unit="L/s" fill="none" minmax={false} /> },
    { key: 'runtime', title: 'Pump runtime · h/day', label: 'Pump runtime', height: 110, chart: <WBarChartDc times={days} data={hours} yMax={6} unit="h" /> },
  ]}
/>
Say what changed in the summary. Title each panel with its measure and unit.

State timeline

Give each zone its own lane. A state has no y value, so don’t plot it as a line.

RunningQueuedFaultToday
<WStateTimeline
  lanes={[
    { name: 'Zone 1', runs: [{ from: .04, to: .19, state: 'run' }] },
    { name: 'Zone 2', runs: [{ from: .30, to: .34, state: 'fault' }] },
    …
  ]}
  xLabels={['12 am', '6 am', '12 pm', '6 pm', '12 am']}
  now={0.47}
/>
A bare track is idle, and every other state has a fixed colour. Show a legend, and name any fault in text too.

Accessibility

Pass ariaLabel with a one-sentence summary; the state is added to it. Line charts and stacks are one tab stop, and a screen reader hears each reading as the arrow keys move.

KeyWhat it does
TabMoves focus to the plot.
← / →Steps to the previous or next reading. In a stack, Shift moves ten.
Home / EndJumps to the first or last reading.
EscapeHides the readout.

Props

Every engine takes times, domain, state, answer and thresholds. A reading is a number, or null for none.

WAreaChart

PropTypeDefaultDescription
seriesAreaSeries[]—Each: data, color, name, times?, raw?, dashed?, fillScale?.
times / domainnumber[] / [from, to]—Reading times and the window, in ms.
yMin / yMaxnumber0 / —The scale. Fix it per kind of reading.
unit / fmtstring / (v) => string—After each value, and how values round.
fill'flat' | 'none''flat'A flat 10% fill under the first series, or none.
band / bandLabel[lo, hi] / string—A range band, named in the gutter.
bandTone'neutral' | 'blue' | 'ok''neutral'Band tint. 'ok' only when it means healthy.
thresholdsThreshold[]—Dashed rules: value, label, short?, tone?.
endLabelsbooleanfalseLatest value per series in the gutter.
answerAnswerRowProps—Latest value, delta and verdict above the plot.
stateChartState'ready'ready, loading, refetching, empty, stale or partial.
stateMessage / stateDetailReactNode—The loading or empty message.
staleSince / partialFromnumber—Where the stale or partial tail starts.
gapMsnumber2.5 × spacingReadings further apart break the line.
xTicks / timeZoneXTick[] / stringauto / 'UTC'Explicit ticks, and the zone for labels.
ariaLabelstring—One-sentence summary that names the chart.

AnswerRowProps

PropTypeDefaultDescription
value / unitnumber | null / string—The latest reading. null prints n/a.
labelReactNode—When it was read: 'Now', '4:35 am'.
delta{ value, period, unit? }—The change against a named period, in neutral ink.
verdict{ tone, label, icon? }—The status chip. Always a word.
mutedboolean—Greys the value when it is stale.

WBarChartDc

PropTypeDefaultDescription
data / yMaxReading[] / number—A value per bucket; null is an n/a column.
times / bucketMsnumber[] / number— / a dayBucket starts, and each bucket’s length.
unit / fmtstring / (v) => string—After each value, and how values round.
partialLast / partialLabelboolean / string— / 'so far'The last bucket is unfinished.
color / colorLaststring—Bars, and the latest bar. Ramp tokens only.

WChartStack

PropTypeDefaultDescription
panelsStackPanel[]—Each: key, title, height, chart; label? and fmt?.
domain[from, to]—The shared window, in ms.
summaryReactNode—What changed, above the panels. Also its name.
gutters / gap{ left, right } / number40, 96 / 14Shared gutter widths, and space between panels.
readoutbooleantrueOne readout listing every panel.

WStateTimeline

PropTypeDefaultDescription
lanesTimelineLane[]—Each: a name, and runs as 0–1 fractions.
runs[].state'run' | 'queue' | 'idle' | 'fault'—Sets the run’s colour. Idle is the bare track.
xLabels / nowstring[] / number— / 0.47Axis labels, and the now marker.

Tokens

TokenValueWhere it lands
SERIES_RAMP#1877F2Series, in order; blue-1000 first.
SERIES_LONE#00AEEFBrand cyan, blue-900: a lone default series.
SERIES_REFERENCE#7F7D83Reference line, solid 1.5px, grey-900.
BAND_FILL.neutral#F1F1F1Range band, grey-300. The default.
BAND_FILL.blue#EBFAFFA water range band, blue-100.
BAND_EDGE.neutral#ADACB0Band bracket in the gutter, grey-800.
THRESH_LINE.warn#EC980CWarning threshold rule, squash-800.
THRESH_LINE.bad#E12121Critical threshold rule, red-800.
THRESH_LINE.neutral#4F4D55Set-point rule, such as pump on, grey-1000.
GAP_FILL#F5F5F5Gaps and stale tails, grey-200.
PARTIAL_FILL#EBFAFFThe unfinished period, blue-100.
SKELETON_FILL#F1F1F1Loading pills, grey-300.
TONE.*.surface#E1FAEAVerdict chip ground, by tone.
T.grid#F1F1F1Gridlines, grey-300.
T.baseline#E6E6E6The baseline under each plot, grey-500.
T.ink3#4F4D55Ticks, labels and the change arrow.
TIMELINE_TONE#00AEEFRunning blue-900, queued squash-800, fault red-800.
RAMP.grey[1200]#1D1C20Readout ground.

Gauges

Dials, rails and a compass for agricultural readings: Delta-T, temperature, soil moisture, wind and fire danger.

Refined portVue source: WildSoilMoistureGauge.vueReact component: WGaugeDial, WGauge, WCompass, WSoilMoisture, WFireIndex

Try it

Change the spray window, then press Replay to watch the arc sweep.

Spray window
Size
<WGaugeDial
  size={160}
  value={4.6}
  min={0}
  max={20}
  zones={DELTA_T_ZONES}
  contained
  ariaLabel="Delta-T 4.6, preferred for spraying"
  animate
/>

When to use

  • Use a dial when a reading only means something against its bands, like Delta-T or air temperature.
  • Use the soil rail for moisture read at several depths on one probe.
  • Use the compass for wind direction, which wraps round at north.
  • Use the fire arc for a fire danger index, where the rating matters more than a band edge.
Don’t use it
  • To show how a reading changed over time. Use a line chart.
  • For a reading with no bands. Show it as a number in a widget.
  • For progress towards a total. Use a progress bar.

Anatomy

A 270° dial. The track holds the value arc in the colour of the band the reading falls in, and a white marker ringed in that colour. A thin ring outside the track shows each band’s colour, and every band edge is labelled.

Delta-T · 160

Delta-T

The spray window. Green is the preferred 2–8 band, amber sits either side of it and red starts at 10.

2.0 · on the edge
4.6 · preferred
11.5 · not optimal
A reading on a band edge takes the lower band, so 2.0 reads amber.

Temperature

Pass your own zones for another scale. Temperature runs 0–50 °C in four bands, and cold takes teal so it doesn’t share amber with hot.

6.4 · 0–10 band
14.2 · 10–30 band
43.1 · 40–50 band

Soil moisture at depth

One rail per probe depth, shallowest first, so the rails sit the way the profile sits in the ground.

8″ Soil Moisture3:00 pm
8.6%VWC
16″ Soil Moisture2:00 pm
16.2%VWC
24″ Soil Moisture2:00 pm
18.8%VWC
32″ Soil Moisture1:10 pm
27.1%VWC
48″ Soil Moisture1:30 pm
40.0%VWC
Refill pointBelow refillBelow stressset per depth
The white marker is each depth’s refill point. Set each row’s colour to its status: amber below refill, red below stress.

Wind

A full circle, because 359° and 1° are neighbours. Only the direction indicator is blue.

NESWSSW210°
Bearing
The centre carries the cardinal and the bearing in text, so the needle never has to be read alone.

Fire danger

A half arc, because a fire index reads as how far up the scale, not where in a band. The rating is named in text under the number.

35FFDI
High
0150+
Rating
The arc fills to 150. Readings above 150 keep a full arc and print the actual figure.

Content

  • Name the band in text beside the dial: “Preferred for spraying”.
  • Put the unit in unit so it sets smaller than the reading.
  • Use display to round the reading without moving the arc.
  • Write soil depths with the double prime: 8″, 16″.

Accessibility

  • Give each dial an ariaLabel naming the reading and its band, so it’s heard as one image.
  • The soil rail shows status by colour alone, so name it in text too.
  • The compass announces its bearing and cardinal.
  • The fire arc is a meter capped at 0–150. Its value text carries the actual index and rating.
  • Under reduced motion the arc and the needle start at their end state.

Props

PropTypeDefaultDescription
valuenumber—The reading. The arc clamps to min and max.
min / maxnumber—Scale ends: 0–20 for Delta-T, 0–50 for Temperature.
zonesGaugeZone[]—Bands as from, to and color. DELTA_T_ZONES or TEMP_ZONES.
sizenumber · 'sm' | 'md' | 'lg'160 · 150 · mdPx for dial and compass. WFireIndex takes sm, md or lg.
trackWnumber22Track thickness in viewBox units.
containedbooleanfalsePads the box so edge labels stay inside it.
unitstring—WGaugeDial. Suffix after the reading, such as °C.
displaystring—Printed reading, when it differs from value.
ariaLabelstring—Names the dial and its band for screen readers.
animatebooleanfalseSweeps the arc, or springs the needle, on mount.
replaynumber0Increment to run the entrance again.
bearingnumber210WCompass. Needle direction in degrees.
speed / unitstring—WCompass. Centre label and sub-label, such as SSW, 210°.
idPrefixstring—WCompass. Unique per page, for its shadow filter.
rowsSoilDepth[]—WSoilMoisture. Depth, time, fill, refill point, value, colour.
fdinumber—WFireIndex. The index reading. Sets the rating and arc.
indexType'FDI' | 'FFDI' | 'GFDI''FDI'WFireIndex. Index name printed under the reading.
showValuebooleantrueWFireIndex. Prints the reading and index name inside the arc.

Tokens

TokenValueWhere it lands
RAMP.green[800]#019939Preferred band, and soil above refill.
RAMP.squash[800]#EC980CMarginal bands, and soil below refill.
RAMP.red[800]#E12121Top band, and soil below stress.
RAMP.teal[700]#0692BCTemperature’s cold band.
RAMP.grey[400]#ECECEDDial track and compass face edge.
RAMP.grey[200]#F5F5F5Soil track, compass centre, fire track.
RAMP.grey[300]#F1F1F1Fire arc ticks.
RAMP.grey[600] / [700]#DCDCDE · #C9C9CCCompass ticks.
RAMP.blue[900]#00AEEFCompass indicator, fire Moderate arc.
RAMP.green[600] · [900]#3BBA6A · #018030Fire Low arc and reading.
T.brandDeepInk#1877F2Fire Moderate reading.
RAMP.squash[700] · [1000]#FFAB1F · #9D6508Fire High arc and reading.
global-orange-700 · 900#FF6B34 · #C44518Fire Extreme arc and reading.
RAMP.red[700] · [800]#F53535 · #E12121Fire Catastrophic arc and reading.
T.ink#0A090BDial reading, compass centre, soil values.
T.ink4#4F4D55Edge labels, units, compass letters, secondary text.
T.white#FFFFFFDial marker, compass face, refill marker, value pill.
FS.xl4 · W.extrabold30px · 700Dial reading.
FS.base · W.semibold14px · 500Dial unit.
FS.xs · W.semibold11px · 500Edge labels, held at 11px at any size.