opsinjs

Tokens

Every design token opsinjs defines, what it controls, and which parts of the system consume it.

How this is generated

Source: tokens/color.json, tokens/material.json, tokens/motion.json, tokens/type.json, tokens/space.json, tokens/shape.json. Script: scripts/build-tokens.mts, which also writes lib/generated/tokens.ts and app/tokens.generated.css. Command: pnpm run generate.

Three columns, and the third is the one that matters. Token is the name you write. What it controls is the single property or decision it owns. If a token controls two unrelated things, that is a bug in the token, not a longer sentence in this column. Used by lists the components and foundations that read it, which is how you find out whether changing a value is a local adjustment or a system event.

Tier is shown for every row. Primitive tokens are raw values and are listed for completeness only; a component that reads one has broken the rule described in Token architecture. Semantic and component tiers are the ones you are meant to use.

What is deliberately excluded. The documentation site's own theme variables are not opsinjs tokens and are not listed, and that covers everything lyra, shadcn and fumadocs define for the chrome you are looking at. They are not part of the public surface, they carry no semver promise, and confusing the two is the most common way a consumer ends up styling their product with our sidebar's colours.

If you want to change a value rather than read one, you want Theming. If you want to know what a value means, you want Foundations. To change a row here, edit the JSON source; this page cannot be edited.

Tokens

color

neutral

TokenTierWhat it controlsLightDarkUsed by
--opsin-neutral-0primitiveNeutral ramp, step 0.oklch(1 0 0)sameno component
--opsin-neutral-50primitiveNeutral ramp, step 50.oklch(0.985 0.002 250)sameno component
--opsin-neutral-100primitiveNeutral ramp, step 100.oklch(0.967 0.003 250)sameno component
--opsin-neutral-200primitiveNeutral ramp, step 200.oklch(0.929 0.004 250)sameno component
--opsin-neutral-300primitiveNeutral ramp, step 300.oklch(0.871 0.005 250)sameno component
--opsin-neutral-400primitiveNeutral ramp, step 400.oklch(0.708 0.008 250)sameno component
--opsin-neutral-500primitiveNeutral ramp, step 500.oklch(0.556 0.009 250)sameno component
--opsin-neutral-600primitiveNeutral ramp, step 600.oklch(0.439 0.009 250)sameno component
--opsin-neutral-700primitiveNeutral ramp, step 700.oklch(0.371 0.008 250)sameno component
--opsin-neutral-800primitiveNeutral ramp, step 800.oklch(0.269 0.007 250)sameno component
--opsin-neutral-900primitiveNeutral ramp, step 900.oklch(0.205 0.006 250)sameno component
--opsin-neutral-950primitiveNeutral ramp, step 950.oklch(0.145 0.005 250)sameno component
--opsin-neutral-1000primitiveNeutral ramp, step 1000.oklch(0 0 0)sameno component

chrome

TokenTierWhat it controlsLightDarkUsed by
--opsin-chrome-backgroundsemanticChrome role background, resolved to the ladder step it names.oklch(0.985 0.002 250)oklch(0.145 0.005 250)no component
--opsin-chrome-foregroundsemanticChrome role foreground, resolved to the ladder step it names.oklch(0.205 0.006 250)oklch(0.967 0.003 250)no component
--opsin-chrome-cardsemanticChrome role card, resolved to the ladder step it names.oklch(1 0 0)oklch(0.205 0.006 250)no component
--opsin-chrome-card-foregroundsemanticChrome role cardForeground, resolved to the ladder step it names.oklch(0.205 0.006 250)oklch(0.967 0.003 250)no component
--opsin-chrome-mutedsemanticChrome role muted, resolved to the ladder step it names.oklch(0.967 0.003 250)oklch(0.269 0.007 250)no component
--opsin-chrome-muted-foregroundsemanticChrome role mutedForeground, resolved to the ladder step it names.oklch(0.439 0.009 250)oklch(0.871 0.005 250)no component
--opsin-chrome-bordersemanticChrome role border, resolved to the ladder step it names.oklch(0.556 0.009 250)oklch(0.556 0.009 250)no component
--opsin-chrome-inputsemanticChrome role input, resolved to the ladder step it names.oklch(0.556 0.009 250)oklch(0.556 0.009 250)no component
--opsin-chrome-ringsemanticChrome role ring, resolved to the ladder step it names.oklch(0.55 0.13 250)oklch(0.68 0.115 250)no component
--opsin-chrome-primarysemanticChrome role primary, resolved to the ladder step it names.oklch(0.51 0.135 250)oklch(0.72 0.12 250)no component
--opsin-chrome-primary-foregroundsemanticChrome role primaryForeground, resolved to the ladder step it names.oklch(0.99 0 0)oklch(0.16 0.01 260)no component

category

