Skip to the content

Light and dark

  • Light is the default theme. Dark comes from data-theme="dark" on any element or, without an explicit theme, from the system's dark mode. data-theme="light" keeps an element light inside a dark page, so one page can show both themes side by side.
  • Both themes define the same names, and the build fails when one is missing.
  • Dark colours are their own palette steps, chosen for the dark surfaces, not an inversion of the light ones: 300 for status and brand fills and text, 900 for tints, the light neutrals for text.
  • Base tokens never point at a theme token. A custom property resolves where it is declared, so a base token built from a theme colour would keep the root theme's value inside a nested data-theme.

Text

  • Three text colours for the interface. Use color.text.primary for what people read first, and color.text.secondary for supporting text. Keep color.text.tertiary for hints, axis labels, captions and the "—" of an unknown delay or figure, next to stronger text: it misses 4.5:1 on purpose (the figures are on Accessibility), so set sentences people must read in primary or secondary.
  • color.text.inverse sits on color.surface.inverse, the primary button and pressed toggles.
  • On a coloured fill, text is color.text.on-color.dark or color.text.on-color.light, whichever the fill was paired with.
  • color.text.on-color.darkLight#12181Bpalette.neutral.900Dark#12181Bpalette.neutral.900Dark text on a coloured fill (bus, light line colours)
  • color.text.on-color.lightLight#FFFFFFpalette.neutral.0Dark#FFFFFFpalette.neutral.0White text on a coloured fill
  • color.text.primaryLight#12181Bpalette.neutral.900Dark#EBEEEBpalette.neutral.100Main text and icons; also the focus ring
  • color.text.secondaryLight#47535Apalette.neutral.600Dark#A2ADB1palette.neutral.300Supporting text beside or under the main text: labels, second lines and details
  • color.text.tertiaryLight#74818Apalette.neutral.500Dark#74818Apalette.neutral.500Hints, captions, inactive controls
  • color.text.inverseLight#FAFBF9color.surface.defaultDark#12181Bcolor.surface.defaultText on inverse surfaces: tooltips, the chart's value tip
  • color.text.successLight#067849palette.green.700Dark#3CCB80palette.green.300Text in the success colour: on time, running normally
  • color.text.warningLight#965A00palette.orange.700Dark#F0A43Apalette.orange.300Text in the warning colour
  • color.text.dangerLight#AD3600palette.red.700Dark#FF8655palette.red.300Text in the danger colour: late, delay disruptions
  • color.text.infoLight#2351AFpalette.blue.700Dark#7FA6FFpalette.blue.300Text in the info colour: early, diversions
  • color.text.brandLight#896001palette.yellow.700Dark#F2B630palette.yellow.300Text in the brand colour: brand outline buttons and emphasis on the hero page; never links

Surfaces

What each surface is for, and how they stack, is on Elevation.

A control shows hover and pressed as two steps away from its rest look, each one the eye sees: the pressed step is further from rest than the hover step, so a press answers even under a pointer that is already hovering.

  • A solid ink control takes color.surface.inverse-hover on hover and color.surface.inverse-pressed while pressed; a solid brand one takes color.surface.brand-hover and color.surface.brand-pressed. Each step is at least 1.2:1 from the one before it, and the label keeps 4.5:1 on all three.
  • A quiet or outline control, transparent at rest, lays color.surface.hover over what it sits on while hovered and color.surface.selected while pressed. These layers step less than the solid fills: a denser pressed layer would take a brand outline label under 4.5:1 in light.
  • color.surface.defaultLight#FAFBF9palette.neutral.50Dark#12181Bpalette.neutral.900Opaque panel background; text on inverse surfaces
  • color.surface.raisedLight#FFFFFFpalette.neutral.0Dark#1D2428palette.neutral.800Background of fields, checkboxes, radios and keys, and of the selected segment
  • color.surface.insetLight#EBEEEBpalette.neutral.100Dark#283237palette.neutral.700Segmented control track, counts, inset boxes
  • color.surface.overlayLightrgba(250, 251, 249, 0.9)Darkrgba(18, 24, 27, 0.88)Translucent floating panels over the map (used with backdrop blur)
  • color.surface.hoverLightrgba(18, 24, 27, 0.05)Darkrgba(235, 238, 235, 0.06)Translucent layer over a control under the pointer
  • color.surface.selectedLightrgba(18, 24, 27, 0.09)Darkrgba(235, 238, 235, 0.09)Selected row; the pressed layer of a quiet or outline control, in place of color.surface.hover and denser
  • color.surface.inverseLight#12181Bcolor.text.primaryDark#EBEEEBcolor.text.primaryPrimary buttons, pressed icon buttons, chart tooltip
  • color.surface.inverse-hoverLight#283237palette.neutral.700Dark#A2ADB1palette.neutral.300Hover fill of a primary button, a step from color.surface.inverse the eye sees
  • color.surface.inverse-pressedLight#47535Apalette.neutral.600Dark#8B979Epalette.neutral.400Pressed fill of a primary button, a step further from color.surface.inverse than its hover
  • color.scrimLightrgba(10, 14, 16, 0.42)Darkrgba(10, 14, 16, 0.42)Backdrop behind modal dialogs

