> ## Documentation Index
> Fetch the complete documentation index at: https://docs.chmodlab.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Appearance

> Theme, color palette, corner style and typography for the verification flow.

The flow can be themed to match your app: two full color palettes, a corner style and text
sizes.

<CodeGroup>
  ```swift iOS lines theme={null}
  let appearance = ChmodKycConfiguration.Appearance(
      theme:      .system,             // .system .light .dark
      corners:    .medium,             // .none .extraSmall .small .medium .large .extraLarge .full
      light:      lightColors,         // Palette used when the flow renders in light mode
      dark:       darkColors,          // Palette used when the flow renders in dark mode
      typography: typography           // Font family and text sizes
  )
  ```

  ```kotlin Android lines theme={null}
  val appearance = SdkConfig.Appearance(
      theme = ThemeMode.SYSTEM,                    // SYSTEM, LIGHT, DARK
      light = lightColors,                         // Palette used when the flow renders in light mode
      dark = darkColors,                           // Palette used when the flow renders in dark mode
      typography = SdkConfig.Typography(),         // Text sizes
      shapes = SdkConfig.Shapes(ShapePreset.FULL)  // NONE, EXTRA_SMALL, SMALL, MEDIUM, LARGE, EXTRA_LARGE, FULL
  )
  ```
</CodeGroup>

## Theme

| Value | Behaviour |
| - | - |
| `SYSTEM` | Follows the device setting. Default. |
| `LIGHT` | Always the light palette |
| `DARK` | Always the dark palette |

With `SYSTEM`, define **both** palettes. A user in dark mode with only a light palette set
gets the SDK's dark defaults, which almost certainly are not your brand.

## Colors

Hex strings (`"#RRGGBB"`). Every field is optional: leaving one unset falls back to the SDK
default, and an empty palette is valid.

<CodeGroup>
  ```swift iOS lines theme={null}
  let lightColors = ChmodKycConfiguration.ThemeColors(
      primary:                 "#1F49B6",  // Buttons, accents, active elements
      onPrimary:               "#FFFFFF",  // Text and icons on top of primary
      secondary:               "#5B7BD5",  // Secondary accent
      onSecondary:             "#FFFFFF",  // Text on top of secondary
      tertiary:                "#8FA9E8",  // Tertiary accent
      onTertiary:              "#0B1F4D",  // Text on top of tertiary
      background:              "#F5F6FA",  // Screen background
      onBackground:            "#0B1220",  // Text on top of the background
      surface:                 "#FFFFFF",  // Cards, sheets and input fields
      onSurface:               "#0B1220",  // Text on top of surface
      surfaceVariant:          "#E7EAF3",  // Secondary surfaces
      onSurfaceVariant:        "#454B5C",  // Text on top of surfaceVariant
      error:                   "#D93025",  // Error states
      onError:                 "#FFFFFF",  // Text on top of error
      outline:                 "#C3C8D4",  // Borders and dividers
      resultSuccessBackground: "#08A25D",  // Success circle on the result screen
      resultSuccessIcon:       "#FFFFFF",  // Icon inside the success circle
      resultErrorBackground:   "#D93025",  // Error circle on the result screen
      resultErrorIcon:         "#FFFFFF"   // Icon inside the error circle
  )
  ```

  ```kotlin Android lines theme={null}
  val lightColors = SdkConfig.ThemeColors(
      primary                 = "#1F49B6",  // Buttons, accents, active elements
      onPrimary               = "#FFFFFF",  // Text and icons on top of primary
      secondary               = "#5B7BD5",  // Secondary accent
      onSecondary             = "#FFFFFF",  // Text on top of secondary
      tertiary                = "#8FA9E8",  // Tertiary accent
      onTertiary              = "#0B1F4D",  // Text on top of tertiary
      background              = "#F5F6FA",  // Screen background
      onBackground            = "#0B1220",  // Text on top of the background
      surface                 = "#FFFFFF",  // Cards, sheets and input fields
      onSurface               = "#0B1220",  // Text on top of surface
      surfaceVariant          = "#E7EAF3",  // Secondary surfaces
      onSurfaceVariant        = "#454B5C",  // Text on top of surfaceVariant
      error                   = "#D93025",  // Error states
      onError                 = "#FFFFFF",  // Text on top of error
      outline                 = "#C3C8D4",  // Borders and dividers
      resultSuccessBackground = "#08A25D",  // Success circle on the result screen
      resultSuccessIcon       = "#FFFFFF",  // Icon inside the success circle
      resultErrorBackground   = "#D93025",  // Error circle on the result screen
      resultErrorIcon         = "#FFFFFF"   // Icon inside the error circle
  )
  ```
</CodeGroup>

### Overriding one color

This is the mistake people hit first. A palette you build yourself **replaces** the
defaults rather than merging into them: every field you leave out is unset, not the SDK
default.

To change one color and keep the rest, start from the defaults:

<CodeGroup>
  ```swift iOS lines theme={null}
  var colors = ChmodKycConfiguration.Defaults.lightColors
  colors.primary = "#1F49B6"

  let appearance = ChmodKycConfiguration.Appearance(light: colors)
  ```

  ```kotlin Android lines theme={null}
  val colors = SdkConfig.ThemeColors.defaultLight().copy(primary = "#1F49B6")
  val appearance = SdkConfig.Appearance(light = colors)
  ```
</CodeGroup>

<Warning>
  Passing `ThemeColors(primary: "#1F49B6")` instead would also reset `background`,
  `surface` and `onPrimary` back to their Material fallbacks — which is why a flow that
  should be your brand blue comes out Material purple.
</Warning>

### On-color pairs

Every `onX` color is what renders **on top of** `X`. They travel in pairs, and breaking a
pair is how you end up with unreadable text: setting `primary` to a dark blue without
setting `onPrimary` to something light leaves dark-on-dark button labels.

The SDK does not compute a contrasting color for you. Set both halves.

<Info>
  Aim for at least 4.5:1 contrast between each pair. The flow is used by people
  photographing a document in poor lighting, sometimes one-handed, often outdoors —
  legibility matters more here than in most of your app.
</Info>

## Corners

One preset applies to buttons, cards and inputs throughout the flow.

| Preset | Feel |
| - | - |
| `NONE` | Square |
| `EXTRA_SMALL` / `SMALL` | Subtle rounding |
| `MEDIUM` | Balanced. A safe default |
| `LARGE` / `EXTRA_LARGE` | Noticeably rounded |
| `FULL` | Pill-shaped buttons |

## Typography

<CodeGroup>
  ```swift iOS lines theme={null}
  let typography = ChmodKycConfiguration.Typography(
      fontFamily: .sansSerif,  // .default .sansSerif .serif .monospace .cursive
      bodySize:   14,          // Body text size in points
      titleSize:  22,          // Title text size in points
      labelSize:  12           // Label text size in points
  )
  ```

  ```kotlin Android lines theme={null}
  val typography = SdkConfig.Typography(
      bodySize  = 14,  // Body text size in sp
      titleSize = 22,  // Title text size in sp
      labelSize = 12   // Label text size in sp
  )
  ```
</CodeGroup>

<Warning>
  On Android, `Typography` also has a `fontFamily` field, but it is `@Transient`: the
  config is serialized into the launching `Intent`, and a transient field does not survive
  that trip. Whatever you set there is dropped and the flow renders with
  `FontFamily.Default`. Leave it alone until the SDK exposes a serializable way to name a
  font.
</Warning>

Text sizes are in points on iOS and sp on Android, so both respect the user's system text
size setting. Do not compensate by shrinking them — you would be undoing an accessibility
setting the user chose deliberately.


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.