TokenTierWhat it controlsLightDarkUsed by
--opsin-category-sleep-50primitiveSleep ramp, step 50.oklch(0.972 0.013 275)sameno component
--opsin-category-sleep-100primitiveSleep ramp, step 100.oklch(0.941 0.028 275)sameno component
--opsin-category-sleep-200primitiveSleep ramp, step 200.oklch(0.884 0.057 275)sameno component
--opsin-category-sleep-300primitiveSleep ramp, step 300.oklch(0.806 0.092 275)sameno component
--opsin-category-sleep-400primitiveSleep ramp, step 400.oklch(0.714 0.123 275)sameno component
--opsin-category-sleep-500primitiveSleep ramp, step 500.oklch(0.622 0.14 275)sameno component
--opsin-category-sleep-600primitiveSleep ramp, step 600.oklch(0.541 0.136 275)sameno component
--opsin-category-sleep-700primitiveSleep ramp, step 700.oklch(0.452 0.123 275)sameno component
--opsin-category-sleep-800primitiveSleep ramp, step 800.oklch(0.362 0.104 275)sameno component
--opsin-category-sleep-900primitiveSleep ramp, step 900.oklch(0.276 0.081 275)sameno component
--opsin-category-sleep-950primitiveSleep ramp, step 950.oklch(0.208 0.062 275)sameno component
--opsin-category-sleep-surfacesemanticThe tinted background a component in this ramp sits on.oklch(0.972 0.013 275)oklch(0.208 0.062 275)no component
--opsin-category-sleep-linesemanticThe boundary, icon stroke or chart mark. The lightest value in the ramp that clears the non-text floor against surface.oklch(0.541 0.136 275)oklch(0.806 0.092 275)trend-sparkline
--opsin-category-sleep-inksemanticText and text-sized icons on surface. Clears the text floor against surface.oklch(0.362 0.104 275)oklch(0.884 0.057 275)metric-tile, range-bar, result-card, score-dial
--opsin-category-sleep-accentsemanticThe identity fill: a bar fill, a dial track, a legend dot. Chosen for recognition, not for contrast. It must be bounded by line or labelled in ink; it is never the only thing that carries the meaning.oklch(0.58 0.14 275)oklch(0.714 0.123 275)log-sheet
--opsin-category-heart-50primitiveHeart ramp, step 50.oklch(0.972 0.014 15)sameno component
--opsin-category-heart-100primitiveHeart ramp, step 100.oklch(0.941 0.03 15)sameno component
--opsin-category-heart-200primitiveHeart ramp, step 200.oklch(0.884 0.062 15)sameno component
--opsin-category-heart-300primitiveHeart ramp, step 300.oklch(0.806 0.112 15)sameno component
--opsin-category-heart-400primitiveHeart ramp, step 400.oklch(0.714 0.15 15)sameno component
--opsin-category-heart-500primitiveHeart ramp, step 500.oklch(0.622 0.17 15)sameno component
--opsin-category-heart-600primitiveHeart ramp, step 600.oklch(0.541 0.165 15)sameno component
--opsin-category-heart-700primitiveHeart ramp, step 700.oklch(0.452 0.15 15)sameno component
--opsin-category-heart-800primitiveHeart ramp, step 800.oklch(0.362 0.126 15)sameno component
--opsin-category-heart-900primitiveHeart ramp, step 900.oklch(0.276 0.099 15)sameno component
--opsin-category-heart-950primitiveHeart ramp, step 950.oklch(0.208 0.075 15)sameno component
--opsin-category-heart-surfacesemanticThe tinted background a component in this ramp sits on.oklch(0.972 0.014 15)oklch(0.208 0.075 15)no component
--opsin-category-heart-linesemanticThe boundary, icon stroke or chart mark. The lightest value in the ramp that clears the non-text floor against surface.oklch(0.541 0.165 15)oklch(0.806 0.112 15)trend-sparkline
--opsin-category-heart-inksemanticText and text-sized icons on surface. Clears the text floor against surface.oklch(0.362 0.126 15)oklch(0.884 0.062 15)metric-tile, range-bar, result-card, score-dial
--opsin-category-heart-accentsemanticThe identity fill: a bar fill, a dial track, a legend dot. Chosen for recognition, not for contrast. It must be bounded by line or labelled in ink; it is never the only thing that carries the meaning.oklch(0.62 0.17 15)oklch(0.714 0.15 15)log-sheet
--opsin-category-activity-50primitiveActivity ramp, step 50.oklch(0.972 0.022 140)sameno component
--opsin-category-activity-100primitiveActivity ramp, step 100.oklch(0.941 0.038 140)sameno component
--opsin-category-activity-200primitiveActivity ramp, step 200.oklch(0.884 0.067 140)sameno component
--opsin-category-activity-300primitiveActivity ramp, step 300.oklch(0.806 0.106 140)sameno component
--opsin-category-activity-400primitiveActivity ramp, step 400.oklch(0.714 0.141 140)sameno component
--opsin-category-activity-500primitiveActivity ramp, step 500.oklch(0.622 0.16 140)sameno component
--opsin-category-activity-600primitiveActivity ramp, step 600.oklch(0.541 0.155 140)sameno component
--opsin-category-activity-700primitiveActivity ramp, step 700.oklch(0.452 0.141 140)sameno component
--opsin-category-activity-800primitiveActivity ramp, step 800.oklch(0.362 0.118 140)sameno component
--opsin-category-activity-900primitiveActivity ramp, step 900.oklch(0.276 0.092 140)sameno component
--opsin-category-activity-950primitiveActivity ramp, step 950.oklch(0.208 0.07 140)sameno component
--opsin-category-activity-surfacesemanticThe tinted background a component in this ramp sits on.oklch(0.972 0.022 140)oklch(0.208 0.07 140)no component
--opsin-category-activity-linesemanticThe boundary, icon stroke or chart mark. The lightest value in the ramp that clears the non-text floor against surface.oklch(0.541 0.155 140)oklch(0.806 0.106 140)trend-sparkline
--opsin-category-activity-inksemanticText and text-sized icons on surface. Clears the text floor against surface.oklch(0.362 0.118 140)oklch(0.884 0.067 140)metric-tile, range-bar, result-card, score-dial
--opsin-category-activity-accentsemanticThe identity fill: a bar fill, a dial track, a legend dot. Chosen for recognition, not for contrast. It must be bounded by line or labelled in ink; it is never the only thing that carries the meaning.oklch(0.7 0.16 140)oklch(0.714 0.141 140)log-sheet
--opsin-category-nutrition-50primitiveNutrition ramp, step 50.oklch(0.972 0.02 70)sameno component
--opsin-category-nutrition-100primitiveNutrition ramp, step 100.oklch(0.941 0.034 70)sameno component
--opsin-category-nutrition-200primitiveNutrition ramp, step 200.oklch(0.884 0.059 70)sameno component
--opsin-category-nutrition-300primitiveNutrition ramp, step 300.oklch(0.806 0.092 70)sameno component
--opsin-category-nutrition-400primitiveNutrition ramp, step 400.oklch(0.714 0.123 70)sameno component
--opsin-category-nutrition-500primitiveNutrition ramp, step 500.oklch(0.622 0.135 70)sameno component
--opsin-category-nutrition-600primitiveNutrition ramp, step 600.oklch(0.541 0.118 70)sameno component
--opsin-category-nutrition-700primitiveNutrition ramp, step 700.oklch(0.452 0.099 70)sameno component
--opsin-category-nutrition-800primitiveNutrition ramp, step 800.oklch(0.362 0.08 70)sameno component
--opsin-category-nutrition-900primitiveNutrition ramp, step 900.oklch(0.276 0.062 70)sameno component
--opsin-category-nutrition-950primitiveNutrition ramp, step 950.oklch(0.208 0.049 70)sameno component
--opsin-category-nutrition-surfacesemanticThe tinted background a component in this ramp sits on.oklch(0.972 0.02 70)oklch(0.208 0.049 70)no component
--opsin-category-nutrition-linesemanticThe boundary, icon stroke or chart mark. The lightest value in the ramp that clears the non-text floor against surface.oklch(0.541 0.118 70)oklch(0.806 0.092 70)trend-sparkline
--opsin-category-nutrition-inksemanticText and text-sized icons on surface. Clears the text floor against surface.oklch(0.362 0.08 70)oklch(0.884 0.059 70)metric-tile, range-bar, result-card, score-dial
--opsin-category-nutrition-accentsemanticThe identity fill: a bar fill, a dial track, a legend dot. Chosen for recognition, not for contrast. It must be bounded by line or labelled in ink; it is never the only thing that carries the meaning.oklch(0.75 0.14 70)oklch(0.714 0.123 70)log-sheet
--opsin-category-mind-50primitiveMind ramp, step 50.oklch(0.972 0.018 310)sameno component
--opsin-category-mind-100primitiveMind ramp, step 100.oklch(0.941 0.034 310)sameno component
--opsin-category-mind-200primitiveMind ramp, step 200.oklch(0.884 0.059 310)sameno component
--opsin-category-mind-300primitiveMind ramp, step 300.oklch(0.806 0.092 310)sameno component
--opsin-category-mind-400primitiveMind ramp, step 400.oklch(0.714 0.123 310)sameno component
--opsin-category-mind-500primitiveMind ramp, step 500.oklch(0.622 0.14 310)sameno component
--opsin-category-mind-600primitiveMind ramp, step 600.oklch(0.541 0.136 310)sameno component
--opsin-category-mind-700primitiveMind ramp, step 700.oklch(0.452 0.123 310)sameno component
--opsin-category-mind-800primitiveMind ramp, step 800.oklch(0.362 0.104 310)sameno component
--opsin-category-mind-900primitiveMind ramp, step 900.oklch(0.276 0.081 310)sameno component
--opsin-category-mind-950primitiveMind ramp, step 950.oklch(0.208 0.062 310)sameno component
--opsin-category-mind-surfacesemanticThe tinted background a component in this ramp sits on.oklch(0.972 0.018 310)oklch(0.208 0.062 310)no component
--opsin-category-mind-linesemanticThe boundary, icon stroke or chart mark. The lightest value in the ramp that clears the non-text floor against surface.oklch(0.541 0.136 310)oklch(0.806 0.092 310)trend-sparkline
--opsin-category-mind-inksemanticText and text-sized icons on surface. Clears the text floor against surface.oklch(0.362 0.104 310)oklch(0.884 0.059 310)metric-tile, range-bar, result-card, score-dial
--opsin-category-mind-accentsemanticThe identity fill: a bar fill, a dial track, a legend dot. Chosen for recognition, not for contrast. It must be bounded by line or labelled in ink; it is never the only thing that carries the meaning.oklch(0.62 0.14 310)oklch(0.714 0.123 310)log-sheet
--opsin-category-labs-50primitiveLabs ramp, step 50.oklch(0.972 0.015 210)sameno component
--opsin-category-labs-100primitiveLabs ramp, step 100.oklch(0.941 0.026 210)sameno component
--opsin-category-labs-200primitiveLabs ramp, step 200.oklch(0.884 0.046 210)sameno component
--opsin-category-labs-300primitiveLabs ramp, step 300.oklch(0.806 0.073 210)sameno component
--opsin-category-labs-400primitiveLabs ramp, step 400.oklch(0.714 0.097 210)sameno component
--opsin-category-labs-500primitiveLabs ramp, step 500.oklch(0.622 0.108 210)sameno component
--opsin-category-labs-600primitiveLabs ramp, step 600.oklch(0.541 0.094 210)sameno component
--opsin-category-labs-700primitiveLabs ramp, step 700.oklch(0.452 0.079 210)sameno component
--opsin-category-labs-800primitiveLabs ramp, step 800.oklch(0.362 0.063 210)sameno component
--opsin-category-labs-900primitiveLabs ramp, step 900.oklch(0.276 0.049 210)sameno component
--opsin-category-labs-950primitiveLabs ramp, step 950.oklch(0.208 0.038 210)sameno component
--opsin-category-labs-surfacesemanticThe tinted background a component in this ramp sits on.oklch(0.972 0.015 210)oklch(0.208 0.038 210)no component
--opsin-category-labs-linesemanticThe boundary, icon stroke or chart mark. The lightest value in the ramp that clears the non-text floor against surface.oklch(0.541 0.094 210)oklch(0.806 0.073 210)trend-sparkline
--opsin-category-labs-inksemanticText and text-sized icons on surface. Clears the text floor against surface.oklch(0.362 0.063 210)oklch(0.884 0.046 210)metric-tile, range-bar, result-card, score-dial
--opsin-category-labs-accentsemanticThe identity fill: a bar fill, a dial track, a legend dot. Chosen for recognition, not for contrast. It must be bounded by line or labelled in ink; it is never the only thing that carries the meaning.oklch(0.6 0.11 210)oklch(0.714 0.097 210)log-sheet

