← IndustryOS Design Pack
01

Web app design system

Every IndustryOS app starts from this frame: navy sidebar, white topbar, one page rhythm, one component set, one motion language. Product colour appears in the logo slot and in status only.

1.1

Live shell reference

Sidebar nav is clickable
IndustryOS / {{ pageName }}

Operations overview

Plan against actual across the site. Variances beyond tolerance require sign-off.

Development metres
1,240
▲ 4vs last shift
Plan adherence
96.2%
▲ 2watch list
Ore tonnes hoisted
84.6k
▼ 1vs last shift
Open variances
3
▬ 0since 04:00

Active headings

live View all
Heading Metres Δ plan Status
ND-14 Decline 142.6 −12.4 Danger
ND-16 Crosscut 96.2 −6.2 Warning
SD-08 Drive 88.4 −1.8 Caution
SD-11 Ore drive 120.8 +2.4 Healthy
WP-02 Portal 120.8 +3.1 Healthy

This shift

98.6%
Plan adherence, shift to date
Metres advanced118.4
Fleet utilisation88.1%

Headings

Every active heading and its progress against plan. Filter by area, crew, or state.

Heading Area Metres Crew Status
ND-14 Decline North decline 142.6 Crew A Danger
ND-16 Crosscut North decline 96.2 Crew B Warning
SD-08 Drive South decline 88.4 Crew A Caution
ED-05 Decline North decline 74.0 Crew C Caution
SD-11 Ore drive North decline 120.8 Crew B Healthy
WP-02 Portal West portal 120.8 Crew C Healthy

Variances

Three variances open. Anything beyond tolerance needs a superintendent sign-off before the next shift.

Danger North decline · 12.4 m behind plan 04:12 AEST

Three consecutive shifts behind the development schedule. Jumbo availability is the stated cause; recovery plan due this shift.

Warning Stope 14 · paste pour held 05:48 AEST

Barricade cure below target in Safewall. Pour rescheduled to the back shift.

Caution Crew B · 6.2% under shift target 06:30 AEST

Within tolerance. Review at the shift handover, no action required now.

Sidebar 250px, navy #17263c. Text #c4d2e0, secondary #8aa0b8, active white on raised navy #1d3a58 with a 3px cyan indicator. Collapses to 66px, icons only.
Topbar 58px, white, 1px bottom border. Breadcrumb left, jump-search, then context pill and icon cluster right. Sticky above content.
Content Page background #eeeeee (Paper), padding on the 24px step. One page per route; page head → KPI row → card grids → tables.
Product slot Only the logo and status carry warm colour. Chrome stays navy + cyan so planning, barricade cure, and re-entry monitoring all feel like one product.
1.1a

Product skin — Minefox

Same frame, product identity

Same frame, product identity. This variant goes further than the platform rule: the product colour replaces cyan as the interactive accent throughout — primary buttons, active nav indicator, links, avatar — alongside the lockup, the rule under the logo slot, the page eyebrow, and the card edge. Navy chrome, neutrals, and the four-step status scale are untouched.

Minefox / Plan vs actual
Week 31 · FY26
RM
Minefox · Mine planning

Plan vs actual — Week 31

Development and production against the approved weekly plan. Variances beyond ±5% require planner sign-off.

Metres planned
1,320
approved 12 Jul
Metres achieved
1,240
−6.1%vs plan
Ore tonnes
84.6k
+1.8%vs plan
Fleet utilisation
88.1%
target 90.0%

Development by area

metres, week to date Open in schedule
Area Plan Actual Variance
ND-14 DeclineJumbo 2 155.0 142.6 ✕ −8.0%
ND-16 CrosscutJumbo 1 102.4 96.2 ! −6.1%
SD-08 DriveJumbo 3 90.0 88.4 ▲ −1.8%
SD-11 Ore driveJumbo 2 118.0 120.8 ✓ +2.4%
WP-02 PortalJumbo 1 117.2 120.8 ✓ +3.1%

Week 31 adherence

93.9%
Development plan adherence
0%target 95%
Shifts lost to standby2.5
Rehandle1,840 t
Two variances open

ND-14 and ND-16 are behind plan on ground support delays. Planner sign-off required before the Week 32 plan publishes.

Changes per product Lockup, the 3px rule under the logo slot, the page eyebrow, and the top edge of the product's primary card. Nothing else.
Under review · accent takeover This mockup tries the product colour as the interactive accent: red primary buttons, active indicator, links, avatar. Navy chrome and the neutral ramp are unchanged.
Watch the collision Minefox red is also Danger. With red as the accent, a red button and a red breach badge now share one colour — the cost of the takeover. Status keeps its icon and label, which is what still separates them.
1.2

Buttons and controls

Below the minimum shift target for this heading.
Primary = cyan fill, navy text. Dark = navy fill, white text — one per view. Ghost and bordered for secondary. Destructive uses danger ink on white, never a red fill. Radius 8px buttons, 4px inputs; focus ring is always cyan at 16% over a 1px cyan border.
1.3

Status, tags, banners

