# Canvas Kit 16.0 Upgrade Guide

This guide contains an overview of the changes in Canvas Kit v16. Please
[reach out](https://github.com/Workday/canvas-kit/issues/new?labels=bug&template=bug.md) if you have
any questions.

## Why You Should Upgrade

Canvas Kit v16 is a 1:1 component update that aligns every Canvas component to Sana's visual
styling. Components ship that styling regardless of theme — you do not need to opt into the Sana
Canvas theme for components to look correct.

The Sana Canvas **theme** (CSS variables + `data-theme="sana-canvas"`) is a separate, opt-in step
that updates brand colors, neutrals, surfaces, and shapes at the application level. See
[Sana Canvas Theme](#sana-canvas-theme) below.

### What You Need
- Canvas Tokens v4.4.0: Introduces the new Sana Canvas variables.
- Canvas System Icons v5.0.0: Introduces the new Sana Canvas icons.
- Canvas Kit v16: The new version of Canvas Kit that includes the new Sana Canvas components and utilities.

> **Note:** Canvas Tokens and Canvas System Icons are not included in the Canvas Kit package. Install
> them separately, then upgrade Canvas Kit itself:

```sh
# Separate packages required by Canvas Kit v16
yarn add @workday/canvas-tokens-web@4.4.0 @workday/canvas-system-icons-web@5.0.0

# Upgrade Canvas Kit packages (adjust package names to what your app uses)
yarn add @workday/canvas-kit-react@^16
```

## Sana Canvas Theme

Your application is Sana-aligned out of the box when the Sana Canvas theme is applied. To opt in —
brand neutrals, surfaces, and shapes — import the Sana CSS variables and set
`data-theme="sana-canvas"` on `<html>`.

> **Note:** All visual updates in this guide apply to both the Default Canvas theme and the Sana
> Canvas theme unless specified otherwise.

### Opting In

Import the Sana variables **last** in your root CSS entry point. Sana's `[data-theme="sana-canvas"]`
selector and `:root` have equal specificity — source order determines the winner.

```css
/* index.css — order matters */
@import '@workday/canvas-tokens-web/css/base/_variables.css';
@import '@workday/canvas-tokens-web/css/brand/_variables.css';
@import '@workday/canvas-tokens-web/css/component/_variables.css';
@import '@workday/canvas-tokens-web/css/system/_variables.css';
/* Sana last: [data-theme="sana-canvas"] and :root have equal specificity (0,1,0),
   so when both match <html> the cascade falls back to source order. */
@import '@workday/canvas-tokens-web/css/sana/_variables.css';
```

Set `data-theme="sana-canvas"` on `<html>` when you control the document root (preferred). Nested
elements are not enough for portaled popups (including all Canvas Kit popups such as menus,
selects, modals, and toasts) — those render under `document.body` via React portals, outside the
parent component's DOM hierarchy, and only inherit theme from `<html>`, or from
`sanaCanvasProviderTheme` on `CanvasProvider` when `<html>` is unavailable.

```html
<html lang="en" data-theme="sana-canvas"></html>
```

> **Gotcha:** There is no `[data-theme="canvas"]` rule. The sana file only defines
> `[data-theme="sana-canvas"]` overrides, so removing the attribute is how you get classic Canvas —
> there's nothing to undo it with.

### What Changes When You Opt In

Things that change are primary brand consumers and Sana's neutral color scale
(`--cnvs-brand-neutral-*`, which replaces classic slate neutrals). Verified against
`@workday/canvas-tokens-web/css/sana/_variables.css`:

- **Brand primary consumers flip.** `--cnvs-sys-color-brand-accent-primary` and `-accent-action`
  re-point from blue to `--cnvs-brand-neutral-975`, and `-brand-fg-primary-default/-strong` to
  `--cnvs-brand-neutral-a900/-a950`. `PrimaryButton`, brand links, and selected states are what
  visibly change.
- **Focus does not.** `--cnvs-sys-color-brand-focus-primary` and `-border-primary` stay `blue-500`.
- **`--cnvs-brand-primary-600` is intentionally _not_ redefined** — it stays the consumer's brand
  hook.
- **The full neutral color scale is replaced** (`--cnvs-brand-neutral-*`, all steps plus alphas),
  plus selected `critical`, `caution`, `positive`, shapes (`sm`, `xs`, `xxl`, `xxxl`),
  surfaces/overlays, and chart ramps.

### Scoped Theming

The `CanvasProvider` theming updates in
[#4060](https://github.com/Workday/canvas-kit/pull/4060) are for **scoped** use cases — embedding
Canvas in another brand, multi-tenant sections, and popup parity when you cannot set
`data-theme="sana-canvas"` on `<html>`. Application teams that control `<html>` and import the
Sana variables globally do not need a `theme` prop for app-wide Sana.

For the scoped theming API, see our
[Theming documentation](https://workday.github.io/canvas-kit/?path=/docs/features-theming-overview--docs).

#### Default Scope Change for Legacy Themes

**Important:** If you previously used `canvas.palette.<color>.main` only (without other palette properties)
to scope-theme your application, the default behavior has changed. In v16:

- **Before v16:** Setting only `palette.primary.main` would automatically generate a full color ramp
  (lightest, lighter, light, dark, darkest, contrast) and apply broad `system.color.brand.*` forwarding.
- **In v16:** Setting only `palette.primary.main` defaults to `'brand'` scope, which applies a narrower
  set of variables (PrimaryButton and selected states only).

To restore the previous behavior, explicitly set `themeScope: 'full'`:

```jsx
// v15 behavior (implicit full scope)
<CanvasProvider theme={{canvas: {palette: {primary: {main: '#FF00FF'}}}}} />

// v16 - to get the same behavior as v15
<CanvasProvider
  theme={{canvas: {palette: {primary: {main: '#FF00FF'}}}}}
  themeScope="full"
/>
```

This change provides more control over theming scope and prevents unintended overrides, but teams
relying on the auto-generated color ramp need to explicitly opt into `'full'` scope.

### Simplified Sana Canvas Setup

If you can set `data-theme="sana-canvas"` on `<html>`, you no longer need to pass
`sanaCanvasProviderTheme` to CanvasProvider. Popups are called out specifically because Canvas Kit
renders them through React portals under `document.body` — outside the parent component's DOM
hierarchy — so they inherit CSS variables from `<html>`, not from a nested wrapper.

**Before:**
```tsx
import {CanvasProvider, sanaCanvasProviderTheme} from '@workday/canvas-kit-react/common';

<CanvasProvider theme={sanaCanvasProviderTheme}>
  <App />
</CanvasProvider>
```

**After (when you control `<html>`):**
```tsx
import {CanvasProvider} from '@workday/canvas-kit-react/common';

// <html data-theme="sana-canvas">
<CanvasProvider>
  <App />
</CanvasProvider>
```

**Still required — cannot set `data-theme` on `<html>`:** embedded apps, microfrontends, and
third-party shells often cannot set attributes on the document root. Nested `data-theme` does not
reach portaled popups (including all Canvas Kit popups such as menus, selects, modals, and toasts).
Pass both `data-theme="sana-canvas"` (in-tree UI) and `sanaCanvasProviderTheme` (popup forwarding):

```tsx
import {CanvasProvider, sanaCanvasProviderTheme} from '@workday/canvas-kit-react/common';

<CanvasProvider theme={sanaCanvasProviderTheme} data-theme="sana-canvas">
  <App />
</CanvasProvider>
```

If you control `<html>` and see a console warning about unnecessary theme usage, you can safely
remove the theme prop.

## Table of Contents

- [Sana Canvas Theme](#sana-canvas-theme)
  - [Opting In](#opting-in)
  - [What Changes When You Opt In](#what-changes-when-you-opt-in)
  - [Scoped Theming](#scoped-theming)
  - [Simplified Sana Canvas Setup](#simplified-sana-canvas-setup)
- [Codemod](#codemod)
  - [Instructions](#instructions)
  - [Codemod Transformations for Icons](#codemod-transformations-for-icons)
- [MCP](#mcp)
  - [Icon migration — `get-canvas-kit-icon-migration`](#icon-migration--get-canvas-kit-icon-migration)
  - [Token references — `get-canvas-kit-tokens`](#token-references--get-canvas-kit-tokens)
- [New Components](#new-components)
  - [KBD](#kbd)
  - [Tabs](#tabs)
- [Component Updates](#component-updates)
  - [Action Bar](#action-bar)
  - [Buttons](#buttons)
    - [Delete Button Outline Variant](#delete-button-outline-variant)
    - [Secondary Button](#secondary-button)
  - [Container Components](#container-components)
    - [Card](#card)
    - [Expandable](#expandable)
    - [Side Panel](#side-panel)
    - [Table](#table)
  - [Indicators](#indicators)
    - [Avatar](#avatar)
    - [Banner](#banner)
    - [Count Badge](#count-badge)
    - [Information Highlight](#information-highlight)
    - [Pill](#pill)
    - [Skeleton](#skeleton)
    - [Status Indicator](#status-indicator)
  - [Inputs](#inputs)
    - [Accessibility: Checked-State Contrast](#accessibility-checked-state-contrast)
    - [Checkbox](#checkbox)
    - [Color Input](#color-input)
    - [Color Picker](#color-picker)
    - [Form Field](#form-field)
    - [Radio](#radio)
    - [Switch](#switch)
    - [Text Area](#text-area)
    - [Text Input](#text-input)
    - [Select](#select)
    - [MultiSelect](#multiselect)
  - [Popups](#popups)
    - [Menu](#menu)
    - [Modal](#modal)
    - [Popup](#popup)
    - [Toast](#toast)
    - [Tooltip](#tooltip)
  - [Navigation Components](#navigation-components)
    - [Hyperlink](#hyperlink)
    - [Breadcrumbs](#breadcrumbs)
    - [Pagination](#pagination)
  - [Segmented Control](#segmented-control)
- [New Utilities](#new-utilities)
  - [cornerShapeStencil](#cornershapestencil)
- [Fonts](#fonts)
  - [Sana Canvas Theme — Switch to Sana Sans](#sana-canvas-theme--switch-to-sana-sans)
  - [Classic Canvas — Keep Roboto](#classic-canvas--keep-roboto)
- [Deprecations](#deprecations)
- [Glossary](#glossary)
  - [Main](#main)
  - [Preview](#preview)
  - [Labs](#labs)

## Codemod

We've provided a [codemod](https://github.com/Workday/canvas-kit/tree/master/modules/codemod) to
automatically update your code to work with most of the breaking changes in v16. **Breaking changes
handled by the codemod are marked with 🤖 in the Upgrade Guide.**

A codemod is a script that makes programmatic transformations on your codebase by traversing the
AST, identifying patterns, and making prescribed changes. This greatly decreases opportunities for
error and reduces the number of manual updates, which allows you to focus on changes that need your
attention. **We highly recommend you use the codemod for these reasons.**

If you're new to running codemods or if it's been a minute since you've used one, there are a few
things you'll want to keep in mind.

- Our codemods are meant to be run sequentially. For example, if you're using v14 of Canvas Kit,
  you'll need to run the v15 codemod before you run v16.
- The codemod will update your code to be compatible with the specified version, but it will **not**
  remove outdated dependencies or upgrade dependencies to the latest version. You'll need to upgrade
  dependencies on your own.
  - We recommend upgrading dependencies before running the codemod.
  - Always review your `package.json` files to make sure your dependency versions look correct.
- The codemod will not handle every breaking change in v16. You will likely need to make some manual
  changes to be compatible. Use our Upgrade Guide as a checklist.
- Codemods are not bulletproof.
  - Conduct a thorough PR and QA review of all changes to ensure no regressions were introduced.
  - As a safety precaution, we recommend committing the changes from the codemod as a single
    isolated commit (separate from other changes) so you can roll back more easily if necessary.

We're here to help! Automatic changes to your codebase can feel scary. You can always reach out to
our team. We'd be very happy to walk you through the process to set you up for success.

### Instructions

The easiest way to run our codemod is to use `npx` in your terminal.

```sh
npx @workday/canvas-kit-codemod v16 [path]
```

Be sure to provide specific directories that need to be updated via the `[path]` argument. This
decreases the amount of AST the codemod needs to traverse and reduces the chances of the script
having an error. For example, if your source code lives in `src/`, use `src/` as your `[path]`. Or,
if you have a monorepo with three packages using Canvas Kit, provide those specific packages as your
`[path]`.

Alternatively, if you're unable to run the codemod successfully using `npx`, you can install the
codemod package as a dev dependency, run it with `yarn`, and then remove the package after you're
finished.

```sh
yarn add @workday/canvas-kit-codemod --dev
yarn canvas-kit-codemod v16 [path]
yarn remove @workday/canvas-kit-codemod
```

> **Note:** The codemod only works on `.js`, `.jsx`, `.ts`, and `.tsx` files. You'll need to
> manually edit other file types (`.json`, `.mdx`, `.md`, etc.). You may need to run your linter
> after executing the codemod, as its resulting formatting (spacing, quotes, etc.) may not match
> your project conventions.

## Codemod Transformations for v16

The following automated transformations are available for upgrading to v16:

- **Update Hyperlink Props**: updateHyperlinkProps

Run the codemod with: `npx @workday/canvas-kit-codemod v16 [path]`

### Codemod Transformations for Icons

#### Icon Migration Codemod

For v16, there is a **separate codemod** called `icon-migration` that updates
`@workday/canvas-system-icons-web` usage across your codebase. Upgrade the icon package to v5 before
you run it so deprecation and fallback mappings match what the transform expects.

```sh
yarn add @workday/canvas-system-icons-web@^5
```

The codemod reads `system.deprecated.metadata.json` from the installed icon package and rewrites
each deprecated export to its fallback icon. This codemod will:

- Update **named imports** and their references (for example, `uploadIcon` to `arrowUpToLineIcon`).
- Preserve **import aliases** and point them at the fallback export.
- Update **namespace imports** member access (for example, `systemIcons.uploadIcon` to
  `systemIcons.arrowUpToLineIcon`).
- Resolve **chained fallbacks** when a fallback icon is itself deprecated.
- Remove **duplicate imports** when the fallback is already imported in the same declaration.

Because it applies every mapping in the metadata file, a single run covers both the v4 naming
convention migrations and the v5 Sana Canvas Assets renames and deprecations. Icons that are not
deprecated are left unchanged.

To run the codemod:

```sh
npx @workday/canvas-kit-codemod icon-migration [path]
```

> **Tip:** Provide the specific directory or directories you want to update as `[path]` to speed up
> migration.
>
> This codemod only touches `@workday/canvas-system-icons-web`. For accent, applet, and expressive
> icons, use the `v15-icons` transform covered in the
> [v15 upgrade guide](/docs/guides-upgrade-guides-v15-0-overview--docs#codemod-transformations-for-icons).
> For details on what changed in v5 and the full list of deprecated icons, see the
> [Sana Canvas Assets overview](/docs/guides-icon-migration-sana-canvas-assets-overview--docs) and
> the [Icon Migration codemod guide](/docs/guides-icon-migration-codemod--docs).

> **Note:** 🤖 The `icon-migration` codemod automates the majority of system icon migration work,
> but _always_ review the PR for any remaining icons the codemod could not address, especially
> dynamic icon selection, non-code assets, and heavily customized usages.

## New Components

### KBD

**PR:** [#4001](https://github.com/Workday/canvas-kit/pull/4001)

The new `KBD` component allows you to display keyboard inputs in your UI using accessible, visually
consistent keyboard key representations. This is useful for documenting keyboard shortcuts,
instructional prompts, or any UI patterns that reference specific keys.

**Highlights:**

- Provides a semantic (`kbd` element) way to visually present keyboard keys and shortcuts to users.
- Supports various variants (`default` for prominence, `plain` for use on colored surfaces), as well
  as size options (`small`, `medium`, `large`).
- Easy to use nested `KBD.Item` components for sequences or combinations.
- RTL support.

**Example:**

```tsx
import {KBD} from '@workday/canvas-kit-labs-react';

<KBD>
  <KBD.Item aria-label="Command">⌘</KBD.Item>
  <KBD.Item>C</KBD.Item>
</KBD>;
```

For more details and advanced usage, including accessibility guidance for symbolic keys and
functional shortcuts, refer to the storybook documentation and our example stories.

### Tabs

**PR:** [#4062](https://github.com/Workday/canvas-kit/pull/4062)

A new `Tabs` component has been added to `@workday/canvas-kit-preview-react`, aligned with the Sana
Canvas visual language. It supports `filled` and `outlined` variants.

```tsx
import {Tabs} from '@workday/canvas-kit-preview-react/tabs';

<Tabs>
  <Tabs.List>
    <Tabs.Item>First Tab</Tabs.Item>
    <Tabs.Item>Second Tab</Tabs.Item>
  </Tabs.List>
  <Tabs.Panels>
    <Tabs.Panel>Contents of First Tab</Tabs.Panel>
    <Tabs.Panel>Contents of Second Tab</Tabs.Panel>
  </Tabs.Panels>
</Tabs>;
```

## MCP

Canvas Kit's MCP server (`@workday/canvas-kit-mcp`) helps agents migrate icons and look up tokens for
v16 / tokens `4.4.0`.

### Icon migration — `get-canvas-kit-icon-migration`

Use this tool when upgrading `@workday/canvas-system-icons-web` to v5 (Sana Canvas Assets), finding
replacements for deprecated icons, or running the `icon-migration` codemod.

1. Install / enable the Canvas Kit MCP server (see the
   [MCP docs](/docs/ai-for-llms-mcp-docs--docs)).
2. Ask your agent to call `get-canvas-kit-icon-migration`.
3. Follow the returned guides:
   - [Sana Canvas Assets overview](/docs/guides-icon-migration-sana-canvas-assets-overview--docs)
     (full deprecated → replacement table)
   - [Icon Migration codemod](/docs/guides-icon-migration-codemod--docs)

```sh
npx @workday/canvas-kit-codemod icon-migration [path]
```

### Token references — `get-canvas-kit-tokens`

Token docs were updated for `@workday/canvas-tokens-web` `4.4.0`. Call `get-canvas-kit-tokens` and
start with the v4.4 token reference served by the MCP (`docs://tokens/v4/v4.4-token-reference`) for
the current token surface (Sana Canvas, t-shirt scales, deprecations).

## Component Updates

### Action Bar

**PR:** [#4048](https://github.com/Workday/canvas-kit/pull/4048)

#### Visual Updates

- `ActionBar` padding has been updated to `padding.md` (16px).

### Buttons

**PR:** [#4000](https://github.com/Workday/canvas-kit/pull/4000)

All buttons have had the following updates:

- `fontWeight` has been updated from `system.fontWeight.bold` to `system.fontWeight.medium`.
- `minWidth` has been updated to the following:

| Default Size | minWidth v15 | minWidth v16 |
| ------------ | ------------ | ------------ |
| extraSmall   | unchanged    | unchanged    |
| small        | `5rem`       | `4.5rem`     |
| medium       | `6rem`       | `5.5rem`     |
| large        | `7rem`       | `6.5rem`     |

- `paddingInline` has been updated to the following:

| Size       | paddingInline v15 | paddingInline v16 |
| ---------- | ----------------- | ----------------- |
| extraSmall | `0.75rem`         | `0.5rem`          |
| small      | `1rem`            | `0.75rem`         |
| medium     | `1.5rem`          | `1rem`            |
| large      | `2rem`            | `1.25rem`         |

#### Delete Button Outline Variant

We've added an `outline` variant to the `DeleteButton` component. This variant will reverse the
button's styling with a `border` and `transparent` background.

```tsx
import {DeleteButton} from '@workday/canvas-kit-react/button';

<DeleteButton variant="outline">Delete</DeleteButton>;
```

#### Secondary Button

`SecondaryButton` now has a `transparent` `backgroundColor` and will not show on interactive states.
The interactive states will now show on the `border`.

### Container Components

**PR:** [#4088](https://github.com/Workday/canvas-kit/pull/4088)

#### Alt Variant Support

Several container components now support an `alt` variant that provides an elevated surface
appearance:

- `Menu.Card` - Can use `variant="alt"` for elevated menu styling
- `Dialog.Card` - Can use `variant="alt"` for elevated dialog styling
- `Popup.Card` - Can use `variant="alt"` for elevated popup styling
- `Toast` - Can use `variant="alt"` for elevated toast styling
- `Tooltip` - Can use `variant="alt"` for elevated tooltip styling

The `alt` variant uses `system.sana.color.surface.elevated` background with inverse borders,
providing visual hierarchy and depth to these components when placed on an alt background.

```tsx
// Examples of using the alt variant
<Menu.Card variant="alt">
  <Menu.List>...</Menu.List>
</Menu.Card>

<Dialog.Card variant="alt">
  <Dialog.Heading>Dialog Title</Dialog.Heading>
  <Dialog.Body>Content</Dialog.Body>
</Dialog.Card>

<Toast variant="alt">
  <Toast.Body>
    <Toast.Message>Notification message</Toast.Message>
  </Toast.Body>
</Toast>
```

#### Card

**PR:** [#4014](https://github.com/Workday/canvas-kit/pull/4014),
[#4088](https://github.com/Workday/canvas-kit/pull/4088)

##### Variant Changes

The `Card` component's variants have been updated:

- **Removed:** The `borderless` variant has been removed and replaced with `alt`
- **New:** The `alt` variant provides an elevated surface with inverse borders
- **Updated:** The default variant now has a visible border
- The `tonal` variant now uses a `system.legacy.color.surface.alt.strong` background.

**Note:** If you were previously using `variant="borderless"`, you should use `variant="alt"`
instead. While the styles are different, both where intended to be used on an `alt` background.

🤖 The codemod will automatically update `variant="borderless"` to `variant="alt"`.

```tsx
// v15
<Card variant="borderless">
  <Card.Body>Content</Card.Body>
</Card>

// v16
<Card variant="alt">
  <Card.Body>Content</Card.Body>
</Card>
```

##### Visual Updates

- `Card.Heading` now defaults to `body.small` type level (previously `body.large`). If your design
  requires a larger heading, you can override the `typeLevel` prop on `Card.Heading`.
- The gap between `Card.Heading` and `Card.Body` has been reduced (previously `gap.lg`, now
  `padding.sm`).
- Card's border radius is now managed via the new `cornerShapeStencil` (see
  [New Utilities](#new-utilities)).
- The default variant now includes a visible border (`system.color.border.default`).
- The `alt` variant uses an elevated surface color (`system.sana.color.surface.elevated`) with
  inverse borders.

#### Expandable

##### Visual Updates

- `Expandable.Target` border radius changed from `shape.xxl` (24px, pill) to `shape.lg` (12px), now
  managed via `cornerShapeStencil` (see [New Utilities](#new-utilities)).
- Gap between `Expandable.Target` and `Expandable.Content` is now `gap.sm` (8px), set on the
  `Expandable` container (previously handled entirely via `Expandable.Content`'s top padding).
- `Expandable.Content` padding is now uniform `padding.xs` (8px) on all sides (previously
  `padding.md` top / `padding.xs` sides and bottom).

#### Side Panel

**PR:** [#4107](https://github.com/Workday/canvas-kit/pull/4107)

##### Breaking Changes

The `variant` prop on `SidePanel` no longer accepts `alternate`. It has been renamed to `overlay` to
describe what the variant is for — a panel that floats above page content — because a second
non-overlay variant now occupies the "alternative surface" role.

```tsx
import {SidePanel} from '@workday/canvas-kit-react/side-panel';

// Before
<SidePanel variant="alternate">{/* ... */}</SidePanel>

// After
<SidePanel variant="overlay">{/* ... */}</SidePanel>
```

> 🤖 The `v16` codemod will rename `variant="alternate"` to `variant="overlay"` as shown above. It
> only transforms `SidePanel` imported from `@workday/canvas-kit-react`; the deprecated `SidePanel`
> in `@workday/canvas-kit-preview-react` is left alone.

If you were using `alternate` for a panel that sits inline with page content rather than over it,
switch to the new `alternative` variant instead of `overlay` to avoid picking up the elevation
shadow.

##### New API

- `variant="alternative"` — uses a raised surface (`system.legacy.color.surface.raised`) with no
  depth. Use it for panels that need to stand out from the page background while remaining part of
  the page layout.

The full set of variants is now:

| Variant       | Surface                                  | Depth |
| ------------- | ---------------------------------------- | ----- |
| `standard`    | `system.legacy.color.surface.navigation` | None  |
| `alternative` | `system.legacy.color.surface.raised`     | None  |
| `overlay`     | `system.legacy.color.surface.default`    | 6     |

##### Visual Updates

- The `overlay` variant's box-shadow updated from `system.depth[3]` to `system.depth[6]`.
- `SidePanel.ToggleButton`'s default icon changed from `extendIcon` to `sidebarLeftIcon`. The icon
  no longer rotates as the panel expands and collapses: it keeps a single orientation in LTR and is
  mirrored horizontally in RTL.
- `SidePanel.ToggleButton`'s width changed from `gap.lg` (24px) to `size.md` (40px), and its top
  offset changed from `gap.lg` (24px) to `12px`.
- `SidePanel.Heading` padding changed from a symmetric `padding.xs` (8px) to `padding.sm` (12px)
  with a `paddingInlineStart` of `padding.md` (16px), and it now has a `minHeight` of `size.xxl`
  (64px) so the heading lines up with the toggle button and the collapsed panel width.
- `SidePanel.Heading` now lays out its children with flexbox and centers them vertically, so an icon
  passed alongside the heading text aligns without extra styling.

#### Table

##### Visual Updates

- `BaseTable` / `Table` outer border color updated from `system.legacy.color.border.strong` to
  `system.legacy.color.border.default`.
- `Table.Caption` divider (`borderBlockEnd`) updated from `system.legacy.color.border.strong` to
  `system.legacy.color.border.default`.
- Container corner radius is now **12px** (`shape.lg`, previously `shape.md` / 8px), managed via
  `cornerShapeStencil` (see [New Utilities](#new-utilities)).
- `Table.Header` (and `BaseTable.Header`) cell padding is now uniform `padding.md` (16px) on all
  sides (previously asymmetric `padding.xs` vertically and `padding.md` horizontally).
- Column header label text color is now `system.color.fg.strong` (previously inherited `fg.default`
  from the table container).

### Indicators

#### Avatar

**PR:** [#3981](https://github.com/Workday/canvas-kit/pull/3981)

We've updated `Avatar` color variants to align with Sana Canvas. These changes are **only visual** —
the component API is unchanged except for two new `variant` options.

##### Updated Variants

Existing variants use darker background colors and updated foreground colors for improved contrast:

| Variant  | Change                                                                                       |
| -------- | -------------------------------------------------------------------------------------------- |
| `blue`   | Background updated from `blue300` to `blue600`; text now uses `system.color.fg.inverse`      |
| `amber`  | Background updated from `amber200` to `amber300`; text updated from `amber700` to `amber800` |
| `purple` | Background updated from `purple300` to `purple600`; text now uses `system.color.fg.inverse`  |

The `teal` variant is unchanged.

##### New Variants

Two new color variants are available:

- `magenta` — `magenta600` background with `system.color.fg.inverse` text
- `green` — `green600` background with `system.color.fg.inverse` text

```tsx
import {Avatar} from '@workday/canvas-kit-react/avatar';

<Avatar name="Mary Jane" variant="magenta" />
<Avatar name="Green Arrow" variant="green" />
```

#### Banner

**PR:** [#4087](https://github.com/Workday/canvas-kit/pull/4087)

##### Visual Updates

- Font weight changed from `system.fontWeight.medium` to `system.fontWeight.bold`.
- Padding updated to `paddingInline` of `padding.sm`/`padding.md` (12px/16px) and `paddingBlock` of
  `10px` (previously a symmetric `padding.xs`/`padding.md`, 8px/16px).
- Border radius is now managed via the new `cornerShapeStencil` (see
  [New Utilities](#new-utilities)), using `shape.lg` (12px) instead of individual corner-radius
  properties set to `shape.sm` (4px).
- A box shadow (`system.depth[5]`) has been added to the container.
- The focus ring now uses `system.legacy.color.brand.border.primary` for its outer color.
- Hover background now uses `colorSpace.hover()` instead of `colorSpace.darken()`, making the hover
  direction theme-aware (lightens in the Sana Canvas theme, darkens in the default/legacy theme).
- The default `Banner.Icon` size has been reduced from `24px` to `20px`.

#### Count Badge

**PR:** [#4087](https://github.com/Workday/canvas-kit/pull/4087)

##### Visual Updates

- Typography now uses the `system.legacy.type.subtext.md` type preset (previously individually set
  `fontFamily`/`fontSize`/`lineHeight`/`letterSpacing`); `fontWeight` is now
  `system.fontWeight.medium` (previously `system.fontWeight.bold`).
- Horizontal padding changed from a hardcoded `6.5px` to `system.legacy.padding.xxs` (4px).
- Default background color changed from `system.legacy.color.accent.danger` to
  `system.legacy.color.brand.accent.primary`. This is a visual color change — the default badge is
  no longer red/danger-colored and now uses the brand primary accent color.
- The `inverse` variant's text color changed from `system.legacy.color.fg.info.strong` to
  `system.color.fg.strong`.

#### Information Highlight

**PR:** [#4087](https://github.com/Workday/canvas-kit/pull/4087)

##### Breaking Changes

- The default `variant` changed from `informational` to `default`. If you rely on the implicit
  default, add `variant="informational"` explicitly to preserve the previous appearance.

##### New API

- `variant="default"` — general-purpose variant with gray background (`surface.alt.default`), flat
  `layersIcon` (no colored circle), and icon color `system.color.fg.default`.
- `actionPlacement="bottom" | "end"` — `bottom` (default) stacks the link below heading/body; `end`
  visually places the link at the inline end beside content when the container is wide enough, and
  stacks it below the body when narrower. This only affects visual/grid placement. DOM order,
  keyboard tab order, and screen reader order remain unchanged (heading, body, then link).

##### Visual Updates

- The left accent border (`borderInlineStart`) has been removed.
- Border radius changed from `shape.sm` (4px) to `shape.xxl` (20px) via `cornerShapeStencil` (see
  [New Utilities](#new-utilities)).
- Icon-to-content horizontal gap changed from `gap.md` (16px) to **12px**.
- Vertical spacing between text blocks: **4px** between heading and body (`gap.xs`), **16px**
  between body and link (`gap.md`).
- The default `InformationHighlight.Icon` size has been reduced from `24px` to `20px` (`systemIcon`
  size `md`).
- `Heading` typography now uses `system.legacy.type.subtext.lg` with `fontWeight.medium` (previously
  `body.sm` scale with `fontWeight.bold`). Color changed from `fg.default` to `fg.strong`.
- `Body` typography consolidated to `system.legacy.type.subtext.lg` spread. Color changed from
  `fg.default` to `fg.muted.default`.
- `Link` typography consolidated to `system.legacy.type.subtext.lg` spread; `fontWeight.bold`
  override removed (weight is now regular).
- `Link` now uses the newly introduced `secondary` Hyperlink variant (see [Hyperlink](#hyperlink)).
- Background surface tokens per variant/emphasis are unchanged.

#### Pill

**PR:** [#4087](https://github.com/Workday/canvas-kit/pull/4087)

##### Visual Updates

- Typography now uses the `system.legacy.type.subtext.md` type preset (previously individually set
  `fontFamily`/`fontSize`/`lineHeight`/`letterSpacing`/`fontWeight`).
- Background color tier changed from `surface.alt.strong` to `surface.alt.default` (a lighter
  background) for the base, disabled state, and the disabled `Pill.Count` background. Hover/active
  states now mix `surface.overlay.mixin` into `surface.alt.default` at 3.92% (hover) and 7.45%
  (active) via `colorSpace.darken()`. In Sana, `surface.overlay.mixin` resolves to neutral black;
  mix percentages were recalibrated from the v15 defaults (8%/18%) for the lighter
  `surface.alt.default` base.
- Active state label color changed from `fg.strong` to `fg.stronger`, now matching the hover state.
- The `readOnly` variant now explicitly sets its label color to `fg.default` (previously inherited
  `fg.strong`).
- The disabled state now dims the whole container via `system.opacity.disabled` instead of using a
  distinct label color, matching the convention used by `PrimaryButton`/`DeleteButton`.
- `Pill.IconButton`'s default icon color changed from `fg.strong` to `fg.default`, and its disabled
  icon color changed from `fg.disabled` to `fg.strong`, matching the "dim via container opacity"
  convention above.
- `Pill.IconButton`'s close icon hit box shrunk from `size.xxs` (20px) to `size.xxxs` (16px), and
  the icon glyph itself shrunk from `systemIcon.size.sm` (18px) to `systemIcon.size.xs` (16px) to
  fill the smaller hit box exactly.
- `Pill.IconButton`'s border radius is now driven by `buttonStencil.vars.borderRadius` set to
  `shape.sm`, matching the Pill container's own corner radius (previously a hardcoded `2px`).
- `Pill.IconButton`'s focus indicator is no longer a separate `focusRing()` box-shadow. It's now a
  border drawn on the button's existing larger (invisible) hit-target overlay, so the ring appears
  flush with the ~24px click target instead of hugging the smaller 16px icon box. It uses
  `system.legacy.color.brand.border.primary`, matching the Pill container's own focus color.
- `Pill.Icon`'s glyph size shrunk from `systemIcon.size.sm` (18px) to `systemIcon.size.xs` (16px).

#### Skeleton

##### Visual Updates

- Default fill on `Skeleton.Header`, `Skeleton.Text`, and `Skeleton.Shape` changed from flat
  `surface.loading` to a two-stop shimmer gradient (`surface.alt.strong` → `surface.loading`,
  `to left`).
- `Skeleton.Header` border radius changed from `shape.md` (8px) to `shape.sm` (6px).
- `Skeleton.Text` line placeholder border radius changed from `shape.md` (8px) to `shape.xxxl`
  (28px), producing fully pill-shaped lines at the default 16px line height.
- `Skeleton.Shape` border radius remains consumer-configurable via the `borderRadius` prop or `cs`
  (default `0`); only the default fill changed.

The `backgroundColor` prop still accepts solid color overrides (for example via `cs`). The default
stencil uses the `background` CSS property for the gradient instead of `backgroundColor`.

- Placeholder shapes use a `1px` transparent border so boundaries remain visible in Windows High
  Contrast when gradient fills are suppressed (`border-color: CanvasText` under `forced-colors`).

#### Status Indicator

**PR:** [#4087](https://github.com/Workday/canvas-kit/pull/4087)

##### Visual Updates

- Container height increased from `size.xxs` (20px) to `size.xs` (24px).
- Border radius changed from `shape.sm` (4px) to `shape.md` (8px), now managed via
  `cornerShapeStencil` (see [New Utilities](#new-utilities)).
- Padding changed from asymmetric `0`/`padding.xs` (0px/8px) to `padding.xxs`/`padding.xs`
  (4px/8px).
- The default icon size has been reduced from `20px` to `16px`.
- Label typography now uses the `subtext.medium` type level (12px, previously `subtext.large`, 14px)
  with `fontWeight.medium` (previously `fontWeight.bold`).

### Inputs

#### Accessibility: Checked-State Contrast

> **Important:** The checked states of `Checkbox`, `Radio`, and `Switch` now derive their
> background/fill color from `system.color.brand.accent.positive` (which maps to your theme's
> `brand.success.base`), while the foreground (the check icon, radio dot, and switch thumb) remains
> an inverse/white color. This pairing relies on `brand.success.base` being a sufficiently dark
> color.

This change is safe for the default Canvas themes, where `brand.success.base` is dark enough to
maintain adequate contrast against the white foreground. However, **consumer themes that override
`brand.success.base` with a light color may produce insufficient contrast** between the checked
background and the white check icon, radio dot, or switch thumb. This can cause the checked state to
fail
[WCAG 1.4.11 Non-text Contrast (3:1)](https://www.w3.org/WAI/WCAG21/Understanding/non-text-contrast.html).

If you customize `brand.success.base` in your theme, please verify the following:

- **Maintain a minimum 3:1 contrast ratio** between your `brand.success.main` value and the white
  (`#ffffff`) foreground used for the check icon, radio dot, and switch thumb.
- Prefer a `brand.success.base` value that is dark enough to pair with a light foreground. If your
  brand requires a light success color, you may need to override the component styles so the
  foreground uses a darker, paired contrast color instead of white.

#### Checkbox

**PR:** [#3984](https://github.com/Workday/canvas-kit/pull/3984)

##### Visual Updates

- The default Checkbox size is now **20px** (previously 24px).
- Checked state uses `system.color.brand.accent.positive` instead of
  `system.color.brand.accent.primary` for the background.
- Error and alert states no longer display a status background color; only the standard background
  is shown.
- The hover ring is smaller to better align with the smaller size. The hover ring background color
  uses neutral instead of slate in `sana-canvas` theme.

#### Color Input

**PR:** [#3992](https://github.com/Workday/canvas-kit/pull/3992)

##### Visual Updates

- Shape is now **12px** (previously 8px).

#### Color Picker

**PR:** [#3992](https://github.com/Workday/canvas-kit/pull/3992)

##### Visual Updates

- **Sana Canvas:** swatch shape is now **6px** (previously **4px**).

#### Form Field

**PR:** [#3992](https://github.com/Workday/canvas-kit/pull/3992)

##### Visual Updates

- Shape for grouped inputs (Radio groups and Checkbox groups) is now **12px** (previously 8px). As
  in v15, this shape is primarily visible for error and caution states.
- Error and caution states no longer display a status background color; only the standard background
  is shown.

#### Radio

**PR:** [#3984](https://github.com/Workday/canvas-kit/pull/3984)

##### Visual Updates

- The default Radio size is now **20px** (previously 24px).
- Checked state uses `system.color.brand.accent.positive` instead of
  `system.color.brand.accent.primary` for the background.
- Error and alert states no longer display a status background color; only the standard background
  is shown.
- The hover ring is smaller to better align with the smaller size. The hover ring background color
  uses a neutral color instead of slate in `sana-canvas` theme.

#### Switch

**PR:** [#3984](https://github.com/Workday/canvas-kit/pull/3984)

##### Visual Updates

- The Switch thumb is now **16px** (was 14px). The icon-thumb container width remains unchanged.
- The checked state background now uses `system.color.brand.accent.positive` instead of
  `system.color.brand.accent.primary`.
- The default (unchecked) background color now uses `system.color.surface.muted.default` instead of
  `system.color.surface.muted.soft`. Background color uses a neutral color instead of slate in
  `sana-canvas` theme.

#### Text Area

**PR:** [#3992](https://github.com/Workday/canvas-kit/pull/3992)

##### Visual Updates

- Shape is now **12px** (previously 8px).
- Error and caution states no longer display a status background color; only the standard background
  is shown.

#### Text Input

**PR:** [#3992](https://github.com/Workday/canvas-kit/pull/3992)

##### Visual Updates

- Shape is now **12px** (previously 8px).
- Error and caution states no longer display a status background color; only the standard background
  is shown.

#### Select

**PR:** [#4085](https://github.com/Workday/canvas-kit/pull/4085)

##### Visual Updates

- The dropdown indicator icon now uses `chevronDownSmallIcon` and `chevronUpSmallIcon` instead of
  `caretDownSmallIcon`. The icon toggles direction when the menu is open.
- `Select.Input` inherits the `TextInput` shape update (**12px**, previously 8px) and menu styling
  updates from [Menu](#menu).
- Gap between the input and dropdown menu updated from `4px` to `8px` via `Menu.Popper` offset.

No API changes. No migration is required unless you render a custom dropdown indicator or override
`selectInputStencil` caret styles.

#### MultiSelect

**PR:** [#4085](https://github.com/Workday/canvas-kit/pull/4085)

##### Visual Updates

- Shape is now **12px** (`shape.lg`, previously `shape.md` / 8px) via `cornerShapeStencil`.
- The dropdown indicator icon now uses `chevronDownSmallIcon` and `chevronUpSmallIcon` instead of
  `caretDownSmallIcon`. The icon toggles direction when the menu is open.
- `MultiSelect` menus inherit the [Menu](#menu) styling updates.
- Gap between the input and dropdown menu updated from `4px` to `8px` via `Menu.Popper` offset.

No API changes. No migration is required unless you render a custom dropdown indicator or override
`multiSelectInputStencil` styles.

### Popups

#### Menu

**PR:** [#3987](https://github.com/Workday/canvas-kit/pull/3987)

##### Visual Updates

**Menu.Card**

- Text color updated from `system.color.fg.default` to `system.color.fg.strong`.
- Padding updated from `padding.xxs` (4px) to `padding.xs` (8px).
- Border radius is now managed via `cornerShapeStencil` (still uses `shape.xxl`).

**Menu.Popper**

- Offset between the trigger and dropdown menu updated from `4px` to `8px`. This affects `Select`,
  `MultiSelect`, `Combobox`, and other components that use `Menu.Popper`.

**Menu.List**

- Gap between items updated from `gap.xs` (4px) to `base.legacy.size25` (2px).

**Menu.Item**

- Icon-to-label gap updated from `gap.md` (16px) to `gap.sm` (8px).
- Padding updated from symmetric `padding.sm`/`padding.md` (12px/16px) to asymmetric
  `padding.xs`/`padding.xs`/`padding.xs`/`padding.sm` (8px top/right/bottom, 12px left).
- Item border radius updated from `shape.xxl` (24px) to `shape.lg` (12px).
- Text color updated from `system.color.fg.default` to `system.color.fg.strong`.
- Icon size updated to `md` (20px / 1.25rem).

##### Menu icon sizing

Menu icons are now smaller to align with Sana Canvas specs. In v15, `Menu.Item.Icon` did not set a
`size` prop and fell back to the `SystemIcon` default of `lg` (24px / 1.5rem). In v16, all icons
rendered through `Menu.Item.Icon` and `Menu.Option.Icon` use `size="md"` (20px / 1.25rem).

The selected checkmark in `Menu.Option` now uses `checkIcon` at `size="md"` instead of
`checkSmallIcon` at the previous 24px default. The nested submenu chevron in `Submenu.TargetItem`
also changed from `chevronRightSmallIcon` to `chevronRightIcon` at `size="md"`.

Passing a custom `size` to `Menu.Item.Icon` or `Menu.Option.Icon` will still override the default.
`Select` and `Combobox` menus inherit the `Menu.Option` checkmark change. If you are rendering
custom chevron or checkmark icons inside of menu items, update them to `size="md"` and swap
`*SmallIcon` assets for their standard equivalents where appropriate.

**Menu.Group.Heading**

- Padding updated to use `paddingBlock: padding.xs` with `paddingInline: padding.sm` / `padding.md`.

##### State Style Updates

`Menu.Item` and `Menu.Option` share the same underlying item styles via `menuItemStencil`. For
guidance on when to use `Menu.Item` vs `Menu.Option`, including accessibility requirements for
selectable menus, see the
[Menu accessibility documentation](https://workday.github.io/canvas-kit/?path=/docs/components-popups-menu--docs#accessibility).

###### Menu.Item

| State                                     | v15                                                                     | v16                                                                                                                               |
| ----------------------------------------- | ----------------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------- |
| Active/pressed                            | Not styled                                                              | `surface.overlay.pressed` background                                                                                              |
| Focus                                     | Solid blue fill (`brand.accent.primary`) and white text                 | Inset outline using `brand.border.primary`                                                                                        |
| Disabled + Focus (`aria-disabled="true"`) | Solid blue fill and white text with disabled opacity (dims focus style) | Light blue background and blue text (`brand.surface.selected` / `brand.fg.selected`) with disabled opacity (dims focus indicator) |
| Expanded submenu parent + Focus           | Same blue fill and white text focus style as other focused items        | Focus ring removed; ancestor-trail styling shown instead (`Submenu.TargetItem`)                                                   |

###### Menu.Option

Used in `Select`, `Combobox`, and other listbox menus. Selected states apply when
`aria-selected="true"`.

| State                                     | v15                                                                                         | v16                                                                                                                               |
| ----------------------------------------- | ------------------------------------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------- |
| Active/pressed                            | Not styled                                                                                  | `surface.overlay.pressed` background                                                                                              |
| Focus                                     | Solid blue fill (`brand.accent.primary`) and white text                                     | Inset outline using `brand.border.primary`                                                                                        |
| Selected (`aria-selected="true"`)         | Solid blue fill and white text (`brand.surface.primary.strong` / `brand.fg.primary.strong`) | Light blue background and blue text (`brand.surface.selected` / `brand.fg.selected`)                                              |
| Selected + Focus                          | Solid blue fill and white text                                                              | Inset outline with selected background preserved                                                                                  |
| Disabled + Focus (`aria-disabled="true"`) | Solid blue fill and white text with disabled opacity (dims focus style)                     | Light blue background and blue text (`brand.surface.selected` / `brand.fg.selected`) with disabled opacity (dims focus indicator) |
| Disabled + Selected                       | Solid blue fill and white text with disabled opacity                                        | Light blue background and blue text (`brand.surface.selected` / `brand.fg.selected`) with disabled opacity                        |

#### Modal

##### Visual Updates

- `Modal.Card` box-shadow updated from `system.depth[5]` to `system.depth[6]`.

#### Popup

##### Visual Updates

- `Popup.Card` box-shadow updated from `system.depth[3]` to `system.depth[4]`.

#### Toast

**PR:** [#4053](https://github.com/Workday/canvas-kit/pull/4053)

##### Visual Updates

- Padding is now applied to the `Toast` container itself instead of being distributed across
  `Toast.Body` and `Toast.Icon`.
- Gap between the icon, body, and close icon is now `base.size150` (12px).
- Shape uses `system.shape.xl`.
- Box-shadow updated from `system.depth[3]` to `system.depth[5]`.
- `Toast.Body` no longer has a gap between text and link.
- `Toast.CloseIcon` is set to have absolute positioning and aligned with the top-right corner (in
  LTR).
- `Toast.CloseIcon` was changed to be `extraSmall` tertiary button.

#### Tooltip

**PR:** [#4053](https://github.com/Workday/canvas-kit/pull/4053)

##### Visual Updates

- The default tooltip has been restyled from a dark surface to a light surface.
- A visible border (`system.color.border.default`) is now applied to the container, replacing the
  previous transparent outline.
- Tooltip boundaries remain visible in Windows High Contrast mode: when High Contrast is detected,
  Tooltip uses a solid outline (`outline: solid 1px CanvasText`) to ensure clear visibility.
- Shape is now fully rounded using `system.shape.full`.
- Box-shadow updated from `system.depth[2]` to `system.depth[3]`.
- Type level is now `subtext.lg` (previously `subtext.md`).
- Padding and spacing have been adjusted to accommodate the new styling.

### Navigation Components

#### Hyperlink

##### Visual Updates

- Default link color uses new link tokens (`system.color.fg.link.default` / `.hover`). Hover and
  active text is now the darker link-hover blue.
- Hover and active backgrounds use surface overlay tokens instead of `surface.alt`.

##### New Secondary Variant and `linkType` Prop

A new "secondary" variant and `linkType` prop have been added to `Hyperlink` and
`ExternalHyperlink`. Color and underline are now controlled by separate props:

| Need                       | API                                           |
| -------------------------- | --------------------------------------------- |
| Blue, underlined (default) | _(no props)_                                  |
| Blue, no underline         | `linkType="standalone"`                       |
| Inverse, underlined        | `variant="inverse"`                           |
| Inverse, no underline      | `variant="inverse"` `linkType="standalone"`   |
| Dark gray, underlined      | `variant="secondary"`                         |
| Dark gray, no underline    | `variant="secondary"` `linkType="standalone"` |

`variant` is now either 'inverse' or 'secondary'. Underline is controlled by `linkType` which is
either 'inline' or 'standalone', defaulting to 'inline'. The compound variants `standalone` and
`standaloneInverse` are **removed**.

```tsx
import {ExternalHyperlink, Hyperlink} from '@workday/canvas-kit-react/button';

<Hyperlink variant="secondary" href="#secondary-hyperlink">
  Secondary Hyperlink
</Hyperlink>
<Hyperlink linkType="standalone" href="#standalone-hyperlink">
  Standalone Hyperlink
</Hyperlink>
<ExternalHyperlink
  variant="secondary"
  linkType="standalone"
  href="#secondary-standalone-external-hyperlink"
  iconLabel="Opens new window"
>
  Secondary Standalone External Hyperlink
</ExternalHyperlink>
```

###### Breaking Change Migration

Run the Canvas Kit v16 codemod (`updateHyperlinkProps`) to migrate automatically:

| Before                        | After                                       |
| ----------------------------- | ------------------------------------------- |
| `variant="standalone"`        | `linkType="standalone"`                     |
| `variant="standaloneInverse"` | `variant="inverse"` `linkType="standalone"` |

#### Breadcrumbs

##### Visual Updates

- Trail links (`Breadcrumbs.Link`) use Hyperlink `variant="secondary"` and `linkType="standalone"`.
  Trail text uses `system.color.fg.default`; hover and active states use surface overlay tokens with
  underline on hover.
- The current item (`Breadcrumbs.CurrentItem`) uses `system.color.fg.muted.default`.
- Overflow and separator chevrons use muted/strong foreground colors with
  `component.legacy.systemIcon.size.md`.

#### Pagination

##### Visual Updates

- Page buttons use overlay hover/pressed backgrounds and a focus ring (aligned with the
  TertiaryButton pattern). The current page uses `system.color.brand.accent.primary` with inverse
  label text.
- Control chevrons (previous/next and jump controls) are sized to 16px via
  `component.legacy.systemIcon.size.xs`.
- GoTo label uses `size="large"` (14px). GoTo input text is centered; border radius inherits from
  TextInput `shape.lg` (12px).
- GoToForm spacing uses `marginInlineStart: gap.xs` alongside Controls `gap.xs`.

### Segmented Control

**PR:** [#4048](https://github.com/Workday/canvas-kit/pull/4048)

#### Visual Updates

- Container background changed from `surface.alt.strong` to `surface.alt.default` (a lighter
  background color).
- Border radius changed to `shape.full` (full rounded corners) on the container.
- Grid gap reduced from `gap.sm` (8px) to `gap.xs` (4px).
- Selected/pressed item now uses boxShadow: system.depth[2] instead of a visible border.
- Font weight changed from bold to medium (base and small sizes);
- Medium size now uses semi-bold font weight.
- Size adjustments: large height shrunk to size.sm (32px) (was size.md (40px));
- Medium size is now 28px in height (was 32px).
- Hover and pressed states now use `surface.overlay.hover.default` and
  `surface.overlay.pressed.default` respectively for the item.
- Container padding changed to `padding.md` (16px) including for mobile devices.
- On mobile devices, the container padding remains `padding.md` (16px).

## New Utilities

### cornerShapeStencil

We've added a new stencil called `cornerShapeStencil` to `@workday/canvas-kit-react/common`. It
applies the CSS [`corner-shape`](https://developer.mozilla.org/en-US/docs/Web/CSS/corner-shape)
property as a progressive enhancement for components using border radius that aren't circular.
Browsers that don't support `corner-shape` fall back to `border-radius` alone, as border-radius is
declared first in the cascade.

The stencil exposes a `shape` variable for setting the border radius. Extend it in your own stencils
to get consistent rounded corners:

```tsx
import {cornerShapeStencil} from '@workday/canvas-kit-react/common';
import {createStencil} from '@workday/canvas-kit-styling';
import {system} from '@workday/canvas-tokens-web';

export const myStencil = createStencil({
  extends: cornerShapeStencil,
  base: {
    [cornerShapeStencil.vars.shape]: system.legacy.shape.xxl,
  },
});
```

`Card`, `Expandable` (`Expandable.Target`), `Menu` (`Menu.Card`, `Menu.List`, `Menu.Item`),
`MultiSelect`, and `Table` (`BaseTable`, `Table`) extend this stencil for their rounded corners.

## Fonts

Canvas Kit does not bundle fonts. In v16, which font you load depends on whether you opt into the
[Sana Canvas theme](#sana-canvas-theme).

| Theme | Typeface | Package |
| ----- | -------- | ------- |
| Sana Canvas (`data-theme="sana-canvas"`) | Sana Sans (+ IBM Plex Mono) | `@workday/canvas-kit-react/fonts` |
| Classic Canvas (default) | Roboto (+ Roboto Mono) | `@workday/canvas-kit-react-fonts` |

### Sana Canvas Theme — Switch to Sana Sans

When you opt into Sana, `--cnvs-sys-font-family-default` (`system.fontFamily.default`) points at
`'Sana Sans VF'`. Load the matching `@font-face` rules from the new fonts module (requires
`@workday/canvas-tokens-web` `4.4.0` or later):

```ts
import {fonts} from '@workday/canvas-kit-react/fonts';
import {injectGlobal} from '@workday/canvas-kit-styling';
import {system} from '@workday/canvas-tokens-web';

injectGlobal({
  ...fonts,
  'html, body': {
    fontFamily: system.fontFamily.default,
    margin: 0,
    minHeight: '100vh',
  },
});
```

If your environment already provides Sana Sans, you can skip injecting `@font-face` and keep using
`system.fontFamily.default`.

> **Note:** Prefer `@workday/canvas-kit-react/fonts` over `@workday/canvas-kit-react-fonts` when the
> Sana Canvas theme is enabled. The older package still loads Roboto and will not match the Sana
> font-family token.

### Classic Canvas — Keep Roboto

If you are **not** setting `data-theme="sana-canvas"`, continue using
`@workday/canvas-kit-react-fonts` as before:

```ts
import {fonts} from '@workday/canvas-kit-react-fonts';
import {injectGlobal} from '@workday/canvas-kit-styling';
import {system} from '@workday/canvas-tokens-web';

injectGlobal({
  ...fonts,
  'html, body': {
    fontFamily: system.fontFamily.default,
  },
});
```

For full installation details, variable-font notes, and monospace coverage, see the
[Fonts guide](https://workday.github.io/canvas-kit/?path=/docs/guides-fonts--docs).

## Deprecations

We add the [@deprecated](https://jsdoc.app/tags-deprecated.html) JSDoc tag to code we plan to remove
in a future major release. This signals consumers to migrate to a more stable alternative before the
deprecated code is removed.

## Glossary

For an overview of the different packages we provide, please view our docs
[here](https://workday.github.io/canvas-kit/?path=/docs/guides-packages--docs).

### Main

Components in the Main package are stable and ready for production use.

### Preview

Components in the Preview package are mostly stable but may still receive breaking changes before
being promoted to Main.

### Labs

Components in the Labs package are experimental and may receive significant changes or be removed
entirely.

---

## Codemod Reference

# What is a Codemod?

A codemod is a script that makes programmatic transformations on your codebase by traversing the
[AST](https://www.codeshiftcommunity.com/docs/understanding-asts), identifying patterns, and making
prescribed changes. This greatly decreases opportunities for error and reduces the number of manual
updates, which allows you to focus on changes that need your attention. **We highly recommend you
use the codemod for these reasons.**

If you're new to running codemods or if it's been a minute since you've used one, there are a few
things you'll want to keep in mind.

- Our codemods are meant to be run sequentially. For example, if you're using v8 of Canvas Kit,
  you'll need to run the v9 codemod before you run v10 and so on.
- The codemod will update your code to be compatible with the specified version, but it will **not**
  remove outdated dependencies or upgrade dependencies to the latest version. You'll need to upgrade
  dependencies on your own.
  - We recommend upgrading dependencies before running the codemod.
  - Always review your `package.json` files to make sure your dependency versions look correct.
- The codemod will not handle every breaking change in this upgrade. You will likely need to make some manual
  changes to be compatible. Use our Upgrade Guide as a checklist.
- Codemods are not bulletproof.
  - Conduct a thorough PR and QA review of all changes to ensure no regressions were introduced.
  - As a safety precaution, we recommend committing the changes from the codemod as a single
    isolated commit (separate from other changes) so you can roll back more easily if necessary.

We're here to help! Automatic changes to your codebase can feel scary. You can always reach out to
our team. We'd be very happy to walk you through the process to set you up for success.

## Running a Codemod

### Instructions

The easiest way to run our codemod is to use `npx` in your terminal.

```sh
npx @workday/canvas-kit-codemod v${canvasKitMajorVersionNumber} [path]
```

Be sure to provide specific directories that need to be updated via the `[path]` argument. This
decreases the amount of AST the codemod needs to traverse and reduces the chances of the script
having an error. For example, if your source code lives in `src/`, use `src/` as your `[path]`. Or,
if you have a monorepo with three packages using Canvas Kit, provide those specific packages as your
`[path]`.

Alternatively, if you're unable to run the codemod successfully using `npx`, you can install the
codemod package as a dev dependency, run it with `yarn`, and then remove the package after you're
finished.

```sh
yarn add @workday/canvas-kit-codemod --dev
yarn canvas-kit-codemod v${canvasKitMajorVersionNumber} [path]
yarn remove @workday/canvas-kit-codemod
```

> **Note**: The codemod only works on `.js`, `.jsx`, `.ts`, and `.tsx` files. You'll need to
> manually edit other file types (`.json`, `.mdx`, `.md`, etc.). You may need to run your linter
> after executing the codemod, as its resulting formatting (spacing, quotes, etc.) may not match
> your project conventions.

## Codemod Transformations for v16

The following automated transformations are available for upgrading to v16:

- **Update Card Variant**: updateCardVariant
- **Update Hyperlink Props**: updateHyperlinkProps
- **Update Side Panel Variant**: updateSidePanelVariant

Run the codemod with: `npx @workday/canvas-kit-codemod v16 [path]`
