Sanctuary keeps two promises in every flavor and with every accent: text and accent colors are legible against the stone they sit on, and motion stops when the visitor asks for less. The core’s tests check both on every build, and this page computes them again from the published palette.
Contrast
WCAG 2 asks for a contrast ratio of at least 4.5:1 for normal text (level AA) and 3:1 for focus indicators. For each pairing below, the table shows the lowest ratio across every pigment and every stone it covers, and the pair that gives it. <p> stands for any pigment, and the stones run from surface-sunken to surface-raised-4.
| Pairing | Minimum | Lauds | Vespers | Compline | Matins |
|---|---|---|---|---|---|
| text, text-muted and text-subtle on every stone | 4.50:1 | 4.83:1text-subtle on surface-sunken | 4.51:1text-subtle on surface-raised-4 | 4.60:1text-subtle on surface-raised-4 | 4.64:1text-subtle on surface-raised-4 |
| glass-<p> on every stone but surface-sunken | 4.50:1 | 4.51:1glass-verdure on surface | 6.19:1glass-murrey on surface-raised-4 | 6.75:1glass-murrey on surface-raised-4 | 5.87:1glass-murrey on surface-raised-4 |
| glass-<p>-ink on every stone | 4.50:1 | 6.14:1glass-verdure-ink on surface-sunken | 8.30:1glass-murrey-ink on surface-raised-4 | 9.05:1glass-murrey-ink on surface-raised-4 | 8.29:1glass-murrey-ink on surface-raised-4 |
| glass-<p>-ink on its pane | 4.50:1 | 6.51:1glass-verdure-ink on glass-verdure-pane | 8.22:1glass-verdure-ink on glass-verdure-pane | 8.22:1glass-verdure-ink on glass-verdure-pane | 8.14:1glass-murrey-ink on glass-murrey-pane |
| glass-<p>-on on its glass | 4.50:1 | 4.77:1glass-verdure-on on glass-verdure | 9.57:1glass-murrey-on on glass-murrey | 9.57:1glass-murrey-on on glass-murrey | 6.78:1glass-murrey-on on glass-murrey |
| glass-<p>-on-pane on its pane | 4.50:1 | 9.57:1glass-verdure-on-pane on glass-verdure-pane | 9.57:1glass-verdure-on-pane on glass-verdure-pane | 9.57:1glass-verdure-on-pane on glass-verdure-pane | 10.80:1glass-amber-on-pane on glass-amber-pane |
| The focus halo: glass-<p> against surface | 3.00:1 | 4.51:1glass-verdure on surface | 9.21:1glass-murrey on surface | 9.66:1glass-murrey on surface | 7.42:1glass-murrey on surface |
Each pigment’s ramp fixes the lightness of every tone across hues, which is why swapping the accent never breaks these ratios.
What the guarantees do not cover
lumeis light, not text.glass-<p>-lumeandaccent-lumehave no text guarantee. Use them for glows, hover and gradients, never for words.- Glass on sunken stone. On
surface-sunken(inputs, wells), accent text usesink, not the glass itself. - Disabled text.
text-disabledis deliberately faint. WCAG exempts inactive controls, but never put content a visitor needs in it. - Your own colors. Colors mixed outside the tokens, text over images, and the named windows as backgrounds are not checked. Test what you build.
- Color alone. Contrast makes color legible, not meaningful: a state shown only by color still needs a label, an icon or a shape.
Focus
--san-halo draws the focus ring: a band of stone, then a ring of the accent. The accent clears 3:1 against surface in every flavor (the last row above). Use it on :focus-visible, so a ring appears for keyboard visitors without flashing on every click:
.button:focus-visible {
outline: none;
box-shadow: var(--san-halo);
}
Reduced motion
When the visitor asks for reduced motion (prefers-reduced-motion: reduce), the stylesheet sets these tokens, read from it at build time:
--san-duration-instant:0ms--san-duration-fast:0ms--san-duration-base:0ms--san-duration-slow:0ms--san-duration-slower:0ms--san-duration-procession:0ms
Anything timed with the duration tokens then changes instantly. Animations and durations written without the tokens are not covered: time them with the tokens, or stop them yourself under the same media query. See the motion foundations for the details.