status

TokenTierWhat it controlsLightDarkUsed by
--opsin-status-steady-50primitiveSteady ramp, step 50.oklch(0.972 0.015 178)sameno component
--opsin-status-steady-100primitiveSteady ramp, step 100.oklch(0.941 0.026 178)sameno component
--opsin-status-steady-200primitiveSteady ramp, step 200.oklch(0.884 0.046 178)sameno component
--opsin-status-steady-300primitiveSteady ramp, step 300.oklch(0.806 0.073 178)sameno component
--opsin-status-steady-400primitiveSteady ramp, step 400.oklch(0.714 0.097 178)sameno component
--opsin-status-steady-500primitiveSteady ramp, step 500.oklch(0.622 0.11 178)sameno component
--opsin-status-steady-600primitiveSteady ramp, step 600.oklch(0.541 0.1 178)sameno component
--opsin-status-steady-700primitiveSteady ramp, step 700.oklch(0.452 0.084 178)sameno component
--opsin-status-steady-800primitiveSteady ramp, step 800.oklch(0.362 0.067 178)sameno component
--opsin-status-steady-900primitiveSteady ramp, step 900.oklch(0.276 0.052 178)sameno component
--opsin-status-steady-950primitiveSteady ramp, step 950.oklch(0.208 0.041 178)sameno component
--opsin-status-steady-surfacesemanticThe tinted background a component in this ramp sits on.oklch(0.972 0.015 178)oklch(0.208 0.041 178)alert-banner, status-pill
--opsin-status-steady-linesemanticThe boundary, icon stroke or chart mark. The lightest value in the ramp that clears the non-text floor against surface.oklch(0.541 0.1 178)oklch(0.806 0.073 178)alert-banner, range-bar, range-legend, status-pill
--opsin-status-steady-inksemanticText and text-sized icons on surface. Clears the text floor against surface.oklch(0.362 0.067 178)oklch(0.884 0.046 178)alert-banner, score-dial, status-pill
--opsin-status-steady-accentsemanticThe identity fill: a bar fill, a dial track, a legend dot. Chosen for recognition, not for contrast. It must be bounded by line or labelled in ink; it is never the only thing that carries the meaning.oklch(0.62 0.11 178)oklch(0.714 0.097 178)score-dial
--opsin-status-watch-50primitiveWatch ramp, step 50.oklch(0.972 0.02 82)sameno component
--opsin-status-watch-100primitiveWatch ramp, step 100.oklch(0.941 0.034 82)sameno component
--opsin-status-watch-200primitiveWatch ramp, step 200.oklch(0.884 0.059 82)sameno component
--opsin-status-watch-300primitiveWatch ramp, step 300.oklch(0.806 0.092 82)sameno component
--opsin-status-watch-400primitiveWatch ramp, step 400.oklch(0.714 0.123 82)sameno component
--opsin-status-watch-500primitiveWatch ramp, step 500.oklch(0.622 0.129 82)sameno component
--opsin-status-watch-600primitiveWatch ramp, step 600.oklch(0.541 0.112 82)sameno component
--opsin-status-watch-700primitiveWatch ramp, step 700.oklch(0.452 0.094 82)sameno component
--opsin-status-watch-800primitiveWatch ramp, step 800.oklch(0.362 0.076 82)sameno component
--opsin-status-watch-900primitiveWatch ramp, step 900.oklch(0.276 0.059 82)sameno component
--opsin-status-watch-950primitiveWatch ramp, step 950.oklch(0.208 0.046 82)sameno component
--opsin-status-watch-surfacesemanticThe tinted background a component in this ramp sits on.oklch(0.972 0.02 82)oklch(0.208 0.046 82)alert-banner, status-pill
--opsin-status-watch-linesemanticThe boundary, icon stroke or chart mark. The lightest value in the ramp that clears the non-text floor against surface.oklch(0.541 0.112 82)oklch(0.806 0.092 82)alert-banner, range-bar, range-legend, status-pill
--opsin-status-watch-inksemanticText and text-sized icons on surface. Clears the text floor against surface.oklch(0.362 0.076 82)oklch(0.884 0.059 82)alert-banner, score-dial, status-pill
--opsin-status-watch-accentsemanticThe identity fill: a bar fill, a dial track, a legend dot. Chosen for recognition, not for contrast. It must be bounded by line or labelled in ink; it is never the only thing that carries the meaning.oklch(0.60 0.123 82)oklch(0.714 0.123 82)score-dial
--opsin-status-attention-50primitiveNeeds attention ramp, step 50.oklch(0.972 0.015 45)sameno component
--opsin-status-attention-100primitiveNeeds attention ramp, step 100.oklch(0.941 0.032 45)sameno component
--opsin-status-attention-200primitiveNeeds attention ramp, step 200.oklch(0.884 0.063 45)sameno component
--opsin-status-attention-300primitiveNeeds attention ramp, step 300.oklch(0.806 0.099 45)sameno component
--opsin-status-attention-400primitiveNeeds attention ramp, step 400.oklch(0.714 0.132 45)sameno component
--opsin-status-attention-500primitiveNeeds attention ramp, step 500.oklch(0.622 0.15 45)sameno component
--opsin-status-attention-600primitiveNeeds attention ramp, step 600.oklch(0.541 0.145 45)sameno component
--opsin-status-attention-700primitiveNeeds attention ramp, step 700.oklch(0.452 0.13 45)sameno component
--opsin-status-attention-800primitiveNeeds attention ramp, step 800.oklch(0.362 0.105 45)sameno component
--opsin-status-attention-900primitiveNeeds attention ramp, step 900.oklch(0.276 0.082 45)sameno component
--opsin-status-attention-950primitiveNeeds attention ramp, step 950.oklch(0.208 0.065 45)sameno component
--opsin-status-attention-surfacesemanticThe tinted background a component in this ramp sits on.oklch(0.972 0.015 45)oklch(0.208 0.065 45)alert-banner, status-pill
--opsin-status-attention-linesemanticThe boundary, icon stroke or chart mark. The lightest value in the ramp that clears the non-text floor against surface.oklch(0.541 0.145 45)oklch(0.806 0.099 45)alert-banner, range-bar, range-legend, status-pill
--opsin-status-attention-inksemanticText and text-sized icons on surface. Clears the text floor against surface.oklch(0.362 0.105 45)oklch(0.884 0.063 45)alert-banner, score-dial, status-pill
--opsin-status-attention-accentsemanticThe identity fill: a bar fill, a dial track, a legend dot. Chosen for recognition, not for contrast. It must be bounded by line or labelled in ink; it is never the only thing that carries the meaning.oklch(0.58 0.15 45)oklch(0.714 0.132 45)score-dial
--opsin-status-urgent-50primitiveUrgent ramp, step 50.oklch(0.972 0.014 27)sameno component
--opsin-status-urgent-100primitiveUrgent ramp, step 100.oklch(0.941 0.03 27)sameno component
--opsin-status-urgent-200primitiveUrgent ramp, step 200.oklch(0.884 0.061 27)sameno component
--opsin-status-urgent-300primitiveUrgent ramp, step 300.oklch(0.806 0.11 27)sameno component
--opsin-status-urgent-400primitiveUrgent ramp, step 400.oklch(0.714 0.176 27)sameno component
--opsin-status-urgent-500primitiveUrgent ramp, step 500.oklch(0.622 0.2 27)sameno component
--opsin-status-urgent-600primitiveUrgent ramp, step 600.oklch(0.541 0.194 27)sameno component
--opsin-status-urgent-700primitiveUrgent ramp, step 700.oklch(0.452 0.176 27)sameno component
--opsin-status-urgent-800primitiveUrgent ramp, step 800.oklch(0.362 0.148 27)sameno component
--opsin-status-urgent-900primitiveUrgent ramp, step 900.oklch(0.276 0.115 27)sameno component
--opsin-status-urgent-950primitiveUrgent ramp, step 950.oklch(0.208 0.088 27)sameno component
--opsin-status-urgent-surfacesemanticThe tinted background a component in this ramp sits on.oklch(0.972 0.014 27)oklch(0.208 0.088 27)alert-banner, status-pill
--opsin-status-urgent-linesemanticThe boundary, icon stroke or chart mark. The lightest value in the ramp that clears the non-text floor against surface.oklch(0.541 0.194 27)oklch(0.806 0.11 27)alert-banner, range-bar, range-legend, status-pill
--opsin-status-urgent-inksemanticText and text-sized icons on surface. Clears the text floor against surface.oklch(0.362 0.148 27)oklch(0.884 0.061 27)alert-banner, score-dial, status-pill
--opsin-status-urgent-accentsemanticThe identity fill: a bar fill, a dial track, a legend dot. Chosen for recognition, not for contrast. It must be bounded by line or labelled in ink; it is never the only thing that carries the meaning.oklch(0.52 0.2 27)oklch(0.714 0.176 27)score-dial
--opsin-status-unknown-50primitiveUnknown ramp, step 50.oklch(0.972 0.003 250)sameno component
--opsin-status-unknown-100primitiveUnknown ramp, step 100.oklch(0.941 0.005 250)sameno component
--opsin-status-unknown-200primitiveUnknown ramp, step 200.oklch(0.884 0.008 250)sameno component
--opsin-status-unknown-300primitiveUnknown ramp, step 300.oklch(0.806 0.013 250)sameno component
--opsin-status-unknown-400primitiveUnknown ramp, step 400.oklch(0.714 0.018 250)sameno component
--opsin-status-unknown-500primitiveUnknown ramp, step 500.oklch(0.622 0.02 250)sameno component
--opsin-status-unknown-600primitiveUnknown ramp, step 600.oklch(0.541 0.019 250)sameno component
--opsin-status-unknown-700primitiveUnknown ramp, step 700.oklch(0.452 0.018 250)sameno component
--opsin-status-unknown-800primitiveUnknown ramp, step 800.oklch(0.362 0.015 250)sameno component
--opsin-status-unknown-900primitiveUnknown ramp, step 900.oklch(0.276 0.012 250)sameno component
--opsin-status-unknown-950primitiveUnknown ramp, step 950.oklch(0.208 0.009 250)sameno component
--opsin-status-unknown-surfacesemanticThe tinted background a component in this ramp sits on.oklch(0.972 0.003 250)oklch(0.208 0.009 250)no component
--opsin-status-unknown-linesemanticThe boundary, icon stroke or chart mark. The lightest value in the ramp that clears the non-text floor against surface.oklch(0.541 0.019 250)oklch(0.806 0.013 250)no component
--opsin-status-unknown-inksemanticText and text-sized icons on surface. Clears the text floor against surface.oklch(0.362 0.015 250)oklch(0.884 0.008 250)no component
--opsin-status-unknown-accentsemanticThe identity fill: a bar fill, a dial track, a legend dot. Chosen for recognition, not for contrast. It must be bounded by line or labelled in ink; it is never the only thing that carries the meaning.oklch(0.72 0.02 250)oklch(0.714 0.018 250)no component

