> **R015 follow-up:** a local shared action/badge checkpoint is implemented. The source audit below remains evidence; [current usage and deliberate differences](actions-usage.md) describe the proposed standard. Shared geometry/colors still require M4 visual acceptance.

# M4 — actual wizard buttons and badge audit

R014 establishes a measured baseline; shared action CSS is not implemented in this run. M3 field tokens and behavior are unchanged.

[Actual control gallery](reference/wizard-actions.html) · [Browser measurements](reference/buttons/wizard-actions.json). Reference commit eab1a9a72ea8ca036be292420b8e5c95f19fd7f7. Measurements cover light/dark at 1200px and 390px. Default, hover, programmatic focus and held-pointer active states were measured; disabled Back/Next were measured separately. Apply, Export, Import and file/template actions were not invoked. Zero attempted non-GET requests and zero page exceptions were recorded. Navigation and form changes existed only in the local browser session.

## Imports and actual implementation

ConfigWizard imports Lucide icons and native step components. Its toolbar/navigation actions are inline native buttons; they do not import ui/button.tsx. DevicesStep imports AddDeviceModal and renders inline edit/remove/add buttons; ReviewStep renders inline export buttons and passive count spans. NetworkTestPanel owns Apply and loading/result panels. Therefore the shared CVA files are comparison sources, not the wizard baseline.