Borders

  • Use color.border.subtle for hairlines: dividers, and the edges of panels and cards.
  • Use color.border.control for edges that show where a control is, such as inputs and outline buttons. It reaches 3:1 on every surface, as WCAG asks of anything that identifies a control.
  • Use color.border.strong for lines that decorate, such as dashed tags and chart axes. A control's edge takes color.border.control, which stays visible where strong would fade.
  • color.border.focus is the focus ring, in the colour of primary text. The ring's width and offset are on Semantic spacing.
  • color.border.subtleLightrgba(18, 24, 27, 0.11)Darkrgba(235, 238, 235, 0.1)Dividers and panel borders
  • color.border.strongLightrgba(18, 24, 27, 0.22)Darkrgba(235, 238, 235, 0.2)Dashed tags, axis lines: lines that decorate rather than show where a control is
  • color.border.controlLightrgba(18, 24, 27, 0.47)Darkrgba(235, 238, 235, 0.39)Edges that show where a control is: inputs, outline buttons. 3:1 or better on every surface
  • color.border.brandLight#896001palette.yellow.700Dark#F2B630palette.yellow.300Edge of a brand button, solid or outline, so the yellow reaches 3:1 on every surface
  • color.border.focusLight#12181Bcolor.text.primaryDark#EBEEEBcolor.text.primaryThe ring around the control that has keyboard focus

Status

Status colours are reserved for health, delays and problems: success, warning, danger and info. A status colour always comes with a word or an icon. Each status comes in three tokens:

  • color.status.<status> fills dots, meters, icons and counts.
  • color.text.<status> is text in that colour, 4.5:1 or better on every surface.
  • color.surface.<status> is a tinted background for a message.
  • color.status.successLight#13915Apalette.green.500Dark#3CCB80palette.green.300Healthy, on time, live share at or above 70%
  • color.status.warningLight#B06A00palette.orange.500Dark#F0A43Apalette.orange.300Partial, live share 40–69%
  • color.status.dangerLight#C2410Cpalette.red.500Dark#FF8655palette.red.300Late by 3 min or more, live share under 40%, delay disruptions
  • color.status.infoLight#2D5FC4palette.blue.500Dark#7FA6FFpalette.blue.300Running early and diversions: the info fill of alerts, toasts and meters
  • color.surface.successLight#E5FAECpalette.green.100Dark#133622palette.green.900Tinted background for a success message
  • color.surface.warningLight#FEF1E4palette.orange.100Dark#3F280Apalette.orange.900Tinted background for a warning message or count
  • color.surface.dangerLight#FEF0ECpalette.red.100Dark#452417palette.red.900Tinted background for a danger message
  • color.surface.infoLight#EEF4FFpalette.blue.100Dark#202D49palette.blue.900Tinted background for an info message

Brand

The brand colour is the yellow of the bus dot in the Mylder mark, and Perron's primary colour. It marks the main action, as a brand button, and moments of emphasis on the hero page: a band, a highlighted word. Text on the brand fill is always color.text.on-color.dark.

  • A brand button, solid or outline, has a color.border.brand edge: the light-theme fill reaches only 2.1:1 on the surfaces, and the edge carries the 3:1. Its hover fill is color.surface.brand-hover and its pressed fill color.surface.brand-pressed.
  • Ink actions (color.surface.inverse) stay for everything else, so the yellow keeps meaning the main action.
  • A brand button shares the bus badge's fill and ink label. Keep it out of rows of line and mode badges, where it reads as one.
  • Links, status and vehicles have their own colours.
  • color.surface.brandLight#D99A00palette.yellow.500Dark#F2B630palette.yellow.300Brand fill: brand buttons, hero bands and calls to action. Text on it is color.text.on-color.dark
  • color.surface.brand-hoverLight#C48A02palette.yellow.550Dark#D99A00palette.yellow.500Hover fill of a brand button, a step from color.surface.brand the eye sees
  • color.surface.brand-pressedLight#B07B05palette.yellow.600Dark#B07B05palette.yellow.600Pressed fill of a brand button, a step further from color.surface.brand than its hover
  • color.surface.brand-subtleLight#FFF2DDpalette.yellow.100Dark#3B2B07palette.yellow.900Brand tint for emphasis on the hero page, under color.text.brand
  • color.text.brandLight#896001palette.yellow.700Dark#F2B630palette.yellow.300Text in the brand colour: brand outline buttons and emphasis on the hero page; never links