material

material

TokenTierWhat it controlsLightDarkUsed by
--opsin-material-canvas-tintsemanticRung 0 (canvas): the tint over what is behind it. The application background. Nothing is behind it, so nothing shows through it.var(--opsin-neutral-0)var(--opsin-neutral-950)surface
--opsin-material-canvas-tint-alphasemanticRung 0 (canvas): how opaque that tint is.1samesurface
--opsin-material-canvas-blursemanticRung 0 (canvas): backdrop blur radius.0pxsamesurface
--opsin-material-canvas-saturationsemanticRung 0 (canvas): backdrop saturation multiplier.1samesurface
--opsin-material-canvas-bordersemanticRung 0 (canvas): the boundary.nonesamesurface
--opsin-material-canvas-shadowsemanticRung 0 (canvas): the shadow that separates it from what is behind.nonesamesurface
--opsin-material-canvas-scrimsemanticRung 0 (canvas): the minimum scrim opacity needed for text on this rung to clear the contrast floor.0samesurface
--opsin-material-canvas-opaquesemanticRung 0 (canvas): the opaque substitute used under prefers-reduced-transparency and where backdrop-filter is unsupported.var(--opsin-neutral-0)var(--opsin-neutral-950)surface
--opsin-material-inset-tintsemanticRung 0.5 (inset): the tint over what is behind it. The recessed well inside a card: the explanatory note a Callout draws inside the reading it annotates, and the track a RangeBar lays its range along. Its fill sits below the card fill in both themes, so the well reads as carved into the card rather than lifted off it. In light it is neutral-100, one step under the white card, which is where a Callout already sat. In dark it is a value between the page and the card, below the card so the well is a recess and above the page so a Callout used on its own is still visible.var(--opsin-neutral-100)oklch(0.178 0.006 250)callout, range-bar, surface
--opsin-material-inset-tint-alphasemanticRung 0.5 (inset): how opaque that tint is.1samesurface
--opsin-material-inset-blursemanticRung 0.5 (inset): backdrop blur radius.0pxsamesurface
--opsin-material-inset-saturationsemanticRung 0.5 (inset): backdrop saturation multiplier.1samesurface
--opsin-material-inset-bordersemanticRung 0.5 (inset): the boundary.nonesamesurface
--opsin-material-inset-shadowsemanticRung 0.5 (inset): the shadow that separates it from what is behind.nonesamesurface
--opsin-material-inset-scrimsemanticRung 0.5 (inset): the minimum scrim opacity needed for text on this rung to clear the contrast floor.0samesurface
--opsin-material-inset-opaquesemanticRung 0.5 (inset): the opaque substitute used under prefers-reduced-transparency and where backdrop-filter is unsupported.var(--opsin-neutral-100)oklch(0.178 0.006 250)surface
--opsin-material-card-tintsemanticRung 1 (card): the tint over what is behind it. The default home for a health value. Opaque, bounded by a line rather than a shadow, and the rung every ResultCard, MetricTile and RangeBar sits on.var(--opsin-neutral-0)var(--opsin-neutral-900)surface
--opsin-material-card-tint-alphasemanticRung 1 (card): how opaque that tint is.1samesurface
--opsin-material-card-blursemanticRung 1 (card): backdrop blur radius.0pxsamesurface
--opsin-material-card-saturationsemanticRung 1 (card): backdrop saturation multiplier.1samesurface
--opsin-material-card-bordersemanticRung 1 (card): the boundary.var(--opsin-neutral-200)var(--opsin-neutral-800)surface
--opsin-material-card-shadowsemanticRung 1 (card): the shadow that separates it from what is behind.nonesamesurface
--opsin-material-card-scrimsemanticRung 1 (card): the minimum scrim opacity needed for text on this rung to clear the contrast floor.0samesurface
--opsin-material-card-opaquesemanticRung 1 (card): the opaque substitute used under prefers-reduced-transparency and where backdrop-filter is unsupported.var(--opsin-neutral-0)var(--opsin-neutral-900)surface
--opsin-material-raised-tintsemanticRung 2 (raised): the tint over what is behind it. Menus, popovers, tooltips, a dragged card. Still opaque: the shadow, not translucency, is what says 'above'.var(--opsin-neutral-0)var(--opsin-neutral-800)surface
--opsin-material-raised-tint-alphasemanticRung 2 (raised): how opaque that tint is.1samesurface
--opsin-material-raised-blursemanticRung 2 (raised): backdrop blur radius.0pxsamesurface
--opsin-material-raised-saturationsemanticRung 2 (raised): backdrop saturation multiplier.1samesurface
--opsin-material-raised-bordersemanticRung 2 (raised): the boundary.var(--opsin-neutral-200)var(--opsin-neutral-700)surface
--opsin-material-raised-shadowsemanticRung 2 (raised): the shadow that separates it from what is behind.0 1px 2px oklch(0 0 0 / 0.06), 0 4px 12px oklch(0 0 0 / 0.06)samesurface
--opsin-material-raised-scrimsemanticRung 2 (raised): the minimum scrim opacity needed for text on this rung to clear the contrast floor.0samesurface
--opsin-material-raised-opaquesemanticRung 2 (raised): the opaque substitute used under prefers-reduced-transparency and where backdrop-filter is unsupported.var(--opsin-neutral-0)var(--opsin-neutral-800)surface
--opsin-material-sheet-tintsemanticRung 3 (sheet): the tint over what is behind it. A bottom sheet or side panel the reader can dismiss by dragging. Its tint is now near opaque, so the panel lands close to the card colour and a white control inside it no longer floats above a greyer surface. What keeps the covered page recognisable is the scrim around the panel rather than the page reading through the panel, because at this opacity very little of the page shows through the tint.var(--opsin-neutral-0)var(--opsin-neutral-900)surface
--opsin-material-sheet-tint-alphasemanticRung 3 (sheet): how opaque that tint is.0.930.9surface
--opsin-material-sheet-blursemanticRung 3 (sheet): backdrop blur radius.20pxsamesurface
--opsin-material-sheet-saturationsemanticRung 3 (sheet): backdrop saturation multiplier.1.6samesurface
--opsin-material-sheet-bordersemanticRung 3 (sheet): the boundary.oklch(0 0 0 / 0.08)oklch(1 0 0 / 0.10)surface
--opsin-material-sheet-shadowsemanticRung 3 (sheet): the shadow that separates it from what is behind.0 -1px 2px oklch(0 0 0 / 0.05)samesheet, surface
--opsin-material-sheet-scrimsemanticRung 3 (sheet): the minimum scrim opacity needed for text on this rung to clear the contrast floor.0.93samesurface
--opsin-material-sheet-opaquesemanticRung 3 (sheet): the opaque substitute used under prefers-reduced-transparency and where backdrop-filter is unsupported.var(--opsin-neutral-0)var(--opsin-neutral-900)surface
--opsin-material-overlay-tintsemanticRung 4 (overlay): the tint over what is behind it. A pinned toolbar, a tab bar and a floating action bar are all chrome that content scrolls beneath.var(--opsin-neutral-0)var(--opsin-neutral-900)surface
--opsin-material-overlay-tint-alphasemanticRung 4 (overlay): how opaque that tint is.0.740.7surface
--opsin-material-overlay-blursemanticRung 4 (overlay): backdrop blur radius.28pxsamesurface
--opsin-material-overlay-saturationsemanticRung 4 (overlay): backdrop saturation multiplier.1.8samesurface
--opsin-material-overlay-bordersemanticRung 4 (overlay): the boundary.oklch(0 0 0 / 0.10)oklch(1 0 0 / 0.12)surface
--opsin-material-overlay-shadowsemanticRung 4 (overlay): the shadow that separates it from what is behind.0 8px 32px oklch(0 0 0 / 0.12)samecombobox, menu, popover, select, surface, toast, tooltip
--opsin-material-overlay-scrimsemanticRung 4 (overlay): the minimum scrim opacity needed for text on this rung to clear the contrast floor.0.74samesurface
--opsin-material-overlay-opaquesemanticRung 4 (overlay): the opaque substitute used under prefers-reduced-transparency and where backdrop-filter is unsupported.var(--opsin-neutral-0)var(--opsin-neutral-900)surface
--opsin-material-scrim-tintsemanticRung 5 (scrim): the tint over what is behind it. The dimming layer behind a modal dialog or a consent sheet. Its job is to remove the page from consideration, not to look like glass.var(--opsin-neutral-950)var(--opsin-neutral-1000)surface
--opsin-material-scrim-tint-alphasemanticRung 5 (scrim): how opaque that tint is.0.440.6surface
--opsin-material-scrim-blursemanticRung 5 (scrim): backdrop blur radius.2pxsamesurface
--opsin-material-scrim-saturationsemanticRung 5 (scrim): backdrop saturation multiplier.1samesurface
--opsin-material-scrim-bordersemanticRung 5 (scrim): the boundary.nonesamesurface
--opsin-material-scrim-shadowsemanticRung 5 (scrim): the shadow that separates it from what is behind.nonesamesurface
--opsin-material-scrim-scrimsemanticRung 5 (scrim): the minimum scrim opacity needed for text on this rung to clear the contrast floor.0.44samesurface
--opsin-material-scrim-opaquesemanticRung 5 (scrim): the opaque substitute used under prefers-reduced-transparency and where backdrop-filter is unsupported.oklch(0.205 0.006 250 / 0.72)oklch(0 0 0 / 0.8)surface