Status pill · small — tint plus ink
Danger Warning Caution Healthy Offline SNSR-4471
Solid badge · large only — navy text on the warm fill
Danger Warning Healthy
Status dot · dense rows and live readouts
Danger Caution Healthy · live
Danger ND-14 is 12.4 m behind plan for a third shift. Recovery plan required before the next shift.
Warning Stope 14 paste pour held — barricade cure below target in Safewall.
Healthy All 142 headings reporting. Last ingest 12 seconds ago.
Info Scheduled maintenance Sunday 02:00–04:00 AEST.
Two treatments only — StatusPill and StatusDot. Small pills use a status tint with the darker ink variant, because 11px navy on a saturated warm fill fails AA. Solid fills are reserved for large badges, where navy text is big enough to sit on the colour. Tinted banners carry navy body text with the state named in its ink variant. No state is ever expressed by colour alone.
1.4

Loading and empty states

Loading · skeleton
Empty No headings assigned to this area yet.
Failed Fleet telemetry unreachable. Last sync 14 minutes ago.
Toast
Variance signed off by J. Arundell.
Bottom-right, 4s auto-dismiss, one at a time. Errors persist until dismissed.
1.5

Motion

Motion confirms a change; it never performs. Nothing in an operational UI moves for longer than 250ms, and safety-critical content never animates in — it appears.

TokenDuration / easingApplied to
motion-instant120ms easeHover, focus ring, button press, tag colour
motion-ui180ms easeSidebar collapse, dropdown open, segmented switch, accordion
motion-page250ms ease-outRoute change: opacity 0→1, translateY 6px→0
motion-lift120ms easeCard / KPI hover: translateY -2px, card shadow → raised
motion-live2s infiniteHealthy pulse ring on live-data indicators only
motion-skeleton1.4s linearShimmer while data loads; never for waits under 300ms
Hover me · motion-lift 98.6%
motion-live
Streaming
Never animate Alarm banners, sign-off dialogs, and numeric readings. No count-up, no bounce, no attention loops. Honour prefers-reduced-motion by dropping transforms and keeping opacity only.
1.6

Icons

Lucide · the icon standard

One family, one grid, one stroke. Lucide at 18px in nav, buttons and table cells; 20px in page heads; 16px inside small buttons. Stroke stays at 1.75 to match Inter's weight and never drops below 1.5. Colour is always currentColor, so an icon inherits the status ink or button foreground it sits in.

Navigation
Actions
Status — inherits the ink it sits in
Never mix families, never fill an icon, never use emoji or Unicode geometry as an icon. An icon alone never carries meaning — it accompanies a label, or it is decorative and hidden from assistive tech.
1.7

Type roles

Never set font-size inline

Each role bundles size, weight and line-height, so a heading is a name rather than three numbers. Hierarchy is built from size and colour — weight tops out at 700, and 800 exists only inside logo artwork.

ClassSpecSpecimen
.ios-display40/44 700Site overview
.ios-h130/36 700Plan vs actual
.ios-h224/30 600Cure cycles
.ios-h319/26 600Barricade NR-ST14-B2
.ios-body15/23 400Readings arrive every fifteen minutes.
.ios-label11/14 600 capsLast reviewed
.ios-data14 mono 50041.8 °C · 74%
.ios-kpi28 mono 50093.9%
1.8

Tokens and theming

Two layers, one source

Components reference roles; themes swap values. An app imports styles.css and touches nothing else — no local hex, no redefined palette, no second truth.

Layer 1 · raw ramps The palette, type scale and spacing steps. Named for what they are: --ios-cyan, --ios-neutral-200, --ios-danger. Never referenced directly by a component.
Layer 2 · semantic roles Named for what they do: --ios-button-primary-bg, --ios-card-bg, --ios-status-danger-tint. This is the only layer a component or an app may read.
Dark theme Set data-theme="dark" on any container. Only layer 2 moves — the ramps never change. Status hues hold their meaning; the tints darken so the ink stays legible.
Danger Warning Healthy
Product accent A product surface sets data-brand and the accent role repoints to that brand's colour. The frame, spacing and type never change — only the accent.
1.9

Build contract

Non-negotiable Import styles.css and reference the semantic roles — no raw hex, and no reading layer 1 directly. Sidebar + topbar shell on every route. Numbers in JetBrains Mono, tabular. Table rows at least 44px. Status = tint + icon + label. One primary action per view. Every interactive element is a real button or a, never a clickable div, and keeps its cyan focus ring.
Breakpoints 1400 and up: four-up KPI row. 1100–1399: two-up. Below 1100: sidebar collapses to icons, grids stack, tables gain horizontal scroll with the first column pinned.
Framework-agnostic names Component names carry across React, Vue, and Svelte: AppShell · SideNav · TopBar · PageHead · KpiTile · Card · DataTable · StatusPill · StatusDot · Banner · Toast · FilterBar · Icon · EmptyState · Skeleton. Same names, same props, every codebase.
Dark surfaces Token-swapped only, via data-theme="dark": bg #0f1926, surface #17263c, border #2c3e57, text #eef2f7. Status hues never change; tints darken and ink variants lighten.