Fluent Flex · Chapter 04
Styling
Corner radius, elevation, and stroke — three families with three different internal logics. Radius is algorithmic and tied to component size. Elevation is ordinal because position on the scale matters more than the math between steps. Stroke has explicit role mapping.
11 → 7
Corner radius tokens — irregular progression replaced by 4px base × multiplier
4 → 3
Stroke width tokens — Thickest eliminated, focus ring pattern formally documented
6
Elevation levels — ordinal (lowest → highest), not mathematical
Overview
Three Families, Three Models
The Styling chapter covers three token families that each required a different internal logic. The governing principle from the Flex hub applies here: the naming convention for each family should match how that value is actually reasoned about by a designer.
For corner radius, the math matters — radius should scale with component size, and the relationship between nesting levels should be derivable. For elevation, position on the scale is what matters — whether something is above or below something else — not the specific shadow values between levels. For stroke, intent is what matters — whether a border signals interaction, focus, or decoration is more important than whether it's 1px or 2px.
Family 01
Corner Radius — Algorithmic
V9 had 11 corner radius tokens — borderRadiusNone (0) through
borderRadiusCircular (10000px) — with 9 steps in between ranging from
2px to 40px. The progression wasn't consistent: steps were +2 at the small end, then
+4, then +8. No formula connected them. Adding a new step required a judgment call,
not a derivation.
V9 — Before
Pure size naming (Small, Medium, Large through 6XLarge) — no encoding of component role or nesting. Steps were +2, +4, then +8 — not a consistent ratio. No rule for which components belonged to which radius.
- Values: 2, 4, 6, 8, 12, 16, 24, 32, 40px + none + circular (10000px)
- No nesting rules — any component could use any step
- AI couldn't infer correct radius from component context
Fluent Flex — After
Each step is a clear multiple of the 4px base unit. Nesting rules encoded in the system: parent containers always use a larger radius than their nested children (staircase principle).
- Values: 4 (1×), 8 (2×), 12 (3×), 16 (4×), 24 (6×), 28 (7×), circular (9999px)
- Staircase nesting rule documented — not just a style guide suggestion
- Component size category → radius step is now inferable
The staircase principle
A parent container must always use a larger radius than its nested child. A card with rounded corners contains a button with tighter corners; a dialog with large radius contains inputs with smaller radius. This is encoded in the system documentation — not as a suggestion, but as a structural rule.
The before/after is immediately visible: Default Fluent theme uses radiusSmall=2px, Medium=4px, Large=6px, XLarge=8px. Copilot theme uses radiusSmall=6px, Medium=8px, Large=12px, XLarge=16px — the same components, rounder. The theme switch is a scale multiplier, not a redesign.
"Karlee does an exceptional job at making the extremely ambiguous un-ambiguous. She always looks at a problem and sees how that impacts the system as a whole, building future-proof solutions — whether it be type, corner radii, colours, you name it."
Family 02
Stroke Width — Role-Mapped
V9 had 4 stroke width tokens: Thin, Thick, Thicker, Thickest. Comparative naming without a stated reference point — thick compared to what? Thicker by how much? The names communicate order but not system logic.
Without a governing scale, each component's border weight was a judgment call. The same "Thin" token appeared on interactive borders, dividers, and focus rings — three semantically different uses with no naming distinction between them.
V9 — Before
Thin, Thick, Thicker, Thickest — no explicit pixel values, no role mapping. Any token could appear on any surface with no structural signal about appropriateness.
- No role mapping: interactive borders, dividers, and focus rings shared tokens
- No explicit values — comparative only
- Adding a component required a judgment call on every stroke
Fluent Flex — After
Thin (1px), Thick (2px), Thicker (3px). Thickest eliminated. Focus ring pattern formally documented: outer ring = thick (2px), inner ring = thin (1px). The two-layer pattern is baked into the system spec.
- Thin (1px) — dividers, subtle borders, inner focus ring
- Thick (2px) — interactive borders, outer focus ring, emphasis
- Thicker (3px) — strong emphasis, selected state indicators
Focus ring accessibility
The two-layer focus ring pattern — outer ring at thick (2px), inner ring at thin (1px) — creates two-tone contrast between the focus indicator and whatever surface it appears on. This pattern is now formally specified in the system doc, making the accessibility intent explicit in the naming and structure rather than left to per-component interpretation.
Family 03
Elevation — Ordinal
Elevation uses six levels with ordinal naming: lowest through highest. The naming convention here is intentionally different from corner radius — because what matters for elevation isn't the math between steps (the exact shadow values), it's position on the scale. Whether a surface is above or below another surface is the decision; the specific box-shadow values are an implementation detail.
This is the Flex principle applied specifically: the naming convention should match how the value is actually reasoned about. Designers think in terms of layer order ("this panel floats above the content"), not in terms of shadow blur radii. Ordinal names encode the design intent. Mathematical names would encode implementation.
Under the hood
Shadow Layer Composition
Each elevation level is a composite of up to three rendering layers, emitted as a
comma-joined box-shadow value. Every level has a contour and a key;
ambient is added from Low upward because the two shallowest tiers are too slight to
displace the surrounding scene.
One intentional detail: highest reuses higher's ambient
geometry — only the key layer grows between those two. The single shadow color anchor
(--gnrc-color-shadow, pure black) means overriding it once retints every
shadow in the system.
Corner radius
Valid Nesting Pairs
The staircase principle is formally documented as a nesting table, not just a style guide suggestion. Parent containers must always use a larger radius than their nested children — these are the valid pairings:
base-300 (12px) base-100 (4px), base-200 (8px) base-400 (16px) base-100, base-200, base-300 base-600 (24px) base-100, base-200, base-300, base-400 base-700 (28px) base-100, base-200, base-300, base-400, base-600 Looking ahead
What's Next
- Corner radius tokens feed directly into AI-generated component specs — a model can infer correct radius from component size category without bespoke decisions for each new component.
- The staircase nesting principle is encodable as a constraint in the schema layer — AI tools consuming the token system can detect nesting violations before they ship.
- Elevation ordinal names are directly AI-inferable: 'this is a dialog' maps to 'high' without requiring a lookup of the specific box-shadow values.
- As the component library expands, all three styling families hold without manual additions — the math and the role mapping do the work.