Colors
Two first-class schemes: Feather (light) and Low flame / Dusk (dark). Every pairing below is a measured WCAG claim, re-asserted by build/contrast-test.mjs on every CI run. Click any swatch to copy its hex.
No green. Ever. The fern family is retired. Confirmation, success and live states are the blue pair (
--confirm / --confirm-soft). The contrast test fails the build if a fern hex reappears.Feather (light) — :root
--background
#F8FAFC
4.97:1 — coral-deep as text on ground
6.44:1 — confirm on ground
4.99:1 — waiting on ground
6.44:1 — confirm on ground
4.99:1 — waiting on ground
--foreground
#18222B
5.76:1 — ink on coral (primary button text)
15.41:1 — foreground on background. Also the NEW-MESSAGES PILL's plate against the thread it floats over: ink on ground is the pill's fill read the other way round, and a floating object has to be findable against whatever scrolls under it, which is the argument for a filled pill rather than an outlined one
14.03:1 — foreground on secondary wash
15.41:1 — foreground on background. Also the NEW-MESSAGES PILL's plate against the thread it floats over: ink on ground is the pill's fill read the other way round, and a floating object has to be findable against whatever scrolls under it, which is the argument for a filled pill rather than an outlined one
14.03:1 — foreground on secondary wash
--card
#FFFFFF
2.80:1 (must fail, does) — white on coral must FAIL (that is why ink, never white)
5.20:1 — coral-deep as text on white
6.74:1 — confirm on card
5.20:1 — coral-deep as text on white
6.74:1 — confirm on card
--card-foreground
#18222B
5.76:1 — ink on coral (primary button text)
15.41:1 — foreground on background. Also the NEW-MESSAGES PILL's plate against the thread it floats over: ink on ground is the pill's fill read the other way round, and a floating object has to be findable against whatever scrolls under it, which is the argument for a filled pill rather than an outlined one
14.03:1 — foreground on secondary wash
15.41:1 — foreground on background. Also the NEW-MESSAGES PILL's plate against the thread it floats over: ink on ground is the pill's fill read the other way round, and a floating object has to be findable against whatever scrolls under it, which is the argument for a filled pill rather than an outlined one
14.03:1 — foreground on secondary wash
--popover
#FFFFFF
2.80:1 (must fail, does) — white on coral must FAIL (that is why ink, never white)
5.20:1 — coral-deep as text on white
6.74:1 — confirm on card
5.20:1 — coral-deep as text on white
6.74:1 — confirm on card
--popover-foreground
#18222B
5.76:1 — ink on coral (primary button text)
15.41:1 — foreground on background. Also the NEW-MESSAGES PILL's plate against the thread it floats over: ink on ground is the pill's fill read the other way round, and a floating object has to be findable against whatever scrolls under it, which is the argument for a filled pill rather than an outlined one
14.03:1 — foreground on secondary wash
15.41:1 — foreground on background. Also the NEW-MESSAGES PILL's plate against the thread it floats over: ink on ground is the pill's fill read the other way round, and a floating object has to be findable against whatever scrolls under it, which is the argument for a filled pill rather than an outlined one
14.03:1 — foreground on secondary wash
--primary
#FF6B5A
5.76:1 — ink on coral (primary button text)
2.80:1 (must fail, does) — white on coral must FAIL (that is why ink, never white)
2.55:1 (must fail, does) — full coral as the AgentScreen live dot must FAIL the 3.0 non-text bar on the panel (2.55:1) — this is the claim that MAKES the coral-deep substitution safe: without it the page could go on printing the comparison while the value moved. The dot is coral-deep instead, claimed just above
2.80:1 (must fail, does) — white on coral must FAIL (that is why ink, never white)
2.55:1 (must fail, does) — full coral as the AgentScreen live dot must FAIL the 3.0 non-text bar on the panel (2.55:1) — this is the claim that MAKES the coral-deep substitution safe: without it the page could go on printing the comparison while the value moved. The dot is coral-deep instead, claimed just above
--primary-foreground
#18222B
5.76:1 — ink on coral (primary button text)
15.41:1 — foreground on background. Also the NEW-MESSAGES PILL's plate against the thread it floats over: ink on ground is the pill's fill read the other way round, and a floating object has to be findable against whatever scrolls under it, which is the argument for a filled pill rather than an outlined one
14.03:1 — foreground on secondary wash
15.41:1 — foreground on background. Also the NEW-MESSAGES PILL's plate against the thread it floats over: ink on ground is the pill's fill read the other way round, and a floating object has to be findable against whatever scrolls under it, which is the argument for a filled pill rather than an outlined one
14.03:1 — foreground on secondary wash
--secondary
#EAF0F4
14.03:1 — foreground on secondary wash
14.03:1 — rail label on the active row (sidebarAccent)
1.15:1 (must fail, does) — the quiet disc (the + control) and the quiet button have essentially no plate contrast against the field (1.15:1), BY DESIGN — they are identified by their GLYPH and their label instead (ink on the quiet fill measures 14.03:1), which is why every icon in this section is a drawn SVG and never a text glyph
14.03:1 — rail label on the active row (sidebarAccent)
1.15:1 (must fail, does) — the quiet disc (the + control) and the quiet button have essentially no plate contrast against the field (1.15:1), BY DESIGN — they are identified by their GLYPH and their label instead (ink on the quiet fill measures 14.03:1), which is why every icon in this section is a drawn SVG and never a text glyph
--secondary-foreground
#18222B
5.76:1 — ink on coral (primary button text)
15.41:1 — foreground on background. Also the NEW-MESSAGES PILL's plate against the thread it floats over: ink on ground is the pill's fill read the other way round, and a floating object has to be findable against whatever scrolls under it, which is the argument for a filled pill rather than an outlined one
14.03:1 — foreground on secondary wash
15.41:1 — foreground on background. Also the NEW-MESSAGES PILL's plate against the thread it floats over: ink on ground is the pill's fill read the other way round, and a floating object has to be findable against whatever scrolls under it, which is the argument for a filled pill rather than an outlined one
14.03:1 — foreground on secondary wash
--muted
#F1F5F8
6.11:1 — muted-foreground on muted
6.11:1 — rail label at rest, muted on the rail ground
6.11:1 — status pill, muted on muted (waiting on a third party)
6.11:1 — rail label at rest, muted on the rail ground
6.11:1 — status pill, muted on muted (waiting on a third party)
--muted-foreground
#4E5E6B
6.40:1 — muted-foreground on background
6.11:1 — muted-foreground on muted
6.11:1 — rail label at rest, muted on the rail ground
6.11:1 — muted-foreground on muted
6.11:1 — rail label at rest, muted on the rail ground
--accent
#EAF0F4
14.03:1 — foreground on secondary wash
14.03:1 — rail label on the active row (sidebarAccent)
1.15:1 (must fail, does) — the quiet disc (the + control) and the quiet button have essentially no plate contrast against the field (1.15:1), BY DESIGN — they are identified by their GLYPH and their label instead (ink on the quiet fill measures 14.03:1), which is why every icon in this section is a drawn SVG and never a text glyph
14.03:1 — rail label on the active row (sidebarAccent)
1.15:1 (must fail, does) — the quiet disc (the + control) and the quiet button have essentially no plate contrast against the field (1.15:1), BY DESIGN — they are identified by their GLYPH and their label instead (ink on the quiet fill measures 14.03:1), which is why every icon in this section is a drawn SVG and never a text glyph
--accent-foreground
#18222B
5.76:1 — ink on coral (primary button text)
15.41:1 — foreground on background. Also the NEW-MESSAGES PILL's plate against the thread it floats over: ink on ground is the pill's fill read the other way round, and a floating object has to be findable against whatever scrolls under it, which is the argument for a filled pill rather than an outlined one
14.03:1 — foreground on secondary wash
15.41:1 — foreground on background. Also the NEW-MESSAGES PILL's plate against the thread it floats over: ink on ground is the pill's fill read the other way round, and a floating object has to be findable against whatever scrolls under it, which is the argument for a filled pill rather than an outlined one
14.03:1 — foreground on secondary wash
--destructive
oklch(0.577 0.245 27.325)
--border
#E2E9EF
--input
#E2E9EF
--rule
rgba(78, 94, 107, 0.7)
--disabled-fill
#EAF0F4
14.03:1 — foreground on secondary wash
14.03:1 — rail label on the active row (sidebarAccent)
1.15:1 (must fail, does) — the quiet disc (the + control) and the quiet button have essentially no plate contrast against the field (1.15:1), BY DESIGN — they are identified by their GLYPH and their label instead (ink on the quiet fill measures 14.03:1), which is why every icon in this section is a drawn SVG and never a text glyph
14.03:1 — rail label on the active row (sidebarAccent)
1.15:1 (must fail, does) — the quiet disc (the + control) and the quiet button have essentially no plate contrast against the field (1.15:1), BY DESIGN — they are identified by their GLYPH and their label instead (ink on the quiet fill measures 14.03:1), which is why every icon in this section is a drawn SVG and never a text glyph
--on-disabled
#4E5E6B
6.40:1 — muted-foreground on background
6.11:1 — muted-foreground on muted
6.11:1 — rail label at rest, muted on the rail ground
6.11:1 — muted-foreground on muted
6.11:1 — rail label at rest, muted on the rail ground
--ring
#FF6B5A
5.76:1 — ink on coral (primary button text)
2.80:1 (must fail, does) — white on coral must FAIL (that is why ink, never white)
2.55:1 (must fail, does) — full coral as the AgentScreen live dot must FAIL the 3.0 non-text bar on the panel (2.55:1) — this is the claim that MAKES the coral-deep substitution safe: without it the page could go on printing the comparison while the value moved. The dot is coral-deep instead, claimed just above
2.80:1 (must fail, does) — white on coral must FAIL (that is why ink, never white)
2.55:1 (must fail, does) — full coral as the AgentScreen live dot must FAIL the 3.0 non-text bar on the panel (2.55:1) — this is the claim that MAKES the coral-deep substitution safe: without it the page could go on printing the comparison while the value moved. The dot is coral-deep instead, claimed just above
--confirm
#3E5D86
6.44:1 — confirm on ground
6.74:1 — confirm on card
5.78:1 — confirm on confirm-soft
6.74:1 — confirm on card
5.78:1 — confirm on confirm-soft
--confirm-soft
#E8EEF7
5.78:1 — confirm on confirm-soft
13.82:1 — foreground on member bubble
13.82:1 — the thread, the member's own words on the member bubble, held to the same 7.0 as hers; the palette page claims this pair at 4.5 for a chip, and a bubble is not a chip
13.82:1 — foreground on member bubble
13.82:1 — the thread, the member's own words on the member bubble, held to the same 7.0 as hers; the palette page claims this pair at 4.5 for a chip, and a bubble is not a chip
--waiting
#A9560B
4.99:1 — waiting on ground
4.66:1 — waiting on waiting-soft
5.22:1 — a refusal reason sits in the chat card's SUBTITLE slot, in the waiting amber — beside the field that caused it and never in a toast, so it has to hold as body text on the card rather than merely be findable. (The dark counterpart is the existing 'dark: waiting gold on card'.)
4.66:1 — waiting on waiting-soft
5.22:1 — a refusal reason sits in the chat card's SUBTITLE slot, in the waiting amber — beside the field that caused it and never in a toast, so it has to hold as body text on the card rather than merely be findable. (The dark counterpart is the existing 'dark: waiting gold on card'.)
--waiting-soft
#FBF1DE
4.66:1 — waiting on waiting-soft
--bubble-member
#E8EEF7
5.78:1 — confirm on confirm-soft
13.82:1 — foreground on member bubble
13.82:1 — the thread, the member's own words on the member bubble, held to the same 7.0 as hers; the palette page claims this pair at 4.5 for a chip, and a bubble is not a chip
13.82:1 — foreground on member bubble
13.82:1 — the thread, the member's own words on the member bubble, held to the same 7.0 as hers; the palette page claims this pair at 4.5 for a chip, and a bubble is not a chip
--coral-deep
#C63A28
5.20:1 — coral-deep as text on white
4.97:1 — coral-deep as text on ground
4.76:1 — coral-deep on coral-soft wash
4.97:1 — coral-deep as text on ground
4.76:1 — coral-deep on coral-soft wash
--coral-soft
#FFF2EF
4.76:1 — coral-deep on coral-soft wash
--coral-hover
#FF7A6B
6.33:1 — ink on coral-hover (primary button, hovered)
2.55:1 (must fail, does) — white on coral-hover must FAIL (hover keeps ink type)
2.55:1 (must fail, does) — white on coral-hover must FAIL (hover keeps ink type)
--sidebar
#F1F5F8
6.11:1 — muted-foreground on muted
6.11:1 — rail label at rest, muted on the rail ground
6.11:1 — status pill, muted on muted (waiting on a third party)
6.11:1 — rail label at rest, muted on the rail ground
6.11:1 — status pill, muted on muted (waiting on a third party)
--sidebar-foreground
#18222B
5.76:1 — ink on coral (primary button text)
15.41:1 — foreground on background. Also the NEW-MESSAGES PILL's plate against the thread it floats over: ink on ground is the pill's fill read the other way round, and a floating object has to be findable against whatever scrolls under it, which is the argument for a filled pill rather than an outlined one
14.03:1 — foreground on secondary wash
15.41:1 — foreground on background. Also the NEW-MESSAGES PILL's plate against the thread it floats over: ink on ground is the pill's fill read the other way round, and a floating object has to be findable against whatever scrolls under it, which is the argument for a filled pill rather than an outlined one
14.03:1 — foreground on secondary wash
--sidebar-primary
#FF6B5A
5.76:1 — ink on coral (primary button text)
2.80:1 (must fail, does) — white on coral must FAIL (that is why ink, never white)
2.55:1 (must fail, does) — full coral as the AgentScreen live dot must FAIL the 3.0 non-text bar on the panel (2.55:1) — this is the claim that MAKES the coral-deep substitution safe: without it the page could go on printing the comparison while the value moved. The dot is coral-deep instead, claimed just above
2.80:1 (must fail, does) — white on coral must FAIL (that is why ink, never white)
2.55:1 (must fail, does) — full coral as the AgentScreen live dot must FAIL the 3.0 non-text bar on the panel (2.55:1) — this is the claim that MAKES the coral-deep substitution safe: without it the page could go on printing the comparison while the value moved. The dot is coral-deep instead, claimed just above
--sidebar-primary-foreground
#18222B
5.76:1 — ink on coral (primary button text)
15.41:1 — foreground on background. Also the NEW-MESSAGES PILL's plate against the thread it floats over: ink on ground is the pill's fill read the other way round, and a floating object has to be findable against whatever scrolls under it, which is the argument for a filled pill rather than an outlined one
14.03:1 — foreground on secondary wash
15.41:1 — foreground on background. Also the NEW-MESSAGES PILL's plate against the thread it floats over: ink on ground is the pill's fill read the other way round, and a floating object has to be findable against whatever scrolls under it, which is the argument for a filled pill rather than an outlined one
14.03:1 — foreground on secondary wash
--sidebar-accent
#EAF0F4
14.03:1 — foreground on secondary wash
14.03:1 — rail label on the active row (sidebarAccent)
1.15:1 (must fail, does) — the quiet disc (the + control) and the quiet button have essentially no plate contrast against the field (1.15:1), BY DESIGN — they are identified by their GLYPH and their label instead (ink on the quiet fill measures 14.03:1), which is why every icon in this section is a drawn SVG and never a text glyph
14.03:1 — rail label on the active row (sidebarAccent)
1.15:1 (must fail, does) — the quiet disc (the + control) and the quiet button have essentially no plate contrast against the field (1.15:1), BY DESIGN — they are identified by their GLYPH and their label instead (ink on the quiet fill measures 14.03:1), which is why every icon in this section is a drawn SVG and never a text glyph
--sidebar-accent-foreground
#18222B
5.76:1 — ink on coral (primary button text)
15.41:1 — foreground on background. Also the NEW-MESSAGES PILL's plate against the thread it floats over: ink on ground is the pill's fill read the other way round, and a floating object has to be findable against whatever scrolls under it, which is the argument for a filled pill rather than an outlined one
14.03:1 — foreground on secondary wash
15.41:1 — foreground on background. Also the NEW-MESSAGES PILL's plate against the thread it floats over: ink on ground is the pill's fill read the other way round, and a floating object has to be findable against whatever scrolls under it, which is the argument for a filled pill rather than an outlined one
14.03:1 — foreground on secondary wash
--sidebar-border
#E2E9EF
--sidebar-ring
#FF6B5A
5.76:1 — ink on coral (primary button text)
2.80:1 (must fail, does) — white on coral must FAIL (that is why ink, never white)
2.55:1 (must fail, does) — full coral as the AgentScreen live dot must FAIL the 3.0 non-text bar on the panel (2.55:1) — this is the claim that MAKES the coral-deep substitution safe: without it the page could go on printing the comparison while the value moved. The dot is coral-deep instead, claimed just above
2.80:1 (must fail, does) — white on coral must FAIL (that is why ink, never white)
2.55:1 (must fail, does) — full coral as the AgentScreen live dot must FAIL the 3.0 non-text bar on the panel (2.55:1) — this is the claim that MAKES the coral-deep substitution safe: without it the page could go on printing the comparison while the value moved. The dot is coral-deep instead, claimed just above
Low flame (dark) — .dark
The dark --confirm value #8FB2DC was derived by measurement: the spec asked for a lift of the light confirm blue to ≥ 4.5:1 on the #1F2833 card; it measures 6.79:1 there and 7.62:1 on the page ground.
--background
#171E2A
12.61:1 — foreground on background. Also the new-messages pill's plate against the dark thread, the same pairing read the other way round
6.27:1 — muted-foreground on background
7.62:1 — confirm on background
6.27:1 — muted-foreground on background
7.62:1 — confirm on background
--foreground
#DCE0E5
12.61:1 — foreground on background. Also the new-messages pill's plate against the dark thread, the same pairing read the other way round
11.24:1 — foreground on card
8.14:1 — foreground on member bubble
11.24:1 — foreground on card
8.14:1 — foreground on member bubble
--card
#1F2833
11.24:1 — foreground on card
6.79:1 — confirm on card (the DERIVED value)
8.05:1 — waiting gold on card
6.79:1 — confirm on card (the DERIVED value)
8.05:1 — waiting gold on card
--card-foreground
#DCE0E5
12.61:1 — foreground on background. Also the new-messages pill's plate against the dark thread, the same pairing read the other way round
11.24:1 — foreground on card
8.14:1 — foreground on member bubble
11.24:1 — foreground on card
8.14:1 — foreground on member bubble
--popover
#1F2833
11.24:1 — foreground on card
6.79:1 — confirm on card (the DERIVED value)
8.05:1 — waiting gold on card
6.79:1 — confirm on card (the DERIVED value)
8.05:1 — waiting gold on card
--popover-foreground
#DCE0E5
12.61:1 — foreground on background. Also the new-messages pill's plate against the dark thread, the same pairing read the other way round
11.24:1 — foreground on card
8.14:1 — foreground on member bubble
11.24:1 — foreground on card
8.14:1 — foreground on member bubble
--primary
#E38273
5.92:1 — ink on dusty coral (primary button text)
2.72:1 (must fail, does) — white on dusty coral must FAIL
6.14:1 — dusty coral UI mark on background (3.0 non-text)
2.72:1 (must fail, does) — white on dusty coral must FAIL
6.14:1 — dusty coral UI mark on background (3.0 non-text)
--primary-foreground
#18222B
5.92:1 — ink on dusty coral (primary button text)
6.68:1 — ink on coral-hover (primary button, hovered)
6.68:1 — ink on coral-hover (primary button, hovered)
--secondary
#2A3646
9.24:1 — foreground on secondary
9.24:1 — rail label on the active row (sidebarAccent)
1.06:1 (must fail, does) — the quiet disc and the quiet button have the same non-relationship with the dark field (1.06:1) — read by their glyph and their label, never by their edge
9.24:1 — rail label on the active row (sidebarAccent)
1.06:1 (must fail, does) — the quiet disc and the quiet button have the same non-relationship with the dark field (1.06:1) — read by their glyph and their label, never by their edge
--secondary-foreground
#DCE0E5
12.61:1 — foreground on background. Also the new-messages pill's plate against the dark thread, the same pairing read the other way round
11.24:1 — foreground on card
8.14:1 — foreground on member bubble
11.24:1 — foreground on card
8.14:1 — foreground on member bubble
--muted
#1F2833
11.24:1 — foreground on card
6.79:1 — confirm on card (the DERIVED value)
8.05:1 — waiting gold on card
6.79:1 — confirm on card (the DERIVED value)
8.05:1 — waiting gold on card
--muted-foreground
#93A0AD
6.27:1 — muted-foreground on background
6.59:1 — rail label at rest, muted on the rail ground
5.58:1 — status pill, muted on muted (waiting on a third party)
6.59:1 — rail label at rest, muted on the rail ground
5.58:1 — status pill, muted on muted (waiting on a third party)
--accent
#2A3646
9.24:1 — foreground on secondary
9.24:1 — rail label on the active row (sidebarAccent)
1.06:1 (must fail, does) — the quiet disc and the quiet button have the same non-relationship with the dark field (1.06:1) — read by their glyph and their label, never by their edge
9.24:1 — rail label on the active row (sidebarAccent)
1.06:1 (must fail, does) — the quiet disc and the quiet button have the same non-relationship with the dark field (1.06:1) — read by their glyph and their label, never by their edge
--accent-foreground
#DCE0E5
12.61:1 — foreground on background. Also the new-messages pill's plate against the dark thread, the same pairing read the other way round
11.24:1 — foreground on card
8.14:1 — foreground on member bubble
11.24:1 — foreground on card
8.14:1 — foreground on member bubble
--destructive
oklch(0.704 0.191 22.216)
--border
#2A3646
9.24:1 — foreground on secondary
9.24:1 — rail label on the active row (sidebarAccent)
1.06:1 (must fail, does) — the quiet disc and the quiet button have the same non-relationship with the dark field (1.06:1) — read by their glyph and their label, never by their edge
9.24:1 — rail label on the active row (sidebarAccent)
1.06:1 (must fail, does) — the quiet disc and the quiet button have the same non-relationship with the dark field (1.06:1) — read by their glyph and their label, never by their edge
--input
#2A3646
9.24:1 — foreground on secondary
9.24:1 — rail label on the active row (sidebarAccent)
1.06:1 (must fail, does) — the quiet disc and the quiet button have the same non-relationship with the dark field (1.06:1) — read by their glyph and their label, never by their edge
9.24:1 — rail label on the active row (sidebarAccent)
1.06:1 (must fail, does) — the quiet disc and the quiet button have the same non-relationship with the dark field (1.06:1) — read by their glyph and their label, never by their edge
--rule
rgba(147, 160, 173, 0.7)
--disabled-fill
#2A3646
9.24:1 — foreground on secondary
9.24:1 — rail label on the active row (sidebarAccent)
1.06:1 (must fail, does) — the quiet disc and the quiet button have the same non-relationship with the dark field (1.06:1) — read by their glyph and their label, never by their edge
9.24:1 — rail label on the active row (sidebarAccent)
1.06:1 (must fail, does) — the quiet disc and the quiet button have the same non-relationship with the dark field (1.06:1) — read by their glyph and their label, never by their edge
--on-disabled
#93A0AD
6.27:1 — muted-foreground on background
6.59:1 — rail label at rest, muted on the rail ground
5.58:1 — status pill, muted on muted (waiting on a third party)
6.59:1 — rail label at rest, muted on the rail ground
5.58:1 — status pill, muted on muted (waiting on a third party)
--ring
#E38273
5.92:1 — ink on dusty coral (primary button text)
2.72:1 (must fail, does) — white on dusty coral must FAIL
6.14:1 — dusty coral UI mark on background (3.0 non-text)
2.72:1 (must fail, does) — white on dusty coral must FAIL
6.14:1 — dusty coral UI mark on background (3.0 non-text)
--confirm
#8FB2DC
6.79:1 — confirm on card (the DERIVED value)
7.62:1 — confirm on background
4.92:1 — confirm on confirm-soft
7.62:1 — confirm on background
4.92:1 — confirm on confirm-soft
--confirm-soft
#2E3E58
4.92:1 — confirm on confirm-soft
8.14:1 — foreground on member bubble
8.14:1 — the thread, the member's own words on the member bubble
8.14:1 — foreground on member bubble
8.14:1 — the thread, the member's own words on the member bubble
--waiting
#D9BC6A
8.05:1 — waiting gold on card
9.04:1 — waiting gold on background
6.62:1 — waiting on waiting-soft
9.04:1 — waiting gold on background
6.62:1 — waiting on waiting-soft
--waiting-soft
#3A3524
6.62:1 — waiting on waiting-soft
--bubble-member
#2E3E58
4.92:1 — confirm on confirm-soft
8.14:1 — foreground on member bubble
8.14:1 — the thread, the member's own words on the member bubble
8.14:1 — foreground on member bubble
8.14:1 — the thread, the member's own words on the member bubble
--coral-deep
#FF9081
7.61:1 — coral-deep (coralOnDark) on background
6.30:1 — coral-deep on coral-soft wash
8.00:1 — the same AgentScreen live dot on the dark panel, dark coral-deep on groundAlt (3.0 non-text)
6.30:1 — coral-deep on coral-soft wash
8.00:1 — the same AgentScreen live dot on the dark panel, dark coral-deep on groundAlt (3.0 non-text)
--coral-soft
#3A282A
6.30:1 — coral-deep on coral-soft wash
--coral-hover
#E98F80
6.68:1 — ink on coral-hover (primary button, hovered)
2.41:1 (must fail, does) — white on coral-hover must FAIL
2.41:1 (must fail, does) — white on coral-hover must FAIL
--sidebar
#131926
6.59:1 — rail label at rest, muted on the rail ground
8.00:1 — the same AgentScreen live dot on the dark panel, dark coral-deep on groundAlt (3.0 non-text)
9.50:1 — the same handed-over border on the dark panel (3.0 non-text)
8.00:1 — the same AgentScreen live dot on the dark panel, dark coral-deep on groundAlt (3.0 non-text)
9.50:1 — the same handed-over border on the dark panel (3.0 non-text)
--sidebar-foreground
#DCE0E5
12.61:1 — foreground on background. Also the new-messages pill's plate against the dark thread, the same pairing read the other way round
11.24:1 — foreground on card
8.14:1 — foreground on member bubble
11.24:1 — foreground on card
8.14:1 — foreground on member bubble
--sidebar-primary
#E38273
5.92:1 — ink on dusty coral (primary button text)
2.72:1 (must fail, does) — white on dusty coral must FAIL
6.14:1 — dusty coral UI mark on background (3.0 non-text)
2.72:1 (must fail, does) — white on dusty coral must FAIL
6.14:1 — dusty coral UI mark on background (3.0 non-text)
--sidebar-primary-foreground
#18222B
5.92:1 — ink on dusty coral (primary button text)
6.68:1 — ink on coral-hover (primary button, hovered)
6.68:1 — ink on coral-hover (primary button, hovered)
--sidebar-accent
#2A3646
9.24:1 — foreground on secondary
9.24:1 — rail label on the active row (sidebarAccent)
1.06:1 (must fail, does) — the quiet disc and the quiet button have the same non-relationship with the dark field (1.06:1) — read by their glyph and their label, never by their edge
9.24:1 — rail label on the active row (sidebarAccent)
1.06:1 (must fail, does) — the quiet disc and the quiet button have the same non-relationship with the dark field (1.06:1) — read by their glyph and their label, never by their edge
--sidebar-accent-foreground
#DCE0E5
12.61:1 — foreground on background. Also the new-messages pill's plate against the dark thread, the same pairing read the other way round
11.24:1 — foreground on card
8.14:1 — foreground on member bubble
11.24:1 — foreground on card
8.14:1 — foreground on member bubble
--sidebar-border
#2A3646
9.24:1 — foreground on secondary
9.24:1 — rail label on the active row (sidebarAccent)
1.06:1 (must fail, does) — the quiet disc and the quiet button have the same non-relationship with the dark field (1.06:1) — read by their glyph and their label, never by their edge
9.24:1 — rail label on the active row (sidebarAccent)
1.06:1 (must fail, does) — the quiet disc and the quiet button have the same non-relationship with the dark field (1.06:1) — read by their glyph and their label, never by their edge
--sidebar-ring
#E38273
5.92:1 — ink on dusty coral (primary button text)
2.72:1 (must fail, does) — white on dusty coral must FAIL
6.14:1 — dusty coral UI mark on background (3.0 non-text)
2.72:1 (must fail, does) — white on dusty coral must FAIL
6.14:1 — dusty coral UI mark on background (3.0 non-text)
Every measured claim
| Pairing | Foreground | Background | Measured | Requirement |
|---|---|---|---|---|
| light: ink on coral (primary button text) | #18222B | #FF6B5A | 5.76:1 | ≥ 4.5 |
| light: white on coral must FAIL (that is why ink, never white) | #FFFFFF | #FF6B5A | 2.80:1 | < 3 (a deliberate fail) |
| light: coral-deep as text on white | #C63A28 | #FFFFFF | 5.20:1 | ≥ 4.5 |
| light: coral-deep as text on ground | #C63A28 | #F8FAFC | 4.97:1 | ≥ 4.5 |
| light: coral-deep on coral-soft wash | #C63A28 | #FFF2EF | 4.76:1 | ≥ 4.5 |
| light: confirm on ground | #3E5D86 | #F8FAFC | 6.44:1 | ≥ 4.5 |
| light: confirm on card | #3E5D86 | #FFFFFF | 6.74:1 | ≥ 4.5 |
| light: confirm on confirm-soft | #3E5D86 | #E8EEF7 | 5.78:1 | ≥ 4.5 |
| light: white on confirm (filled confirm control) | #FFFFFF | #3E5D86 | 6.74:1 | ≥ 4.5 |
| light: white on confirmDeep (RN pressed fill) | #FFFFFF | #34517A | 8.06:1 | ≥ 4.5 |
| light: waiting on ground | #A9560B | #F8FAFC | 4.99:1 | ≥ 4.5 |
| light: waiting on waiting-soft | #A9560B | #FBF1DE | 4.66:1 | ≥ 4.5 |
| light: foreground on background. Also the NEW-MESSAGES PILL's plate against the thread it floats over: ink on ground is the pill's fill read the other way round, and a floating object has to be findable against whatever scrolls under it, which is the argument for a filled pill rather than an outlined one | #18222B | #F8FAFC | 15.41:1 | ≥ 7 |
| light: muted-foreground on background | #4E5E6B | #F8FAFC | 6.40:1 | ≥ 4.5 |
| light: muted-foreground on muted | #4E5E6B | #F1F5F8 | 6.11:1 | ≥ 4.5 |
| light: foreground on secondary wash | #18222B | #EAF0F4 | 14.03:1 | ≥ 4.5 |
| light: foreground on member bubble | #18222B | #E8EEF7 | 13.82:1 | ≥ 4.5 |
| dark: ink on dusty coral (primary button text) | #18222B | #E38273 | 5.92:1 | ≥ 4.5 |
| dark: white on dusty coral must FAIL | #FFFFFF | #E38273 | 2.72:1 | < 3 (a deliberate fail) |
| dark: foreground on background. Also the new-messages pill's plate against the dark thread, the same pairing read the other way round | #DCE0E5 | #171E2A | 12.61:1 | ≥ 7 |
| dark: foreground on card | #DCE0E5 | #1F2833 | 11.24:1 | ≥ 7 |
| dark: muted-foreground on background | #93A0AD | #171E2A | 6.27:1 | ≥ 4.5 |
| dark: confirm on card (the DERIVED value) | #8FB2DC | #1F2833 | 6.79:1 | ≥ 4.5 |
| dark: confirm on background | #8FB2DC | #171E2A | 7.62:1 | ≥ 4.5 |
| dark: confirm on confirm-soft | #8FB2DC | #2E3E58 | 4.92:1 | ≥ 4.5 |
| dark: white on confirmDeep (RN filled confirm) | #FFFFFF | #3E5D86 | 6.74:1 | ≥ 4.5 |
| dark: waiting gold on card | #D9BC6A | #1F2833 | 8.05:1 | ≥ 4.5 |
| dark: waiting gold on background | #D9BC6A | #171E2A | 9.04:1 | ≥ 4.5 |
| dark: waiting on waiting-soft | #D9BC6A | #3A3524 | 6.62:1 | ≥ 4.5 |
| dark: coral-deep (coralOnDark) on background | #FF9081 | #171E2A | 7.61:1 | ≥ 4.5 |
| dark: coral-deep on coral-soft wash | #FF9081 | #3A282A | 6.30:1 | ≥ 4.5 |
| dark: foreground on member bubble | #DCE0E5 | #2E3E58 | 8.14:1 | ≥ 4.5 |
| dark: foreground on secondary | #DCE0E5 | #2A3646 | 9.24:1 | ≥ 4.5 |
| dark: dusty coral UI mark on background (3.0 non-text) | #E38273 | #171E2A | 6.14:1 | ≥ 3 |
| icon main: ink A on coral plate | #16211E | #FF6B5A | 5.91:1 | ≥ 4.5 |
| icon beta: dusty-coral A on dusk plate (3.0 graphical) | #E38273 | #171E2A | 6.14:1 | ≥ 3 |
| icon admin: ink A on feather-wash plate | #18222B | #EAF0F4 | 14.03:1 | ≥ 4.5 |
| icon admin: coral-deep tick on feather-wash (3.0 graphical) | #C63A28 | #EAF0F4 | 4.53:1 | ≥ 3 |
| light: rail label on the active row (sidebarAccent) | #18222B | #EAF0F4 | 14.03:1 | ≥ 4.5 |
| dark: rail label on the active row (sidebarAccent) | #DCE0E5 | #2A3646 | 9.24:1 | ≥ 4.5 |
| light: rail label at rest, muted on the rail ground | #4E5E6B | #F1F5F8 | 6.11:1 | ≥ 4.5 |
| dark: rail label at rest, muted on the rail ground | #93A0AD | #131926 | 6.59:1 | ≥ 4.5 |
| light: ink on coral-hover (primary button, hovered) | #18222B | #FF7A6B | 6.33:1 | ≥ 4.5 |
| light: white on coral-hover must FAIL (hover keeps ink type) | #FFFFFF | #FF7A6B | 2.55:1 | < 3 (a deliberate fail) |
| dark: ink on coral-hover (primary button, hovered) | #18222B | #E98F80 | 6.68:1 | ≥ 4.5 |
| dark: white on coral-hover must FAIL | #FFFFFF | #E98F80 | 2.41:1 | < 3 (a deliberate fail) |
| light: confirm focus ring on ground (3.0 non-text; the ring sits at 2px offset, on the page, never on the coral) | #3E5D86 | #F8FAFC | 6.44:1 | ≥ 3 |
| light: confirm focus ring on card (3.0 non-text) | #3E5D86 | #FFFFFF | 6.74:1 | ≥ 3 |
| dark: confirm focus ring on ground (3.0 non-text) | #8FB2DC | #171E2A | 7.62:1 | ≥ 3 |
| light: live-chip dot, confirm on the Feather chip ground (3.0 non-text) | #3E5D86 | #F8FAFC | 6.44:1 | ≥ 3 |
| light: status pill, muted on muted (waiting on a third party) | #4E5E6B | #F1F5F8 | 6.11:1 | ≥ 4.5 |
| dark: status pill, muted on muted (waiting on a third party) | #93A0AD | #1F2833 | 5.58:1 | ≥ 4.5 |
| light: tile label, confirm on card (the 11px uppercase eyebrow) | #3E5D86 | #FFFFFF | 6.74:1 | ≥ 4.5 |
| light: trust chip, muted on muted | #4E5E6B | #F1F5F8 | 6.11:1 | ≥ 4.5 |
| light: white on ink: the nav pill, the closing band, and `Open in Gmail` on a DraftCard, which is the ink fill and never coral because the thread spends its one coral on the composer's send disc (there is no Send: Airmond never sends from a member's mailbox) | #FFFFFF | #18222B | 16.12:1 | ≥ 7 |
| stage: ink on the off-the-record amber | #18222B | #E8A317 | 7.43:1 | ≥ 4.5 |
| stage: secondary caption on the amber (the stage ink at 0.75, resolving to #4C4226) | #4C4226 | #E8A317 | 4.58:1 | ≥ 4.5 |
| stage: dusk ink on the dusk ground (the dark scheme's own pair, asserted again because the stage reads it edge to edge, across a table) | #DCE0E5 | #171E2A | 12.61:1 | ≥ 7 |
| stage: secondary caption on the dusk (the dusk ink at 0.68, resolving to #9DA2A9 — the dusk opacity is unchanged; only the amber needed more ink) | #9DA2A9 | #171E2A | 6.51:1 | ≥ 4.5 |
| call: primary ink on the call ground — the dusk pair, read out of the dark scheme rather than repeated | #DCE0E5 | #171E2A | 12.61:1 | ≥ 7 |
| call: the End disc against the call ground (3.0 non-text: a control must be findable). It is stage.stopOnDusk, read from there so the two Ends cannot drift | #FF453A | #171E2A | 4.91:1 | ≥ 3 |
| call: the white End GLYPH on the End disc — a 24pt handset, so the bar is 3.0 and not 4.5 | #FFFFFF | #FF453A | 3.41:1 | ≥ 3 |
| call: white on the End disc must FAIL the 4.5 TEXT bar — the record of why the Stop button's word is ink while this glyph is white, and why the two rules are not in conflict | #FFFFFF | #FF453A | 3.41:1 | < 4.5 (a deliberate fail) |
| call: the quiet control wash CANNOT make a shape (ink at 0.18 composites to #3A414C, 1.63:1) — it never did on the retired black either (#2E2E2E, 1.55:1), and 0.30 reaches only 2.33:1. The disc is found by its outline, never by its fill | #3A414C | #171E2A | 1.63:1 | < 3 (a deliberate fail) |
| call: the control OUTLINE against the call ground (rule at control.card.borderWidth composites to #6E7986) — this is what makes an unarmed control a shape | #6E7986 | #171E2A | 3.78:1 | ≥ 3 |
| stage: ink on Stop, dusk (systemRed #FF453A kept, the LABEL changed — 17pt semibold is body text, so 4.5) | #18222B | #FF453A | 4.73:1 | ≥ 4.5 |
| stage: ink on Stop, off the record (systemRed #FF3B30) | #18222B | #FF3B30 | 4.55:1 | ≥ 4.5 |
| stage: white on Stop must FAIL, dusk (that is why the label is ink, never white — the same reason onCoral is ink) | #FFFFFF | #FF453A | 3.41:1 | < 4.5 (a deliberate fail) |
| stage: white on Stop must FAIL, off the record | #FFFFFF | #FF3B30 | 3.55:1 | < 4.5 (a deliberate fail) |
| stage: the Stop fill itself against the dusk ground (3.0 non-text: a control must be findable) | #FF453A | #171E2A | 4.91:1 | ≥ 3 |
| stage: the Stop fill CANNOT separate from the amber ground by luminance (measures 1.64:1) — so the button is identified by its ink LABEL, never by its edge. Recorded as a must-fail because no red that reads on dusk can also clear 3.0 on amber: the two windows are disjoint (>=3 on dusk needs L>=0.138, >=3 on amber needs L<=0.111) | #FF3B30 | #E8A317 | 1.64:1 | < 3 (a deliberate fail) |
| stage: the live dot on the dusk ground (3.0 non-text; there is no amber counterpart — the pill swaps to a pause glyph) | #E8574A | #171E2A | 4.69:1 | ≥ 3 |
| stage: kind chip, confirm blue on its own dusk wash (confirm at 0.18, resolving to #2D394A) | #8FB2DC | #2D394A | 5.33:1 | ≥ 4.5 |
| stage: kind chip, stage ink on its own amber wash (ink at 0.12, resolving to #CF9419) | #18222B | #CF9419 | 6.07:1 | ≥ 4.5 |
| stage: speaker 1 mark on the dusk ground (3.0 non-text) | #5CB8F0 | #171E2A | 7.62:1 | ≥ 3 |
| stage: speaker 1 mark on the amber ground must FAIL 3.0 — NO roster hue can be a legible mark on the amber, and this is arithmetic rather than a bad pick: clearing 3.0 on the dusk needs a luminance of at least 0.138 and clearing 3.0 on the amber needs at most 0.111, so the two windows do not overlap for ANY colour. Recorded as a must-fail so the file states the real relationship; off the record the chip is therefore identified by the NAME and the capsule outline, and speaking is signalled by weight and border, never by hue alone | #5CB8F0 | #E8A317 | 1.01:1 | < 3 (a deliberate fail) |
| stage: speaker 2 mark on the dusk ground (3.0 non-text) | #FAB55C | #171E2A | 9.42:1 | ≥ 3 |
| stage: speaker 2 mark on the amber ground must FAIL 3.0 — NO roster hue can be a legible mark on the amber, and this is arithmetic rather than a bad pick: clearing 3.0 on the dusk needs a luminance of at least 0.138 and clearing 3.0 on the amber needs at most 0.111, so the two windows do not overlap for ANY colour. Recorded as a must-fail so the file states the real relationship; off the record the chip is therefore identified by the NAME and the capsule outline, and speaking is signalled by weight and border, never by hue alone | #FAB55C | #E8A317 | 1.22:1 | < 3 (a deliberate fail) |
| stage: speaker 3 mark on the dusk ground (3.0 non-text) | #B899F5 | #171E2A | 7.10:1 | ≥ 3 |
| stage: speaker 3 mark on the amber ground must FAIL 3.0 — NO roster hue can be a legible mark on the amber, and this is arithmetic rather than a bad pick: clearing 3.0 on the dusk needs a luminance of at least 0.138 and clearing 3.0 on the amber needs at most 0.111, so the two windows do not overlap for ANY colour. Recorded as a must-fail so the file states the real relationship; off the record the chip is therefore identified by the NAME and the capsule outline, and speaking is signalled by weight and border, never by hue alone | #B899F5 | #E8A317 | 1.09:1 | < 3 (a deliberate fail) |
| stage: speaker 4 mark on the dusk ground (3.0 non-text) | #EC8DEC | #171E2A | 7.64:1 | ≥ 3 |
| stage: speaker 4 mark on the amber ground must FAIL 3.0 — NO roster hue can be a legible mark on the amber, and this is arithmetic rather than a bad pick: clearing 3.0 on the dusk needs a luminance of at least 0.138 and clearing 3.0 on the amber needs at most 0.111, so the two windows do not overlap for ANY colour. Recorded as a must-fail so the file states the real relationship; off the record the chip is therefore identified by the NAME and the capsule outline, and speaking is signalled by weight and border, never by hue alone | #EC8DEC | #E8A317 | 1.01:1 | < 3 (a deliberate fail) |
| stage: speaker 5 mark on the dusk ground (3.0 non-text) | #F58FAD | #171E2A | 7.50:1 | ≥ 3 |
| stage: speaker 5 mark on the amber ground must FAIL 3.0 — NO roster hue can be a legible mark on the amber, and this is arithmetic rather than a bad pick: clearing 3.0 on the dusk needs a luminance of at least 0.138 and clearing 3.0 on the amber needs at most 0.111, so the two windows do not overlap for ANY colour. Recorded as a must-fail so the file states the real relationship; off the record the chip is therefore identified by the NAME and the capsule outline, and speaking is signalled by weight and border, never by hue alone | #F58FAD | #E8A317 | 1.03:1 | < 3 (a deliberate fail) |
| light: the chat surface's quiet text, muted on the card and on the message-bar field — the card's subtitle line and the field's placeholder. This is the tone that REPLACED faint across the chat section: faint misses the body-text bar on this very surface (3.08:1, claimed below), so every placeholder, caption and timestamp here is muted instead | #4E5E6B | #FFFFFF | 6.69:1 | ≥ 4.5 |
| dark: the same quiet chat text on surfaceRaised, which IS the dark message bar's field — the dark field is raised off the card rather than flush with it, so this is a different measurement from the card pairing and has to be claimed on its own | #93A0AD | #273240 | 4.87:1 | ≥ 4.5 |
| dark: chat card titles and the typed message on the raised field, held to the same 7.0 bar as the light side | #DCE0E5 | #273240 | 9.80:1 | ≥ 7 |
| light: a refusal reason sits in the chat card's SUBTITLE slot, in the waiting amber — beside the field that caused it and never in a toast, so it has to hold as body text on the card rather than merely be findable. (The dark counterpart is the existing 'dark: waiting gold on card'.) | #A9560B | #FFFFFF | 5.22:1 | ≥ 4.5 |
| light: the AgentScreen's live dot is CORAL-DEEP, not coral (3.0 non-text) — full coral measures only 2.55:1 on that panel and misses the non-text bar, which is the same reason the admin app icon's tick is coral-deep rather than coral | #C63A28 | #F1F5F8 | 4.75:1 | ≥ 3 |
| dark: the same AgentScreen live dot on the dark panel, dark coral-deep on groundAlt (3.0 non-text) | #FF9081 | #131926 | 8.00:1 | ≥ 3 |
| light: faint must FAIL the body-text bar on the chat card and the message-bar field (3.08:1) — faint never carries a word on this surface, which is exactly why every placeholder, caption and timestamp in the chat section uses muted instead | #8595A2 | #FFFFFF | 3.08:1 | < 4.5 (a deliberate fail) |
| light: faint must FAIL even the NON-TEXT minimum on the AgentScreen panel (2.81:1), so it is not usable as a mark there either — the chat surface has no legitimate use for faint at all, and this claim is what says so if somebody reaches for it | #8595A2 | #F1F5F8 | 2.81:1 | < 3 (a deliberate fail) |
| light: the quiet disc (the + control) and the quiet button have essentially no plate contrast against the field (1.15:1), BY DESIGN — they are identified by their GLYPH and their label instead (ink on the quiet fill measures 14.03:1), which is why every icon in this section is a drawn SVG and never a text glyph | #EAF0F4 | #FFFFFF | 1.15:1 | < 3 (a deliberate fail) |
| dark: the quiet disc and the quiet button have the same non-relationship with the dark field (1.06:1) — read by their glyph and their label, never by their edge | #2A3646 | #273240 | 1.06:1 | < 3 (a deliberate fail) |
| dark: CredentialHandoff's required marker, dark coral-deep on the card — the one place the coral family appears on a card, and it marks a required FIELD rather than an action, so it is held to the body-text bar. (The light counterpart is the existing 'light: coral-deep as text on white'.) | #FF9081 | #1F2833 | 6.78:1 | ≥ 4.5 |
| light: AgentScreen handed over — the waiting amber as the panel's 2px BORDER (3.0 non-text). This is the only place on the chat surface where a panel changes its edge, because control moving from her to the member has to be unmistakable at a glance: amber is the system's waiting-on-you tone and she is blocked until it comes back | #A9560B | #F1F5F8 | 4.76:1 | ≥ 3 |
| dark: the same handed-over border on the dark panel (3.0 non-text) | #D9BC6A | #131926 | 9.50:1 | ≥ 3 |
| light: full coral as the AgentScreen live dot must FAIL the 3.0 non-text bar on the panel (2.55:1) — this is the claim that MAKES the coral-deep substitution safe: without it the page could go on printing the comparison while the value moved. The dot is coral-deep instead, claimed just above | #FF6B5A | #F1F5F8 | 2.55:1 | < 3 (a deliberate fail) |
| light: a ChoiceCard option title, ink on the recessed panel the option rows sit on — the option rows are the panel tone rather than the card, so this is its own pairing and it carries the member's actual choices, hence 7.0 | #18222B | #F1F5F8 | 14.71:1 | ≥ 7 |
| dark: the same ChoiceCard option title on the dark panel | #DCE0E5 | #131926 | 13.26:1 | ≥ 7 |
| light: a ChoiceCard option KEY (the lettered badge), muted on the quiet fill — the badge is how an option is referred to out loud (“go with B”), so it is text and held to 4.5 | #4E5E6B | #EAF0F4 | 5.82:1 | ≥ 4.5 |
| dark: the same ChoiceCard option key on the dark quiet fill — 4.59:1, the tightest pairing on the chat surface and the one to watch if either token moves | #93A0AD | #2A3646 | 4.59:1 | ≥ 4.5 |
| dark: the MessageBar recording waveform, confirm blue on the raised field (3.0 non-text). The waveform is confirm rather than coral on purpose: the armed send disc is the bar's one coral | #8FB2DC | #273240 | 5.92:1 | ≥ 3 |
| dark: the armed coral send disc's plate against the DARK field (3.0 non-text). Unlike the light scheme, this one clears — which is why the light claim is a must-fail and this one is not, and why the ink glyph has to carry the control in both | #E38273 | #273240 | 4.77:1 | ≥ 3 |
| dark: full dusty coral on the dark panel (3.0 non-text) — the dark half of the live-dot comparison. It clears on the dark panel, so only the light scheme forces the coral-deep substitution; the page prints both numbers side by side | #E38273 | #131926 | 6.45:1 | ≥ 3 |
| dark: the AgentScreen watching bar's live dot — dark coral-deep on the quiet fill (3.0 non-text). The bar is the one place the live mark sits on the quiet fill instead of on the panel, so it is its own pairing. (The light counterpart is the existing 'icon admin: coral-deep tick on feather-wash', the same two values.) | #FF9081 | #2A3646 | 5.57:1 | ≥ 3 |
| light: the thread, Ada's words on her bubble fill, and the new-messages pill's plate against a bubble scrolling under it (the same two values, read the other way round). The bubble is unbroken body text a member reads for minutes at a time, so the thread holds it to 7.0 rather than the 4.5 the palette page claims for the same tones elsewhere | #18222B | #F1F5F8 | 14.71:1 | ≥ 7 |
| dark: the thread, Ada's words on her bubble fill, and the pill's plate against a dark bubble under it | #DCE0E5 | #1F2833 | 11.24:1 | ≥ 7 |
| light: the thread, the member's own words on the member bubble, held to the same 7.0 as hers; the palette page claims this pair at 4.5 for a chip, and a bubble is not a chip | #18222B | #E8EEF7 | 13.82:1 | ≥ 7 |
| dark: the thread, the member's own words on the member bubble | #DCE0E5 | #2E3E58 | 8.14:1 | ≥ 7 |
| light: the thread's quiet tone, muted on the bubble fill. Every marker, list number, quote and footnote inside a bubble is this tone, because faint fails the same pairing (claimed below) | #4E5E6B | #F1F5F8 | 6.11:1 | ≥ 4.5 |
| dark: the thread's quiet tone, muted on the bubble fill | #93A0AD | #1F2833 | 5.58:1 | ≥ 4.5 |
| light: faint must FAIL the body-text bar on the thread's bubble fill (2.81:1). This is the correction the thread section exists to record: faint carries no marker, timestamp, caption or footnote anywhere on this surface, and muted carries all four | #8595A2 | #F1F5F8 | 2.81:1 | < 4.5 (a deliberate fail) |
| dark: faint must FAIL the body-text bar on the thread's bubble fill (3.35:1). It clears the 3.0 non-text bar in Low flame, which is exactly the trap: a tone that is legal as a mark in one scheme and illegal as a word in both | #6C7987 | #1F2833 | 3.35:1 | < 4.5 (a deliberate fail) |
| light: faint must FAIL even the NON-TEXT minimum on the thread ground (2.94:1), where the timestamp, the day break, the activity line and the rail glyphs all sit; so it is not usable as a mark out there either | #8595A2 | #F8FAFC | 2.94:1 | < 3 (a deliberate fail) |
| dark: faint must FAIL the body-text bar on the thread ground (3.76:1) | #6C7987 | #171E2A | 3.76:1 | < 4.5 (a deliberate fail) |
| light: every caption the thread has sits on the thread ground, not inside a bubble: muted there (6.40:1) carries the timestamp, the day break, the activity line and the rail glyphs | #4E5E6B | #F8FAFC | 6.40:1 | ≥ 4.5 |
| dark: the same captions on the dark thread ground | #93A0AD | #171E2A | 6.27:1 | ≥ 4.5 |
| dark: nothing quiet may go INSIDE the member's bubble; muted there measures 4.05:1 and must fail the body bar. This is why every caption in the thread sits on the ground instead, and the claim is what stops a timestamp being moved into his bubble because it looked tidier | #93A0AD | #2E3E58 | 4.05:1 | < 4.5 (a deliberate fail) |
| light: the unread divider's label, coral-deep on the thread ground (4.97:1). It is a word a member reads, so it takes the 4.5 body bar and not the 3.0 a mark would get | #C63A28 | #F8FAFC | 4.97:1 | ≥ 4.5 |
| dark: the unread divider's label, coral-deep on the thread ground (7.61:1) | #FF9081 | #171E2A | 7.61:1 | ≥ 4.5 |
| light: full coral as the unread label must FAIL (2.68:1). It misses the 4.5 text bar and the 3.0 non-text bar alike, which is the whole reason the label is coral-deep; without this claim the page could go on printing the comparison while the value moved | #FF6B5A | #F8FAFC | 2.68:1 | < 3 (a deliberate fail) |
| dark: full dusty coral CLEARS the body bar on the dark thread ground (6.14:1). Only Feather forces the coral-deep substitution, and Low flame follows it anyway because one role takes one token | #E38273 | #171E2A | 6.14:1 | ≥ 4.5 |
| light: a link inside a bubble, confirm on the bubble fill. Links are the working accent, never coral | #3E5D86 | #F1F5F8 | 6.15:1 | ≥ 4.5 |
| dark: a link inside a bubble, confirm on the bubble fill | #8FB2DC | #1F2833 | 6.79:1 | ≥ 4.5 |
| light: code in the thread, ink on the tinted plate, inline and fenced alike. The plate is now the `mark` tone at thread.mark.plateFillOpacity rather than the quiet fill, so that the plate and its edge come off ONE ink instead of two unrelated tokens | #18222B | #DAE0E4 | 12.10:1 | ≥ 4.5 |
| dark: code in the thread, ink on the tinted plate | #DCE0E5 | #2F3944 | 8.85:1 | ≥ 4.5 |
| light: the code plate's FILL has essentially no contrast against the bubble it sits in (1.22:1) and is not asked to. It is a TINT, not a boundary, and that is precisely why the plate's EDGE cannot be the exception to the 3.0 mark rule: with a fill this quiet, an edge under 3.0 would leave the plate drawn by nothing measurable at all | #DAE0E4 | #F1F5F8 | 1.22:1 | < 3 (a deliberate fail) |
| dark: the code plate's fill against the dark bubble fill (1.27:1), the same tint | #2F3944 | #1F2833 | 1.27:1 | < 3 (a deliberate fail) |
| light: the code plate's fill against the thread ground (1.22:1), for a bubble that is nothing but code | #E0E4E8 | #F8FAFC | 1.22:1 | < 3 (a deliberate fail) |
| dark: the code plate's fill against the dark thread ground (1.26:1) | #28303C | #171E2A | 1.26:1 | < 3 (a deliberate fail) |
| light: Ada's bubble does not separate from the thread ground by luminance (1.05:1) and is not asked to; the 1px hairline and the side it sits on are what make it a bubble. Recorded so nobody deepens the fill to fix a number that was never load-bearing | #F1F5F8 | #F8FAFC | 1.05:1 | < 3 (a deliberate fail) |
| dark: Ada's bubble against the dark thread ground (1.12:1), the same by design | #1F2833 | #171E2A | 1.12:1 | < 3 (a deliberate fail) |
| light: the member's bubble against the thread ground (1.11:1); one step further from the ground than hers, still not a boundary anything relies on | #E8EEF7 | #F8FAFC | 1.11:1 | < 3 (a deliberate fail) |
| dark: the member's bubble against the dark thread ground (1.55:1) | #2E3E58 | #171E2A | 1.55:1 | < 3 (a deliberate fail) |
| light: the unread divider's RULE cannot be what tells you. The hairline is the ink at 0.10, resolving to #E2E4E7 over the thread ground (1.22:1), so it is texture; the LABEL carries the meaning, which is why the label is held to the body bar above | #E2E4E7 | #F8FAFC | 1.22:1 | < 3 (a deliberate fail) |
| dark: the same unread rule in Low flame, the ink at 0.12 resolving to #2F3540 over the dark ground (1.36:1) | #2F3540 | #171E2A | 1.36:1 | < 3 (a deliberate fail) |
| rn light: coralDeep on the app's own ground, which is the pairing mb-airmond-app actually reads (lightColors.coralDeep on lightColors.ground, 4.97:1). Same two hexes as the web claim above and claimed again on purpose: the app mirrors the rn block and NOTHING else, so until 2026-09-14 this tone was not reachable from the app at all and the unread label shipped as full coral at 2.68:1 | #C63A28 | #F8FAFC | 4.97:1 | ≥ 4.5 |
| rn dark: coralDeep on the app's own dark ground (darkColors.coralDeep on darkColors.ground, 7.61:1). In Low flame the deep coral is LIGHTER than coral rather than darker: deep is relative to the ground it has to carry a word on | #FF9081 | #171E2A | 7.61:1 | ≥ 4.5 |
| light: the thread's SECTION RULE, the `mark` tone (muted at 0.7, resolving to #7F8B95) on Ada's bubble fill (3.18:1). Claimed on the BUBBLE and never on the page ground, because the ground is the context the kit's specimens live in and the bubble is the surface the product draws on | #7F8B95 | #F1F5F8 | 3.18:1 | ≥ 3 |
| dark: the thread's section rule on the dark bubble fill (3.50:1) | #707C88 | #1F2833 | 3.50:1 | ≥ 3 |
| light: the thread's QUOTE RULE, the same `mark` tone on the same fill. Claimed separately from the section rule although the pairing is identical: they are two components, and a tone that moved for one of them would have to be argued for both | #7F8B95 | #F1F5F8 | 3.18:1 | ≥ 3 |
| dark: the thread's quote rule on the dark bubble fill | #707C88 | #1F2833 | 3.50:1 | ≥ 3 |
| light: the CODE PLATE'S EDGE, held to the same 3.0 as the two rules rather than to the Mac's 0.5 (which measures 2.16:1 here). Decided explicitly: a plate may be read by its fill instead of its edge, but this fill measures 1.22:1, so the edge is the only measurable thing drawing the plate | #7F8B95 | #F1F5F8 | 3.18:1 | ≥ 3 |
| dark: the code plate's edge on the dark bubble fill | #707C88 | #1F2833 | 3.50:1 | ≥ 3 |
| light: `border` INSIDE A BUBBLE must FAIL the 3.0 mark bar (1.21:1), the ink at 0.10 resolves to #DBE0E4 on the bubble fill. This is the claim the whole correction hangs on: `border` is the hairline token for the PAGE GROUND, it clears 3.0 nowhere near a bubble, and so no thread mark may ever use it no matter what the page around it does | #DBE0E4 | #F1F5F8 | 1.21:1 | < 3 (a deliberate fail) |
| dark: `border` inside a dark bubble must FAIL the 3.0 mark bar (1.38:1), the same token, the same non-relationship, in the other scheme | #363E48 | #1F2833 | 1.38:1 | < 3 (a deliberate fail) |
| light: THE CARD'S HAIRLINE, the `rule` tone drawn on the card, measured against the page ground it separates the card from (3.20:1). The same tone and the same 3.0 bar as the thread's marks: one rule, one tone, every surface | #838E97 | #F8FAFC | 3.20:1 | ≥ 3 |
| dark: the card's hairline against the dark ground (3.92:1) | #707C88 | #171E2A | 3.92:1 | ≥ 3 |
| light: the card's FILL against the ground must FAIL (1.05:1), a shadow at 6% is all that separated a card from the page until 2026-09-14, on every card on every screen, which is a third of what a shape needs. This claim is why the hairline came back | #FFFFFF | #F8FAFC | 1.05:1 | < 3 (a deliberate fail) |
| dark: the card's fill against the dark ground (1.12:1), in Low flame the lift is tone rather than shadow, and it is still not a boundary | #1F2833 | #171E2A | 1.12:1 | < 3 (a deliberate fail) |
| light: `border` as the card's hairline must FAIL (1.16:1), the ink at 0.10 over a white card. This is the version that would have shipped if the card had simply reused the hairline token, and it is why the card's edge is the `rule` tone instead | #E8E9EA | #F8FAFC | 1.16:1 | < 3 (a deliberate fail) |
| dark: `border` as the card's hairline must FAIL (1.54:1) | #363E48 | #171E2A | 1.54:1 | < 3 (a deliberate fail) |
| light: THE SECONDARY CONTROL'S OUTLINE on the page ground (3.24:1). `secondary` was a near-invisible FILL at 24 call sites; it is an outline in the `rule` tone now, because a button a member cannot find is not a button | #818D97 | #F8FAFC | 3.24:1 | ≥ 3 |
| dark: the secondary control's outline on the dark ground (3.78:1) | #6E7986 | #171E2A | 3.78:1 | ≥ 3 |
| light: the same outline where the control sits ON A CARD rather than on the ground (3.34:1), a secondary button appears in both places and has to be findable in both | #838E97 | #FFFFFF | 3.34:1 | ≥ 3 |
| dark: the secondary control's outline on a dark card (3.50:1) | #707C88 | #1F2833 | 3.50:1 | ≥ 3 |
| light: the OLD secondary fill (`groundAlt`) against the page ground must FAIL (1.05:1), this is the measurement that retired the fill. The label carried the whole control and the plate carried nothing | #F1F5F8 | #F8FAFC | 1.05:1 | < 3 (a deliberate fail) |
| dark: the old secondary fill against the dark ground (1.05:1), identical, in the scheme where a fill was the only thing that could have worked | #131926 | #171E2A | 1.05:1 | < 3 (a deliberate fail) |
| light: the old secondary fill on a CARD must FAIL (1.10:1) | #F1F5F8 | #FFFFFF | 1.10:1 | < 3 (a deliberate fail) |
| dark: the old secondary fill on a dark card must FAIL (1.18:1) | #131926 | #1F2833 | 1.18:1 | < 3 (a deliberate fail) |
| light: A DISABLED CONTROL'S LABEL, `onDisabled` on `disabledFill` (5.82:1). A disabled control should look UNAVAILABLE, not ABSENT: the label is held to the full 4.5 body bar because the dim is exactly what hides the copy explaining what enabling it would cost | #4E5E6B | #EAF0F4 | 5.82:1 | ≥ 4.5 |
| dark: a disabled control's label, `onDisabled` on `disabledFill` (4.59:1), the tightest pairing in the token set and the one to watch if either value moves | #93A0AD | #2A3646 | 4.59:1 | ≥ 4.5 |
| light: the disabled PLATE against the ground must FAIL (1.10:1), which is why a disabled control keeps the same `rule` outline an enabled secondary has: the plate says unavailable and the outline says it is still a control | #EAF0F4 | #F8FAFC | 1.10:1 | < 3 (a deliberate fail) |
| dark: the disabled plate against the dark ground (1.37:1) | #2A3646 | #171E2A | 1.37:1 | < 3 (a deliberate fail) |
| light: THE OLD DISABLED RECIPE, `opacity: 0.5` on the whole group, must FAIL the body bar. On a secondary the ink label resolves to #888E94 and the plate to #F5F8FA, measuring 3.10:1: the dim halves the label and the fill together, so the control loses its words and its shape in one step | #888E94 | #F5F8FA | 3.10:1 | < 4.5 (a deliberate fail) |
| dark: the old disabled recipe on a dark secondary (4.25:1), it misses the bar in Low flame too, by less, which is exactly the kind of near-miss a single opacity produces and a token pair cannot | #7A7F88 | #151C28 | 4.25:1 | < 4.5 (a deliberate fail) |
| light: the old disabled recipe on a CORAL primary is the worst case (1.92:1): the ink label goes to #888E94 and the coral plate to #FCB3AB, and the label all but disappears into its own button | #888E94 | #FCB3AB | 1.92:1 | < 4.5 (a deliberate fail) |
| dark: the old disabled recipe on a dark coral primary (2.45:1) | #18202B | #7D504F | 2.45:1 | < 4.5 (a deliberate fail) |
| light: `faint` must FAIL the body bar on the quiet fill (2.68:1). faint is RETIRED from member-facing text: it carries provenance, dates and timestamps, which is the line that says where information came from, and it measured 2.64 to 3.08 in Feather on every ground the app has. Those readings become `muted` | #8595A2 | #EAF0F4 | 2.68:1 | < 4.5 (a deliberate fail) |
| light: `faint` on the member's own bubble is the worst light reading (2.64:1) | #8595A2 | #E8EEF7 | 2.64:1 | < 4.5 (a deliberate fail) |
| dark: `faint` must FAIL the body bar on the recessed ground (3.95:1), the best reading faint gets anywhere in Low flame, and it still misses | #6C7987 | #131926 | 3.95:1 | < 4.5 (a deliberate fail) |
| dark: `faint` on the raised surface (2.92:1), which is the dark message bar's own field | #6C7987 | #273240 | 2.92:1 | < 4.5 (a deliberate fail) |
| dark: `faint` on the quiet fill (2.75:1) | #6C7987 | #2A3646 | 2.75:1 | < 4.5 (a deliberate fail) |
| dark: `faint` on the member's own bubble is the worst reading in the whole set (2.43:1) | #6C7987 | #2E3E58 | 2.43:1 | < 4.5 (a deliberate fail) |
| light: THE DRAFTCARD'S EDGE, the `rule` tone on the card against the thread ground (3.20:1). A card in the thread is the first component drawn AFTER the mark rule was written down, so it takes the rule tone rather than `border` without anybody having to catch it in review | #838E97 | #F8FAFC | 3.20:1 | ≥ 3 |
| dark: the DraftCard's edge against the dark thread ground (3.92:1) | #707C88 | #171E2A | 3.92:1 | ≥ 3 |
| light: THE DRAFT CARD'S caption (To · Re:), muted on the card (6.69:1): the address IS the fact a member checks before opening | #4E5E6B | #FFFFFF | 6.69:1 | ≥ 4.5 |
| dark: the draft card's caption on the dark card (5.58:1) | #93A0AD | #1F2833 | 5.58:1 | ≥ 4.5 |
| light: `Open in Gmail`, the draft card's ONE primary, on-primary on the ink fill (15.41:1). Ink, never coral; and there is no Send, because Airmond never sends from a member's mailbox | #F8FAFC | #18222B | 15.41:1 | ≥ 7 |
| dark: `Open in Gmail` on the dark ink fill (12.61:1) | #171E2A | #DCE0E5 | 12.61:1 | ≥ 7 |
| light: `Read all`, confirm on the card (6.74:1): it opens the rest of her text in place, and links on this system are the working accent | #3E5D86 | #FFFFFF | 6.74:1 | ≥ 4.5 |
| dark: `Read all` on the dark card (6.79:1) | #8FB2DC | #1F2833 | 6.79:1 | ≥ 4.5 |
| light: `Change it`, the quiet control, muted on the card (6.69:1): a word with no plate, so the text bar | #4E5E6B | #FFFFFF | 6.69:1 | ≥ 4.5 |
| light: the REPLACED record's strip label, muted on groundAlt (6.11:1). The record reads lighter than the live card below it and still clears the text bar | #4E5E6B | #F1F5F8 | 6.11:1 | ≥ 4.5 |
| dark: the replaced record's strip label on the dark groundAlt (6.59:1) | #93A0AD | #131926 | 6.59:1 | ≥ 4.5 |
| light: the replaced record's strip against the card must FAIL 3.0 (1.10:1): it is found by its words and its arrow, never by its plate | #F1F5F8 | #FFFFFF | 1.10:1 | < 3 (a deliberate fail) |
| light: the pen on the draft card's head tile, muted on groundAlt (3.0 non-text; 6.11:1) | #4E5E6B | #F1F5F8 | 6.11:1 | ≥ 3 |
| dark: the pen on the dark head tile (6.59:1) | #93A0AD | #131926 | 6.59:1 | ≥ 3 |
| light: THE NEW-MESSAGES PILL, the ground colour on the ink fill (15.41:1). Ink and not confirm, which would mean confirmed and succeeded and live about messages nobody has read; ink and not coral, which the thread has already spent | #F8FAFC | #18222B | 15.41:1 | ≥ 4.5 |
| dark: the new-messages pill's label on its ink fill (12.61:1) | #171E2A | #DCE0E5 | 12.61:1 | ≥ 4.5 |
| light: THE MARK TONE ON THE MEMBER'S OWN BUBBLE scrapes over the bar at 3.07:1, by 0.07. Claimed at 3.0 so the margin is on the record and the next token move cannot quietly spend it. Low flame is what actually decides the rule: see the must-fail below | #7C8995 | #E8EEF7 | 3.07:1 | ≥ 3 |
| dark: the mark tone on the member's own bubble MISSES the bar at 2.79:1, and it is the one surface in the system that does. 0.21 under the bar the whole pass is named after, and no specimen drew it, which is why the guard is in code rather than in a sentence. Recorded as a must-fail rather than fixed by raising the opacity: 0.8 would clear it at 3.15:1 and would also take the card's hairline to 3.98:1 and 4.63:1 against the ground, which is the wireframe the 2026-09-02 ruling removed. His bubble holds his words and nothing else instead, the same rule that already keeps every caption out of it, applied in BOTH schemes because one role takes one answer | #758394 | #2E3E58 | 2.79:1 | < 3 (a deliberate fail) |
| light: A DISABLED CONTROL'S OUTLINE against the ground (3.38:1). The section calls this outline not optional, because the disabled plate alone measures 1.10:1: the plate says unavailable and the outline says it is still a control. It was the one load-bearing mark in that argument with no claim behind it | #7D8A94 | #F8FAFC | 3.38:1 | ≥ 3 |
| dark: a disabled control's outline against the dark ground (4.16:1) | #74808E | #171E2A | 4.16:1 | ≥ 3 |
| light: the mark tone on the QUIET FILL (3.08:1), which is the tightest surface it clears anywhere: a mark drawn on a status pill, a hover mark or a disabled plate. Claimed because the margin is 0.08 and the next token move is what will spend it | #7D8A94 | #EAF0F4 | 3.08:1 | ≥ 3 |
| dark: the mark tone on the dark quiet fill (3.05:1), tighter still | #74808E | #2A3646 | 3.05:1 | ≥ 3 |
| light: ink on a white card, the pairing every card title and every field value on the DraftCard rests on (16.12:1). It was drawn on the guide and measured there without ever being claimed, which is the kind of gap that only shows up when somebody counts | #18222B | #FFFFFF | 16.12:1 | ≥ 7 |
| light: CHAT DENSITY (2026-09-24), the sidebar hero's name, ink on the rail ground (14.71:1) | #18222B | #F1F5F8 | 14.71:1 | ≥ 7 |
| dark: the sidebar hero's name on the dark rail ground (13.26:1) | #DCE0E5 | #131926 | 13.26:1 | ≥ 7 |
| light: the hero's Call / Message / Record captions at 12/15, ink on the rail ground (14.71:1). A word under a disc, so the text bar | #18222B | #F1F5F8 | 14.71:1 | ≥ 4.5 |
| dark: the hero's captions on the dark rail ground (13.26:1) | #DCE0E5 | #131926 | 13.26:1 | ≥ 4.5 |
| light: a sidebar row's 14px label at rest, muted on the rail ground (6.11:1): the compact row came down a size and kept the tone | #4E5E6B | #F1F5F8 | 6.11:1 | ≥ 4.5 |
| dark: a sidebar row's 14px label at rest on the dark rail ground (6.59:1) | #93A0AD | #131926 | 6.59:1 | ≥ 4.5 |
| light: the Message and Record glyphs, ink on the surface disc (3.0 non-text; 16.12:1) | #18222B | #FFFFFF | 16.12:1 | ≥ 3 |
| dark: the Message and Record glyphs on the dark surface disc (11.24:1) | #DCE0E5 | #1F2833 | 11.24:1 | ≥ 3 |
| light: the surface disc against the rail ground must FAIL 3.0 (1.10:1). The disc is found by its glyph and its caption, never by its plate, which is the hero's native design and is recorded so nobody credits the plate | #FFFFFF | #F1F5F8 | 1.10:1 | < 3 (a deliberate fail) |
| dark: the surface disc against the dark rail ground must FAIL 3.0 (1.18:1) | #1F2833 | #131926 | 1.18:1 | < 3 (a deliberate fail) |
| light: the coral Call disc against the rail ground must FAIL 3.0 (2.55:1). The disc is found by its ink glyph (5.76:1, claimed as ink on coral) and its caption; the plate is identity, not a boundary | #FF6B5A | #F1F5F8 | 2.55:1 | < 3 (a deliberate fail) |
| dark: the dusty coral Call disc against the dark rail ground clears 3.0 (6.45:1) | #E38273 | #131926 | 6.45:1 | ≥ 3 |
| light: the 44 chat header's name at 14/600, ink on the header band (surface; 16.12:1) | #18222B | #FFFFFF | 16.12:1 | ≥ 7 |
| dark: the chat header's name on the dark band (11.24:1) | #DCE0E5 | #1F2833 | 11.24:1 | ≥ 7 |
| light: the 42 composer's 14px placeholder, muted on the field (groundAlt; 6.11:1). The size came down a step and the bar did not move | #4E5E6B | #F1F5F8 | 6.11:1 | ≥ 4.5 |
| dark: the composer's placeholder on the dark field (groundAlt; 6.59:1) | #93A0AD | #131926 | 6.59:1 | ≥ 4.5 |
| light: the web thread's 14/20 message text, ink on HER bubble (the muted wash; 14.71:1). Smaller type keeps the 7.0 bar the 17/26 thread was held to | #18222B | #F1F5F8 | 14.71:1 | ≥ 7 |
| dark: the web thread's 14/20 message text on her dark bubble (11.24:1) | #DCE0E5 | #1F2833 | 11.24:1 | ≥ 7 |
| light: LongMessage's Show more / Show less, the body's ink at 600 on HIS bubble (memberBubble; 13.82:1). The control is his bubble's ink, never muted and never onCoral | #18222B | #E8EEF7 | 13.82:1 | ≥ 4.5 |
| dark: LongMessage's control, ink on his dark bubble (8.14:1) | #DCE0E5 | #2E3E58 | 8.14:1 | ≥ 4.5 |
| light: a FINISHED action card's detail lines, muted on the card (surface; 6.69:1) | #4E5E6B | #FFFFFF | 6.69:1 | ≥ 4.5 |
| light: a finished card's report, muted on the card's inset (groundAlt; 6.11:1) | #4E5E6B | #F1F5F8 | 6.11:1 | ≥ 4.5 |
| dark: a finished card's detail lines, muted on the dark card (surface; 5.58:1) | #93A0AD | #1F2833 | 5.58:1 | ≥ 4.5 |
| dark: a finished card's report, muted on the dark inset (surfaceRaised; 4.87:1). The tightest surface the finished rule draws on, and it clears | #93A0AD | #273240 | 4.87:1 | ≥ 4.5 |
| light: an action card's speaker label, confirm on the inset (6.15:1). Labels keep their own tone when the card finishes | #3E5D86 | #F1F5F8 | 6.15:1 | ≥ 4.5 |
| dark: an action card's speaker label, confirm on the dark inset (surfaceRaised; 5.92:1) | #8FB2DC | #273240 | 5.92:1 | ≥ 4.5 |
| dark: muted on the call's blue bubble (confirmSoft) must FAIL 4.5 (4.05:1). This is why a finished card's quiet lines stay ON the card and never move out onto the bubble | #93A0AD | #2E3E58 | 4.05:1 | < 4.5 (a deliberate fail) |
| meeting tile: ink on a dusk card, which is also the ground's lightest point (the radial's centre is dark.card), so it covers the title and every card's text | #DCE0E5 | #1F2833 | 11.24:1 | ≥ 4.5 |
| meeting tile: muted on a dusk card and on the ground's lightest point: the subtitle, kind labels, meta rows, struck words, and the note icon (3.0 would do for the icon) | #93A0AD | #1F2833 | 5.58:1 | ≥ 4.5 |
| meeting tile: muted on the raised fill (dark.secondary): the detail half of the status pill. The thinnest pass on the tile (4.59:1); a darker pill would fail it | #93A0AD | #2A3646 | 4.59:1 | ≥ 4.5 |
| meeting tile: ink on the raised fill: the owner pill's name and the status pill's label | #DCE0E5 | #2A3646 | 9.24:1 | ≥ 4.5 |
| meeting tile: the Edited tag, waiting amber on waiting-soft | #D9BC6A | #3A3524 | 6.62:1 | ≥ 4.5 |
| meeting tile: waiting amber on a dusk card: the due date as text, and the knowledge-update and confirmation-pin icons | #D9BC6A | #1F2833 | 8.05:1 | ≥ 4.5 |
| meeting tile: the Reading aloud tag, coral-deep on the coral wash (rn.dark.coralWash) composited over the card | #FF9081 | #463A40 | 4.93:1 | ≥ 4.5 |
| meeting tile: confirm blue on a dusk card and on the ground's lightest point: the line under a confirmed member, and the answer and summary icons | #8FB2DC | #1F2833 | 6.79:1 | ≥ 4.5 |
| meeting tile: coral-deep on a dusk card (3.0 non-text): the action icon (coral is reserved for the one kind that asks someone to act), and the live dot on the ground's lightest point. Never set as text on the tile except inside its own wash | #FF9081 | #1F2833 | 6.78:1 | ≥ 3 |
| meeting tile: the confirmed badge (confirm blue) against the dusk ground (3.0 non-text) | #8FB2DC | #171E2A | 7.62:1 | ≥ 3 |
| meeting tile: the ground-coloured check on the confirmed badge (3.0 non-text glyph) | #171E2A | #8FB2DC | 7.62:1 | ≥ 3 |
| meeting tile: ink initials on speaker hue 1 | #18222B | #5CB8F0 | 7.35:1 | ≥ 4.5 |
| meeting tile: ink initials on speaker hue 2 | #18222B | #FAB55C | 9.08:1 | ≥ 4.5 |
| meeting tile: ink initials on speaker hue 3 | #18222B | #B899F5 | 6.84:1 | ≥ 4.5 |
| meeting tile: ink initials on speaker hue 4 | #18222B | #EC8DEC | 7.36:1 | ≥ 4.5 |
| meeting tile: ink initials on speaker hue 5 | #18222B | #F58FAD | 7.23:1 | ≥ 4.5 |
| meeting tile: the Removed tag, rn.dark.danger on its own wash at 0.16 composited over the card (13 px type, so 4.5). The mockup's 0.18 measured 4.40:1 and missed the bar; 0.16 is the highest wash that clears it (decided 2026-10-01) | #F2857C | #41373F | 4.57:1 | ≥ 4.5 |
| meeting tile: RECORDED, NOT DECIDED. The card's 12% hairline (rn.dark.border over the card) does not clear the 3.0 mark bar (1.38:1), and the card's fill does not separate from the ground either (1.12:1, the next claim). The approved card is found by its text and its kind icon, which clear 4.5 and 3.0; whether a feed card on a video tile is a mark the mark rule covers is a question for the next pass, not this one | #363E48 | #1F2833 | 1.38:1 | < 3 (a deliberate fail) |
| meeting tile: the dusk card's fill against the dusk ground does not separate by luminance (1.12:1) and is not asked to; recorded so nobody darkens the ground to fix a number that was never load-bearing | #1F2833 | #171E2A | 1.12:1 | < 3 (a deliberate fail) |
| meeting tile: the confirmation pin's amber hairline (waiting at 0.28 over the card) is a tint, not a boundary (1.86:1); the pin is found by its amber question icon and its 18 px title | #535142 | #1F2833 | 1.86:1 | < 3 (a deliberate fail) |
| meeting tile: the portrait's resting ring (the dusk ink at stage.duskHairlineOpacity over the ground) frames the photo and is not a mark (2.33:1); the face is what identifies her | #525862 | #171E2A | 2.33:1 | < 3 (a deliberate fail) |