motion

ease

TokenTierWhat it controlsLightDarkUsed by
--opsin-ease-spring-snapsemanticDirect manipulation only: a switch the reader just flipped, a segmented control, a pressed button settling. It overshoots by 1.5%. That is enough to feel physical but not enough to look playful. The 1.5% is the largest overshoot in the system but not the only one: spring-settle overshoots by 0.88%. Only spring-calm and spring-sheet reach their target without passing it.linear(0, 0.0715, 0.2271, 0.4053, 0.5722, 0.7119, 0.8198, 0.8978, 0.9505, 0.9836, 1.0025, 1.0118, 1.015, 1.0147, 1.0126, 1.01, 1.0073, 1.0051, 1.0033, 1.0019, 1)sameno component
--opsin-ease-spring-settlesemanticThe workhorse for chrome: popovers, tooltips, menus, chips appearing and disappearing.linear(0, 0.0742, 0.2328, 0.4113, 0.5758, 0.7116, 0.8157, 0.8905, 0.9412, 0.9736, 0.9928, 1.003, 1.0076, 1.0088, 1.0082, 1.0068, 1.0053, 1.0038, 1.0026, 1.0017, 1)sameno component
--opsin-ease-spring-calmsemanticA health value that changes while it is already on screen: a bar re-filling from one reading to the next, a dial travelling between two values the reader has already been shown. Never a first paint and never a first reveal. A value arrives at its final figure, with no count-up, no dial sweep and no line drawing itself in (health/motion-in-health-ui rule 2). Slightly overdamped (zeta just over 1) so it never overshoots and never bounces.linear(0, 0.0829, 0.2457, 0.4157, 0.5642, 0.6832, 0.774, 0.841, 0.8893, 0.9236, 0.9476, 0.9643, 0.9757, 0.9836, 0.9889, 0.9926, 0.995, 0.9967, 0.9978, 0.9985, 1)sameno component
--opsin-ease-spring-sheetsemanticLarge surfaces travelling a long distance: sheets, dialogs, full-screen pushes. Overdamped, because a sheet that bounces at the top of its travel reads as a dropped object.linear(0, 0.0881, 0.2576, 0.431, 0.5798, 0.6971, 0.7854, 0.8497, 0.8958, 0.9282, 0.9508, 0.9664, 0.9771, 0.9845, 0.9895, 0.9929, 0.9952, 0.9967, 0.9978, 0.9985, 1)samedialog, sheet
--opsin-ease-standardsemanticNon-spring transitions where a spring would be overkill: colour, opacity, border. Fast out, slow in.cubic-bezier(0.2, 0, 0, 1)sameaccordion, body-map, button, checkbox, combobox, consent-sheet, dialog, menu, number-field, popover, progress, radio-group, scale-input, scroll-area, segmented-control, select, sheet, skeleton, slider, switch, symptom-picker, tab-bar, tabs, textarea, toast, tooltip
--opsin-ease-entersemanticSomething arriving from off-screen or from nothing. Decelerating, because an arrival should feel like it is coming to rest.cubic-bezier(0.05, 0.7, 0.1, 1)sameno component
--opsin-ease-exitsemanticSomething leaving. Accelerating and shorter than its enter, because a reader does not need to watch a dismissal finish.cubic-bezier(0.3, 0, 0.8, 0.15)samedialog