Line colours

  • Line colours are the operators' own: color.transit.line.<id> for metro and S-tog, color.transit.mode.bus and color.transit.mode.regional for the rest. They stay exact, never adjusted to the brand.
  • A line colour fills a shape only in a line badge. Elsewhere it is a dot, a ring, a rail or a swatch.
  • Text on a line colour always uses its partner, color.transit.line-on.<id> or color.transit.mode.on-*.
  • Several official pairs miss 4.5:1: C 2.51:1, A 2.94:1, B 3.27:1, M4 3.56:1 and M1 4.44:1. They stay exact, set bold, with the line always named in words nearby. The test lists them.
  • color.transit.line.m1Light#0B8A44Dark#0B8A44Metro M1: fills its line badge and colours its vehicle dots, station icons, stop timeline and rail on the map
  • color.transit.line.m2Light#F0B400Dark#F0B400Metro M2: fills its line badge and colours its vehicle dots, station icons, stop timeline and rail on the map
  • color.transit.line.m3Light#E2231ADark#E2231AMetro M3 (Cityringen): fills its line badge and colours its vehicle dots, station icons, stop timeline and rail on the map
  • color.transit.line.m4Light#0090D0Dark#0090D0Metro M4: fills its line badge and colours its vehicle dots, station icons, stop timeline and rail on the map
  • color.transit.line.aLight#00A1DEDark#00A1DES-tog A: fills its line badge and colours its vehicle dots, station icons, stop timeline and rail on the map; also the S-tog dot of the Mylder mark
  • color.transit.line.bLight#4BA046Dark#4BA046S-tog B: fills its line badge and colours its vehicle dots, station icons, stop timeline and rail on the map
  • color.transit.line.cLight#F18A00Dark#F18A00S-tog C: fills its line badge and colours its vehicle dots, station icons, stop timeline and rail on the map
  • color.transit.line.eLight#7D5AA6Dark#7D5AA6S-tog E: fills its line badge and colours its vehicle dots, station icons, stop timeline and rail on the map
  • color.transit.line.fLight#F5C200Dark#F5C200S-tog F: fills its line badge and colours its vehicle dots, station icons, stop timeline and rail on the map
  • color.transit.line.hLight#DD1F2ADark#DD1F2AS-tog H: fills its line badge and colours its vehicle dots, station icons, stop timeline and rail on the map
  • color.transit.line-on.m1Light#FFFFFFcolor.text.on-color.lightDark#FFFFFFcolor.text.on-color.lightLabel text on the M1 line badge
  • color.transit.line-on.m2Light#12181Bcolor.text.on-color.darkDark#12181Bcolor.text.on-color.darkLabel text on the M2 line badge
  • color.transit.line-on.m3Light#FFFFFFcolor.text.on-color.lightDark#FFFFFFcolor.text.on-color.lightLabel text on the M3 line badge
  • color.transit.line-on.m4Light#FFFFFFcolor.text.on-color.lightDark#FFFFFFcolor.text.on-color.lightLabel text on the M4 line badge
  • color.transit.line-on.aLight#FFFFFFcolor.text.on-color.lightDark#FFFFFFcolor.text.on-color.lightLabel text on the A line badge
  • color.transit.line-on.bLight#FFFFFFcolor.text.on-color.lightDark#FFFFFFcolor.text.on-color.lightLabel text on the B line badge
  • color.transit.line-on.cLight#FFFFFFcolor.text.on-color.lightDark#FFFFFFcolor.text.on-color.lightLabel text on the C line badge
  • color.transit.line-on.eLight#FFFFFFcolor.text.on-color.lightDark#FFFFFFcolor.text.on-color.lightLabel text on the E line badge
  • color.transit.line-on.fLight#12181Bcolor.text.on-color.darkDark#12181Bcolor.text.on-color.darkLabel text on the F line badge
  • color.transit.line-on.hLight#FFFFFFcolor.text.on-color.lightDark#FFFFFFcolor.text.on-color.lightLabel text on the H line badge
  • color.transit.mode.busLight#D99A00palette.yellow.500Dark#F2B630palette.yellow.300Every bus line: fills bus badges and colours bus dots, station icons and stop timelines; also the bus dot of the Mylder mark
  • color.transit.mode.regionalLight#232C31Dark#EEF1F0Regional and Øresund trains
  • color.transit.mode.on-busLight#12181Bcolor.text.on-color.darkDark#12181Bcolor.text.on-color.darkLabel text on bus badges
  • color.transit.mode.on-regionalLight#FAFBF9color.surface.defaultDark#12181Bcolor.surface.defaultLabel text on regional train badges