- [ConfigWizard toolbar/navigation](https://github.com/SebastianTamayo/Wsdmmcentral/blob/eab1a9a72ea8ca036be292420b8e5c95f19fd7f7/src/app/components/ConfigWizard.tsx#L559)
- [Device type badge and edit/remove actions](https://github.com/SebastianTamayo/Wsdmmcentral/blob/eab1a9a72ea8ca036be292420b8e5c95f19fd7f7/src/app/components/wizard-steps/DevicesStep.tsx#L140)
- [Dashed add-device action](https://github.com/SebastianTamayo/Wsdmmcentral/blob/eab1a9a72ea8ca036be292420b8e5c95f19fd7f7/src/app/components/wizard-steps/DevicesStep.tsx#L194)
- [Review passive count pill](https://github.com/SebastianTamayo/Wsdmmcentral/blob/eab1a9a72ea8ca036be292420b8e5c95f19fd7f7/src/app/components/wizard-steps/ReviewStep.tsx#L262)
- [Apply and loading state implementation](https://github.com/SebastianTamayo/Wsdmmcentral/blob/eab1a9a72ea8ca036be292420b8e5c95f19fd7f7/src/app/components/NetworkTestPanel.tsx#L1)
- [Generic CVA button](https://github.com/SebastianTamayo/Wsdmmcentral/blob/eab1a9a72ea8ca036be292420b8e5c95f19fd7f7/src/app/components/ui/button.tsx#L10) / [badge](https://github.com/SebastianTamayo/Wsdmmcentral/blob/eab1a9a72ea8ca036be292420b8e5c95f19fd7f7/src/app/components/ui/badge.tsx#L7) — different sizes/radius/variants, not imported by these wizard controls.

## Measured variants

| Role | Desktop (1200px) | Mobile (390px) | State/source notes |
|---|---|---|---|
| Import / Load Template | 42px high, radius 14px, padding 10px/16px, label 14px/500 | 34px high, radius 10px, padding 8px/12px; text hidden | Icons 16px; light blue-tinted fill, dark white/10 → white/20 on hover |
| Next / Back / Export | 50px high, radius 14px, padding 12px/24px, visible label 16px/500 | Next/Back 42px high, radius 10px, padding 10px/16px, label 14px/500; Export hidden | Source button font itself is 14px; nested span sets desktop label size. Do not measure only the parent. |
| Add New Device | 57px high, radius 14px, padding 16px/0, 2px dashed contour, label 14px/500 | Same height/radius | Lucide Plus 20px; hover changes border/fill/text |
| Apply Configuration | 51px high, radius 14px, padding 14px/24px, label 14px/500 | Same height/radius | Lucide Zap 20px; not the same geometry as Next |
| Devices-step count | 38px high, radius 10px, padding 8px/16px, text 14px/400 | Same | Passive div, no click/pressed state |
| Review count | 28px high, pill radius, padding 4px/12px, text 14px/400 | Same | Passive span, blue status/count treatment |

Chromium confirms actual custom Noto Sans glyph rendering for the visible desktop Import label. The mobile label is hidden and has no rendered glyphs. [Keyboard/font observations](reference/buttons/wizard-keyboard.json) confirm a real Tab focus-visible state with a browser-auto 2px outline; its contrast is not established by this audit. General icon stroke is 2. Source light primary fill is the #004a8f → #005a9c gradient with white text; hover uses those colors at 90%. Dark primary uses the same gradient stops at 40% → 60% opacity and a #4a9fd8/30 contour. Secondary navigation uses white/light and white/10 dark with source gray-300/white-30 contours. Exact CSS color models and hover values are retained in raw evidence.

## Conflicts and gaps to resolve in the standard

1. The company image specifies bold 14.4px button labels. Actual wizard roles use weight 500 and 14px/16px responsive labels. Prefer verified wizard roles for this baseline; record the guide discrepancy rather than globally imposing its label scale.
2. The original control skill prescribes dark primary #1f6fcb/#2e80db and broad radius/typography rules. The actual wizard uses translucent #004a8f/#005a9c gradients and multiple geometries. Those skill claims cannot override this evidence. See the prior skill audit; company corporate #00457e is a separate anchor, not the rendered wizard action gradient.
3. Generic shared button/badge CVA variants differ from actual wizard controls. Do not migrate source components or assume generic .dark variants represent the context-driven wizard theme.
4. Mobile toolbar labels are display:none, with no aria-label/title on those buttons in the measured markup. Chromium’s accessibility tree confirms Import has an empty accessible name at 390px (desktop name is “Import”). Preserve accessible names in the standard even when visible text is hidden. A minimum touch-target policy should be deliberate: the source toolbar is only 34px tall on mobile.
5. Most measured programmatic-focus/held-active styles do not add a distinct visual treatment. Real keyboard focus is checked separately; do not infer keyboard visibility solely from .focus(). Use an explicit focus-visible style in the standard and verify contrast against actual surfaces.
6. Back uses disabled opacity; Next uses a separate disabled palette. Consolidate a coherent disabled contract without copying hover effects onto inactive controls. Loading/result handling is source-inspected in NetworkTestPanel, not triggered or live-verified in this run.
7. Device/review counts are passive badges, not interactive chips. Type badges exist in source but were not live-rendered because the browser session had no devices. Template type badges are source-only here too. No selectable/dismissible chip was established in the inspected wizard controls; any such example must be an explicit standard extension with native button semantics and aria-pressed where appropriate.
8. The Add Device dashed action is a special container action, not a universal primary button. Do not apply its 57px height/dashed border to ordinary actions.

## Proposed shared layer and next bounded implementation

- Add opt-in action styles alongside fields.css; importing theme.css continues to emit only scoped variables. Keep Sass as the editable source.
- Define semantic primary, secondary, toolbar, destructive/icon and add-row roles, plus passive count/type badges. Preserve source-responsive navigation and toolbar geometry; keep Apply's larger icon/vertical padding explicit.
- Proposed tokens: button radius by size, block/inline padding, label size/weight, icon size/gap; action primary fill/hover/text/border; secondary and toolbar equivalents; focus ring; disabled fill/text/border; badge neutral/accent/status fill/text/border. Do not treat all existing source values as global tokens before reviewing their purpose.
- Use native button type=button unless submitting. Keep links for navigation. Define keyboard focus-visible with the accepted theme focus colors as a starting candidate; measure contrast before declaring readiness. Active treatment should be distinct but restrained; reduced-motion and forced-colors fallback remain required.
- Retain accessible action names when icons stand alone. Passive badge text stays outside the tab order; selectable chips, if introduced, get a separate interaction contract. Do not attach fake click handlers to passive spans.
- Build a local functional action reference using existing typography/theme surfaces and Lucide assets. Use harmless local demonstrations for pressed/loading states, not application backend actions. Compare source and standard in both themes before completing M4.

This run changes documentation/evidence only. Buttons/chips are not yet implemented or approved; cards/shadows, broad palette changes, source-app edits and publishing remain outside the run.