duration

TokenTierWhat it controlsLightDarkUsed by
--opsin-duration-spring-snapsemanticSettle time for the spring-snap spring, measured from its own parameters.283mssameno component
--opsin-duration-spring-settlesemanticSettle time for the spring-settle spring, measured from its own parameters.382mssameno component
--opsin-duration-spring-calmsemanticSettle time for the spring-calm spring, measured from its own parameters.550mssameno component
--opsin-duration-spring-sheetsemanticSettle time for the spring-sheet spring, measured from its own parameters.483mssamedialog, sheet
--opsin-duration-instantsemanticState change with no travel: hover tint, focus ring, checkbox tick.80mssameno component
--opsin-duration-fastsemanticSmall elements moving a small distance.140mssameaccordion, body-map, button, checkbox, combobox, consent-sheet, dialog, menu, number-field, popover, progress, radio-group, scale-input, scroll-area, segmented-control, select, sheet, skeleton, slider, switch, symptom-picker, tab-bar, tabs, textarea, toast, tooltip
--opsin-duration-basesemanticThe default for chrome that is not spring-driven.220mssamedialog, sheet
--opsin-duration-slowsemanticLayout change: a list reflowing, a card expanding.360mssameno component
--opsin-duration-deliberatesemanticThe ceiling on a transition a reader is waiting on, such as a first-run reveal or a consent sheet, where the point is that the reader notices. No such transition may exceed it. A looping placeholder period, like the skeleton shimmer, is bounded instead by its iteration count, so a single sweep of it may run longer.560mssameno component
--opsin-duration-shimmersemanticOne sweep of a loading placeholder's sheen. This is a period, the time for the sheen to make one pass across the bar, and not a travel time. At 1600ms the movement reads as calm rather than as urgency, which the first motion rule requires of anything that is not a value the reader controls. Its consumer pairs it with a finite iteration count so the total motion stays under the five seconds at which WCAG 2.2 SC 2.2.2 engages.1600mssameskeleton

type

font

TokenTierWhat it controlsLightDarkUsed by
--opsin-font-sanssemanticThe sans family stack.system-ui, -apple-system, 'Segoe UI', Roboto, 'Helvetica Neue', Arial, sans-serifsameno component
--opsin-font-monosemanticThe mono family stack.ui-monospace, SFMono-Regular, 'SF Mono', Menlo, Consolas, 'Liberation Mono', monospacesameno component
--opsin-font-numericsemanticThe numeric family stack.system-ui, -apple-system, 'Segoe UI', Roboto, sans-serifsameresult-card, value

text