Delays and disruptions

Delay and disruption colours point at the status text colours. When each is used is on Data states.

  • color.transit.delay.on-timeLight#067849color.text.successDark#3CCB80color.text.successDelay text when on time
  • color.transit.delay.slightLight#12181Bcolor.text.primaryDark#EBEEEBcolor.text.primaryLate by 1–2 min
  • color.transit.delay.lateLight#AD3600color.text.dangerDark#FF8655color.text.dangerLate by 3 min or more
  • color.transit.delay.earlyLight#2351AFcolor.text.infoDark#7FA6FFcolor.text.infoDelay text when early
  • color.transit.delay.unknownLight#74818Acolor.text.tertiaryDark#74818Acolor.text.tertiaryDelay text when there is no real-time data
  • color.transit.severity.delayLight#AD3600color.text.dangerDark#FF8655color.text.dangerIcon and label for delays
  • color.transit.severity.dataLight#47535Acolor.text.secondaryDark#A2ADB1color.text.secondaryIcon and label for data feed problems
  • color.transit.severity.diversionLight#2351AFcolor.text.infoDark#7FA6FFcolor.text.infoIcon and label for diversions
  • color.transit.severity.plannedLight#47535Acolor.text.secondaryDark#A2ADB1color.text.secondaryIcon and label for planned works
  • color.transit.severity.noticeLight#47535Acolor.text.secondaryDark#A2ADB1color.text.secondaryIcon and label for service notices

Data states

  • color.data-state.no-signalLight#9AA4A9Dark#5F6B71Vehicle dot fill when a vehicle has been silent past the ageing threshold
  • color.data-state.haloLight#EDEFEBcolor.map.landDark#151B1Ecolor.map.landMap only: ring under each dot
  • color.data-state.outlineLightrgba(18, 24, 27, 0.45)Darkrgba(0, 0, 0, 0)Map only: outline around light line colours on a light map

Charts

A chart with one series draws it in color.chart.series, with the area under a line at opacity.series-fill. Values and labels stay in text colours, never in the series colour.

TokenLightDark
color.chart.seriesSingle data series (vehicles in service curve)
#2B6C8C
#6DB3D8
opacity.series-fillArea under a chart line
0.12
0.12

Map

The map's ground. How the map is drawn is on Map.

  • color.map.waterLight#C4D4DDDark#0A1115Sea, lakes and the page behind the map
  • color.map.landLight#EDEFEBDark#151B1ELand, the map's main ground
  • color.map.parkLight#D8E4D2Dark#16231EParks and green areas
  • color.map.streetLight#FFFFFFDark#252D31Roads and streets, drawn over the land
  • color.map.airportLight#E2E5E1Dark#1C2326Airport grounds, under the runways and taxiways
  • color.map.runwayLight#CBD1CEDark#2B3438Runways and taxiways, drawn over the airport grounds
  • color.map.buildingLight#E2E5E0Dark#1A2125Building footprints at close zoom, on the flat map
  • color.map.building-3dLight#D3D9D4Dark#2A33383D buildings, walls and roofs: the map's light shades each face from it
  • color.map.railLight#BCC4C1Dark#323C41Rail tracks without a coloured line on them
  • color.map.labelLight#66737ADark#7E8B91Place names on land; names on water use color.map.water-label
  • color.map.water-labelLight#5F7A88Dark#4B6774Names of seas, lakes and harbours, set on the water
  • color.map.aircraftLight#B3127ADark#F27BC8The aircraft glyph on the map, and nothing else; a no-signal aircraft is grey