TokenTierWhat it controlsLightDarkUsed by
--opsin-text-large-title-sizesemanticThe largest step in the scale, reserved for a surface whose entire subject is one number or one word. No component in the system sets a value at this step yet.2.125remsameno component
--opsin-text-large-title-leadingsemanticLine height for largeTitle, unitless so it scales with the size.1.206sameno component
--opsin-text-large-title-trackingsemanticLetter spacing for largeTitle.-0.011emsameno component
--opsin-text-large-title-weightsemanticFont weight for largeTitle.700sameno component
--opsin-text-title1-sizesemanticA screen title, and the hero treatment a value's number takes at size display.1.75remsameresult-card, value
--opsin-text-title1-leadingsemanticLine height for title1, unitless so it scales with the size.1.214sameresult-card, value
--opsin-text-title1-trackingsemanticLetter spacing for title1.-0.009emsameresult-card, value
--opsin-text-title1-weightsemanticFont weight for title1.700sameresult-card, value
--opsin-text-title2-sizesemanticSection title; the floor for a primary health value inside a card.1.375remsamegoal-ring
--opsin-text-title2-leadingsemanticLine height for title2, unitless so it scales with the size.1.273samegoal-ring
--opsin-text-title2-trackingsemanticLetter spacing for title2.-0.006emsamegoal-ring
--opsin-text-title2-weightsemanticFont weight for title2.600samegoal-ring
--opsin-text-title3-sizesemanticA Dialog or Sheet title, and the unit beside a value's number at size display.1.25remsamedialog, questionnaire, reading-input, sheet, value
--opsin-text-title3-leadingsemanticLine height for title3, unitless so it scales with the size.1.25samedialog, questionnaire, reading-input, sheet, value
--opsin-text-title3-trackingsemanticLetter spacing for title3.-0.004emsamedialog, questionnaire, reading-input, sheet, value
--opsin-text-title3-weightsemanticFont weight for title3.600samedialog, questionnaire, reading-input, sheet, value
--opsin-text-headline-sizesemanticAn emphasised line of body text, such as a status sentence or a question in a form.1.0625remsameaccordion, alert-banner, avatar, button, callout, card, care-card, empty-state, field, log-sheet, menu, popover, range-bar, reading-input, result-card, scale-input, segmented-control, status-pill, surface, tabs, textarea, timeline-entry, toast, trend-sparkline, value
--opsin-text-headline-leadingsemanticLine height for headline, unitless so it scales with the size.1.294sameaccordion, alert-banner, avatar, button, callout, card, care-card, empty-state, field, log-sheet, menu, popover, range-bar, reading-input, result-card, scale-input, segmented-control, status-pill, surface, tabs, textarea, timeline-entry, toast, trend-sparkline, value
--opsin-text-headline-trackingsemanticLetter spacing for headline.-0.003emsameaccordion, alert-banner, avatar, button, callout, card, care-card, empty-state, field, log-sheet, menu, popover, range-bar, reading-input, result-card, scale-input, segmented-control, status-pill, surface, tabs, textarea, timeline-entry, toast, trend-sparkline, value
--opsin-text-headline-weightsemanticFont weight for headline.600sameaccordion, alert-banner, avatar, button, callout, card, care-card, empty-state, field, log-sheet, menu, popover, range-bar, reading-input, result-card, scale-input, segmented-control, status-pill, surface, tabs, textarea, timeline-entry, toast, trend-sparkline, value
--opsin-text-body-sizesemanticEverything a reader reads as prose. The anchor of the scale.1.0625remsameaccordion, alert-banner, badge, callout, card, care-card, checkbox, combobox, consent-sheet, dialog, disclaimer-note, divider, dose-tracker, empty-state, field, link, menu, number-field, popover, questionnaire, radio-group, range-bar, range-legend, reading-input, relative-time, result-card, score-dial, scroll-area, select, sheet, surface, switch, symptom-picker, table, tabs, term, textarea, timeline-entry, toast, tooltip, trend-sparkline, value, visually-hidden
--opsin-text-body-leadingsemanticLine height for body, unitless so it scales with the size.1.294sameaccordion, alert-banner, badge, callout, card, care-card, checkbox, combobox, consent-sheet, dialog, disclaimer-note, divider, dose-tracker, empty-state, field, link, menu, number-field, popover, questionnaire, radio-group, range-bar, range-legend, reading-input, relative-time, result-card, score-dial, scroll-area, select, sheet, skeleton, surface, switch, symptom-picker, table, tabs, term, textarea, timeline-entry, toast, tooltip, trend-sparkline, value, visually-hidden
--opsin-text-body-trackingsemanticLetter spacing for body.-0.003emsameaccordion, alert-banner, badge, callout, card, care-card, checkbox, combobox, consent-sheet, dialog, disclaimer-note, divider, dose-tracker, empty-state, field, link, menu, number-field, popover, questionnaire, radio-group, range-bar, range-legend, reading-input, relative-time, result-card, score-dial, scroll-area, select, sheet, surface, switch, symptom-picker, table, tabs, term, textarea, timeline-entry, toast, tooltip, trend-sparkline, value, visually-hidden
--opsin-text-body-weightsemanticFont weight for body.400sameaccordion, alert-banner, badge, callout, card, care-card, checkbox, combobox, consent-sheet, dialog, disclaimer-note, divider, dose-tracker, empty-state, field, link, menu, number-field, popover, questionnaire, radio-group, range-bar, range-legend, reading-input, relative-time, result-card, score-dial, scroll-area, select, sheet, surface, switch, symptom-picker, table, tabs, term, textarea, timeline-entry, toast, tooltip, trend-sparkline, value, visually-hidden
--opsin-text-callout-sizesemanticSecondary prose inside a card or a callout.1remsamedialog, sheet, toast
--opsin-text-callout-leadingsemanticLine height for callout, unitless so it scales with the size.1.313samedialog, sheet, toast
--opsin-text-callout-trackingsemanticLetter spacing for callout.-0.002emsamedialog, sheet, toast
--opsin-text-callout-weightsemanticFont weight for callout.400samedialog, sheet, toast
--opsin-text-subheadline-sizesemanticA supporting line under a title.0.9375remsamebutton, care-card, empty-state, goal-ring, metric-tile, progress, radio-group, score-dial, segmented-control, slider, spinner, status-pill, stepper, table
--opsin-text-subheadline-leadingsemanticLine height for subheadline, unitless so it scales with the size.1.333samebutton, care-card, empty-state, goal-ring, metric-tile, progress, radio-group, score-dial, segmented-control, slider, spinner, status-pill, stepper, table
--opsin-text-subheadline-trackingsemanticLetter spacing for subheadline.-0.001emsamebutton, care-card, empty-state, goal-ring, metric-tile, progress, radio-group, score-dial, segmented-control, slider, spinner, status-pill, stepper, table
--opsin-text-subheadline-weightsemanticFont weight for subheadline.400samebutton, care-card, empty-state, goal-ring, metric-tile, progress, radio-group, score-dial, segmented-control, slider, spinner, status-pill, stepper, table
--opsin-text-subheadline-emphasis-sizesemanticThe emphasised twin of subheadline, for a compact control's label, where the control must read as narrower and never as quieter.0.9375remsameavatar, button
--opsin-text-subheadline-emphasis-leadingsemanticLine height for subheadlineEmphasis, unitless so it scales with the size.1.333sameavatar, button
--opsin-text-subheadline-emphasis-trackingsemanticLetter spacing for subheadlineEmphasis.-0.001emsameavatar, button
--opsin-text-subheadline-emphasis-weightsemanticFont weight for subheadlineEmphasis.600sameavatar, button
--opsin-text-footnote-sizesemanticProvenance: who measured this, when, with what.0.8125remsamebody-map, card, checkbox, combobox, consent-sheet, dialog, disclaimer-note, divider, dose-tracker, goal-ring, log-sheet, menu, metric-tile, questionnaire, radio-group, range-bar, range-legend, result-card, scale-input, score-dial, sheet, source-citation, status-pill, stepper, switch, symptom-picker, table, timeline-entry, toast, tooltip, trend-sparkline
--opsin-text-footnote-leadingsemanticLine height for footnote, unitless so it scales with the size.1.385samebody-map, card, checkbox, combobox, consent-sheet, dialog, disclaimer-note, divider, dose-tracker, goal-ring, log-sheet, menu, metric-tile, questionnaire, radio-group, range-bar, range-legend, result-card, scale-input, score-dial, sheet, source-citation, status-pill, stepper, switch, symptom-picker, table, timeline-entry, toast, tooltip, trend-sparkline
--opsin-text-footnote-trackingsemanticLetter spacing for footnote.0emsamebody-map, card, checkbox, combobox, consent-sheet, dialog, disclaimer-note, divider, dose-tracker, goal-ring, log-sheet, menu, metric-tile, questionnaire, radio-group, range-bar, range-legend, result-card, scale-input, score-dial, sheet, source-citation, status-pill, stepper, switch, symptom-picker, table, timeline-entry, toast, tooltip, trend-sparkline
--opsin-text-footnote-weightsemanticFont weight for footnote.400samebody-map, card, checkbox, combobox, consent-sheet, dialog, disclaimer-note, divider, dose-tracker, goal-ring, log-sheet, menu, metric-tile, questionnaire, radio-group, range-bar, range-legend, result-card, scale-input, score-dial, sheet, source-citation, status-pill, stepper, switch, symptom-picker, table, timeline-entry, toast, tooltip, trend-sparkline
--opsin-text-caption1-sizesemanticAxis labels, legend text, and legal text.0.75remsameavatar, badge, consent-sheet, dose-tracker, range-bar, skeleton, tab-bar, visually-hidden
--opsin-text-caption1-leadingsemanticLine height for caption1, unitless so it scales with the size.1.333sameavatar, badge, consent-sheet, dose-tracker, range-bar, skeleton, tab-bar, visually-hidden
--opsin-text-caption1-trackingsemanticLetter spacing for caption1.0.002emsameavatar, badge, consent-sheet, dose-tracker, range-bar, skeleton, tab-bar, visually-hidden
--opsin-text-caption1-weightsemanticFont weight for caption1.400sameavatar, badge, consent-sheet, dose-tracker, range-bar, skeleton, tab-bar, visually-hidden
--opsin-text-caption2-sizesemanticThe smallest text the system permits, and only for text that repeats a label already present elsewhere. Never the only place a fact appears.0.6875remsameno component
--opsin-text-caption2-leadingsemanticLine height for caption2, unitless so it scales with the size.1.182sameno component
--opsin-text-caption2-trackingsemanticLetter spacing for caption2.0.005emsameno component
--opsin-text-caption2-weightsemanticFont weight for caption2.500sameno component

numerals

TokenTierWhat it controlsLightDarkUsed by
--opsin-numeralssemanticEvery component that renders a number sets this, so a changing value does not shift its own layout.tabular-numssameno component

space

space

TokenTierWhat it controlsLightDarkUsed by
--opsin-space-0primitive0px.0remsameno component
--opsin-space-1primitiveGap between an icon and its label.0.25remsamebadge, button, callout, care-card, checkbox, combobox, dialog, dose-tracker, empty-state, field, goal-ring, log-sheet, menu, questionnaire, radio-group, range-bar, result-card, scale-input, scroll-area, segmented-control, select, sheet, slider, source-citation, status-pill, stepper, surface, symptom-picker, tab-bar, tabs, timeline-entry, toast, tooltip, trend-sparkline
--opsin-space-2primitiveGap between tightly related lines. For the separation between two interactive targets see targets.separation, which is the same number and carries its scope.0.5remsamealert-banner, avatar, badge, body-map, button, callout, combobox, consent-sheet, dialog, disclaimer-note, dose-tracker, empty-state, field, icon-button, log-sheet, menu, metric-tile, number-field, popover, progress, questionnaire, radio-group, range-bar, range-legend, reading-input, relative-time, scale-input, score-dial, scroll-area, segmented-control, select, sheet, skeleton, slider, spinner, status-pill, surface, symptom-picker, tab-bar, table, tabs, textarea, timeline-entry, toast, tooltip, trend-sparkline, visually-hidden
--opsin-space-3primitiveInner padding of a compact control.0.75remsameaccordion, alert-banner, button, card, checkbox, combobox, consent-sheet, dialog, disclaimer-note, divider, empty-state, field, log-sheet, menu, metric-tile, popover, progress, radio-group, reading-input, result-card, scroll-area, segmented-control, select, sheet, slider, status-pill, stepper, surface, symptom-picker, tab-bar, table, tabs, textarea, timeline-entry, toast, tooltip, value
--opsin-space-4primitiveThe default gap between elements inside a card.1remsameaccordion, avatar, badge, button, callout, care-card, consent-sheet, dialog, divider, empty-state, goal-ring, link, log-sheet, menu, popover, range-legend, result-card, scale-input, score-dial, segmented-control, sheet, surface, switch, tabs, timeline-entry, toast
--opsin-space-5primitiveCard inner padding on a phone.1.25remsameavatar, button, consent-sheet, dialog, questionnaire, sheet, slider, switch, symptom-picker
--opsin-space-6primitiveCard inner padding on a wide screen; gap between cards.1.5remsameavatar, card, dialog, disclaimer-note, empty-state, field, log-sheet, skeleton, stepper, switch, tab-bar, trend-sparkline
--opsin-space-8primitiveGap between sections within a screen.2remsameavatar, body-map, disclaimer-note, popover, range-bar, reading-input, sheet, stepper
--opsin-space-10primitiveSpace above a section heading.2.5remsameavatar, sheet, skeleton, switch
--opsin-space-12primitiveGap between major regions of a screen.3remsameavatar, trend-sparkline
--opsin-space-16primitiveTop of a screen below the safe area; the space a consent sheet leaves above its first question.4remsamedialog, skeleton
--opsin-space-20primitiveEmpty-state vertical rhythm.5remsameno component
--opsin-space-24primitiveThe largest step. Beyond this, use a layout, not a gap.6remsameno component
--opsin-space-pxprimitiveHairline borders only.0.0625remsamebody-map, trend-sparkline
--opsin-space-0-5primitiveOptical nudges. Not a layout step.0.125remsamebadge, dose-tracker, radio-group, range-legend, result-card, scroll-area, segmented-control, status-pill, stepper, switch, tab-bar, tabs, term, trend-sparkline

target

TokenTierWhat it controlsLightDarkUsed by
--opsin-target-minimumsemanticThe opsinjs floor for any interactive control, applied to the hit area rather than to the visible box.2.75remsameaccordion, body-map, button, card, checkbox, combobox, consent-sheet, dialog, disclaimer-note, field, icon-button, menu, metric-tile, number-field, popover, questionnaire, radio-group, reading-input, scale-input, segmented-control, select, sheet, slider, source-citation, switch, symptom-picker, tab-bar, tabs, textarea, toast, tooltip
--opsin-target-comfortablesemanticThe default for a primary action in the product theme.3remsamedialog
--opsin-target-generoussemanticA single primary action on a consent, escalation or emergency surface, where a mis-tap has a real cost.3.5remsameno component
--opsin-target-separationsemanticThe minimum gap between two adjacent targets whose visible boxes are smaller than 44px. It is a floor for undersized targets only. Two targets that both meet the 44px minimum are outside its scope, and separating those is governed by the differing cost of a mis-tap between them rather than by a fixed gap.0.5remsamealert-banner, card, care-card, consent-sheet, result-card

gutter

TokenTierWhat it controlsLightDarkUsed by
--opsin-gutter-phonesemanticThe screen gutter in the phone responsive mode.16pxsameno component
--opsin-gutter-tabletsemanticThe screen gutter in the tablet responsive mode.24pxsameno component
--opsin-gutter-widesemanticThe screen gutter in the wide responsive mode.32pxsameno component

measure

TokenTierWhat it controlsLightDarkUsed by
--opsin-measure-tightsemanticA caption or a legend.45chsamedialog, empty-state, goal-ring, popover, tooltip
--opsin-measure-comfortablesemanticThe maximum line length for prose anywhere in the product, including a disclaimer nobody wants to read.66chsamedisclaimer-note, result-card, score-dial, sheet, source-citation, term
--opsin-measure-widesemanticCode and machine output only.80chsameno component

graphic

TokenTierWhat it controlsLightDarkUsed by
--opsin-graphic-dialsemanticThe maximum width of the ScoreDial arc. This is 16em against the product body of 1.0625rem, which is 17rem and lands on the 4px grid at 68 steps, and it yields to w-full when the column is narrower.17remsamegoal-ring, score-dial

safe

TokenTierWhat it controlsLightDarkUsed by
--opsin-safe-topsemanticThe top safe-area inset, for installed web apps where browser chrome does not protect the edge.env(safe-area-inset-top, 0px)sameno component
--opsin-safe-rightsemanticThe right safe-area inset, for installed web apps where browser chrome does not protect the edge.env(safe-area-inset-right, 0px)samesheet
--opsin-safe-bottomsemanticThe bottom safe-area inset, for installed web apps where browser chrome does not protect the edge.env(safe-area-inset-bottom, 0px)samedialog, sheet
--opsin-safe-leftsemanticThe left safe-area inset, for installed web apps where browser chrome does not protect the edge.env(safe-area-inset-left, 0px)samesheet

shape

radius

TokenTierWhat it controlsLightDarkUsed by
--opsin-radius-basesemanticThe one radius the whole ladder is derived from.0.875remsameaccordion, alert-banner, button, callout, card, care-card, combobox, empty-state, field, menu, metric-tile, popover, questionnaire, radio-group, range-bar, reading-input, result-card, scale-input, segmented-control, select, skeleton, symptom-picker, tab-bar, textarea, timeline-entry, toast, tooltip, trend-sparkline
--opsin-radius-nonesemanticFull-bleed media and anything that meets a screen edge.0remsameno component
--opsin-radius-xssemanticThe floor for a nested corner. Tags inside a chip, a swatch inside a legend.0.25remsamepopover, range-legend, surface, symptom-picker, term, tooltip
--opsin-radius-smsemanticInputs and small controls inside a card.0.4375remsamecard, checkbox, combobox, consent-sheet, dialog, divider, field, log-sheet, menu, number-field, progress, reading-input, scroll-area, select, sheet, skeleton, slider, switch, tab-bar, tabs, toast, visually-hidden
--opsin-radius-mdsemanticThe default. Buttons, chips, cards.0.875remsamealert-banner, button, callout, card, combobox, empty-state, menu, metric-tile, popover, questionnaire, radio-group, result-card, scale-input, segmented-control, select, skeleton, symptom-picker, tab-bar, textarea, toast, tooltip
--opsin-radius-lgsemanticCards on a phone, where the card is nearly the width of the screen.1.3125remsameaccordion, card, combobox, disclaimer-note, menu, popover, result-card, scroll-area, segmented-control, select, surface, toast
--opsin-radius-xlsemanticSheets and dialogs. Applied to the leading edge only when the surface meets a screen edge on the other side.1.75remsamealert-banner, dialog, sheet
--opsin-radius-inner-cardsemanticA box inside a card at the comfortable density (card padding p-5).max(calc(0.875rem - 5 * var(--spacing)), var(--opsin-radius-xs))sameno component
--opsin-radius-inner-card-compactsemanticA box inside a card at the compact density (card padding p-4).max(calc(0.875rem - 4 * var(--spacing)), var(--opsin-radius-xs))sameno component

corner-shape

TokenTierWhat it controlsLightDarkUsed by
--opsin-corner-shapesemanticThe squircle curvature. Degrades to round where corner-shape is unsupported.superellipse(4)samealert-banner, callout, card, dialog, metric-tile, result-card, sheet

border

TokenTierWhat it controlsLightDarkUsed by
--opsin-border-hairlinesemanticEvery boundary in the system by default.1pxsamebutton, surface
--opsin-border-emphasissemanticThe boundary of a surface carrying attention or urgent, where the boundary is one of the three non-colour carriers of the status.2pxsamedisclaimer-note, field, surface
--opsin-border-focussemanticThe focus ring. Always 2px with a 2px offset, always in a colour measured against both the surface and the page behind it, and never removed. See /docs/accessibility/keyboard-and-focus.2pxsameaccordion, body-map, button, card, checkbox, combobox, consent-sheet, link, menu, number-field, popover, questionnaire, radio-group, scale-input, scroll-area, segmented-control, select, slider, switch, symptom-picker, tab-bar, table, tabs, term, textarea, toast, tooltip
--opsin-border-focus-offsetsemanticOffset for the focus boundary.2pxsameaccordion, body-map, button, card, checkbox, combobox, consent-sheet, link, menu, number-field, popover, questionnaire, radio-group, scale-input, scroll-area, segmented-control, select, slider, switch, symptom-picker, tab-bar, table, tabs, term, textarea, toast, tooltip