## setTheme

`setTheme` accepts a **JSON string** describing the theme. Two formats are supported:

- **V2** — cross-platform (Android + iOS V2 UX). This is the current, recommended format.
- **V1** — iOS legacy UX only.

Call `setTheme` before starting any onboarding section/flow.

JavaScript

```javascript
cordova.exec(
  function () { console.log("Theme applied"); },
  function (err) { console.log("setTheme error:", err); },
  "Cplugin",
  "setTheme",
  [jsonThemeString]
);
```

### V2 theme (cross-platform, current)

The V2 theme is composed of `displayMode`, `typography`, `colorPalette`, and `components.buttons`.

JSON

```json
{
  "displayMode": "light",
  "typography": {
    "family": {
      "text": {
        "android": {
          "regular": "onboard_sdk_dm_sans_regular",
          "bold": "onboard_sdk_dm_sans_bold",
          "medium": "onboard_sdk_dm_sans_medium"
        },
        "ios": {
          "regular": "DMSans-Regular",
          "bold": "DMSans-Bold",
          "medium": "DMSans-Medium"
        }
      },
      "display": {
        "android": {
          "regular": "onboard_sdk_dm_sans_regular",
          "bold": "onboard_sdk_dm_sans_bold",
          "medium": "onboard_sdk_dm_sans_medium"
        },
        "ios": {
          "extraBold": "DMSans-ExtraBold"
        }
      }
    },
    "letterSpacing": {
      "none": 0,
      "medium": -0.5,
      "large": -1.0,
      "extraLarge": -1.5
    }
  },
  "colorPalette": {
    "neutralLight": "#ffffff",
    "neutralDark": "#000000",
    "brand50": "#e5f0ff",
    "brand200": "#99c3ff",
    "brand300": "#66a6ff",
    "brand400": "#3388ff",
    "brand500": "#006aff",
    "brand600": "#0055cc",
    "brand900": "#21273b",
    "gray50": "#FCFCFD",
    "gray100": "#EBECEF",
    "gray200": "#C6C8D2",
    "gray300": "#A3A8B8",
    "gray500": "#60667C",
    "gray700": "#3A3E4B",
    "gray800": "#262831",
    "gray900": "#14151A",
    "brandSecondary50": "#F2E2FE",
    "brandSecondary500": "#820AD1",
    "negative50": "#FFF0F0",
    "negative500": "#FF5A5F",
    "negative600": "#E71111",
    "negative950": "#240001",
    "warning50": "#FFF7EB",
    "warning400": "#FFB647",
    "warning500": "#FF9900",
    "warning950": "#523100",
    "positive50": "#E4FBF0",
    "positive600": "#189F60",
    "positive800": "#0C5030"
  }
}
```

#### `displayMode`

| Key            | Values                      | Description               |
|----------------|-----------------------------|---------------------------|
| `displayMode`  | `"light"` / `"dark"`    | Base display mode.       |

#### `typography`

| Key                          | Description                                   |
|------------------------------|-----------------------------------------------|
| `family.text.android`       | Android font resource names for body text (`regular`, `bold`, `medium`). |
| `family.text.ios`          | iOS font names for body text (`regular`, `bold`, `medium`). |
| `family.display.android`    | Android font resource names for display/headline text. |
| `family.display.ios`       | iOS font names for display/headline text (e.g. `extraBold`). |
| `letterSpacing`             | Letter-spacing tokens: `none`, `medium`, `large`, `extraLarge`. |

#### `colorPalette`

| Key group                 | Keys                                              |
|---------------------------|---------------------------------------------------|
| Neutral                   | `neutralLight`, `neutralDark`                    |
| Brand                     | `brand50`, `brand200`, `brand300`, `brand400`, `brand500`, `brand600`, `brand900` |
| Gray                      | `gray50`, `gray100`, `gray200`, `gray300`, `gray500`, `gray700`, `gray800`, `gray900` |
| Brand secondary           | `brandSecondary50`, `brandSecondary500`         |
| Negative (errors)        | `negative50`, `negative500`, `negative600`, `negative950` |
| Warning                   | `warning50`, `warning400`, `warning500`, `warning950` |
| Positive (success)       | `positive50`, `positive600`, `positive800`     |

> **Migration note (4.6.0, Android):** the `neutral` and `black` keys were renamed to `neutralLight` and `neutralDark`. Theme JSON using the old keys silently falls back to defaults (`#FFFFFF` / `#000000`).

#### `components.buttons`

Each entry in `components.buttons` targets a button style (`"primary"`, `"secondary"`, `"text"`) and lets you override surface color, text color, and border per state.

JSON

```json
{
  "components": {
    "buttons": [
      {
        "style": "primary",
        "surface": {
          "default": "#006aff",
          "hover": "#3388ff",
          "pressed": "#0055cc",
          "disabled": "#C6C8D2"
        },
        "text": {
          "default": "#ffffff",
          "disabled": "#A3A8B8"
        },
        "border": {
          "color": {
            "default": "#006aff",
            "hover": "#3388ff",
            "pressed": "#0055cc",
            "disabled": "#C6C8D2"
          },
          "width": 0,
          "radius": 200
        }
      }
    ]
  }
}
```

`surface` and `text``default` values accept either a single hex string or a two-element array for light/dark mode override: `["#lightHex", "#darkHex"]`.

| Field                        | Description                                               |
|------------------------------|-----------------------------------------------------------|
| `style`                      | Which button type to style: `"primary"`, `"secondary"`, or `"text"`. |
| `surface.default`            | Background color in the default/idle state.             |
| `surface.hover`              | Background color on hover (primarily web/desktop).     |
| `surface.pressed`            | Background color when pressed/tapped.                   |
| `surface.disabled`           | Background color when the button is disabled.           |
| `text.default`               | Label text color in the default state.                   |
| `text.disabled`              | Label text color when disabled.                           |
| `border.color.default`       | Border color in the default state.                       |
| `border.color.hover`         | Border color on hover.                                   |
| `border.color.pressed`       | Border color when pressed.                                |
| `border.color.disabled`       | Border color when disabled.                              |
| `border.width`                 | Border width in points/dp (`0` for no border).         |
| `border.radius`               | Corner radius in points/dp.                             |

### V1 theme (iOS legacy)

The V1 theme is for the legacy iOS UX only. It is composed of `colors`, `fonts`, `buttons`, `labels`, and `customComponents`.

JSON

```json
{
  "colors": {
    "accent": "#00B2FD",
    "primary": "#20263D",
    "background": "#FFFFFF",
    "secondaryBackground": "#E9E9EB",
    "success": "#0CD5A2",
    "error": "#FF5C6F",
    "warning": "#F3AB3C",
    "cancel": "#20263D"
  },
  "fonts": {
    "buttonBig": { "name": "CircularXXTT-Black", "size": "20" },
    "buttonMedium": { "name": "CircularXXTT-Black", "size": "16" },
    "buttonSmall": { "name": "CircularXXTT-Black", "size": "12" },
    "title": { "name": "CircularXXTT-Black", "size": "25" },
    "hugeTitle": { "name": "CircularXXTT-Black", "size": "40" },
    "subtitle": { "name": "CircularXXTT-Black", "size": "18" },
    "boldedSubtitle": { "name": "CircularXXTT-Bold", "size": "18" },
    "smallSubtitle": { "name": "CircularXXTT-Black", "size": "14" },
    "info": { "name": "CircularXXTT-Black", "size": "16" },
    "body": { "name": "CircularXXTT-Medium", "size": "14" },
    "boldedBody": { "name": "CircularXXTT-Bold", "size": "14" },
    "textFieldBig": { "name": "CircularXXTT-Black", "size": "20" },
    "textFieldMedium": { "name": "CircularXXTT-Black", "size": "15" }
  },
  "buttons": {
    "primary": {
      "states": {
        "normal": {
          "animateStateChange": true,
          "alpha": 1,
          "backgroundColor": "#00B2FD",
          "borderColor": "",
          "borderWidth": 0,
          "cornerRadius": 32,
          "shadowColor": "#000000",
          "shadowOffset": [0, 5],
          "shadowOpacity": 0.15,
          "shadowRadius": 9,
          "textColor": "#FFFFFF",
          "transform": { "a": 1, "b": 0, "c": 0, "d": 1, "tx": 0, "ty": 0 }
        },
        "highlighted": {
          "animateStateChange": true,
          "alpha": 1,
          "backgroundColor": "#20263D",
          "borderColor": "",
          "borderWidth": 0,
          "cornerRadius": 32,
          "shadowColor": "#000000",
          "shadowOffset": [0, 5],
          "shadowOpacity": 0.15,
          "shadowRadius": 9,
          "textColor": "#00B2FD",
          "transform": { "a": 1, "b": 0, "c": 0, "d": 1, "tx": 0, "ty": 0 }
        },
        "disabled": {
          "animateStateChange": true,
          "alpha": 1,
          "backgroundColor": "#E9E9EB",
          "borderColor": "",
          "borderWidth": 0,
          "cornerRadius": 32,
          "shadowColor": "#000000",
          "shadowOffset": [0, 5],
          "shadowOpacity": 0,
          "shadowRadius": 9,
          "textColor": "#FFFFFF",
          "transform": { "a": 1, "b": 0, "c": 0, "d": 1, "tx": 0, "ty": 0 }
        }
      },
      "big": {
        "height": 64,
        "minWidth": 200,
        "contentInsets": { "top": 19, "left": 32, "bottom": 19, "right": 32 },
        "kerning": 0
      },
      "medium": {
        "height": 46,
        "minWidth": 0,
        "contentInsets": { "top": 12, "left": 24, "bottom": 12, "right": 24 },
        "kerning": 0
      }
    },
    "secondary": {
      "states": {
        "normal": {
          "animateStateChange": true,
          "alpha": 1,
          "backgroundColor": "#FFFFFF",
          "borderColor": "#20263D",
          "borderWidth": 1,
          "cornerRadius": 32,
          "shadowColor": "",
          "shadowOffset": [0, 0],
          "shadowOpacity": 0,
          "shadowRadius": 0,
          "textColor": "#20263D",
          "transform": { "a": 1, "b": 0, "c": 0, "d": 1, "tx": 0, "ty": 0 }
        },
        "highlighted": {
          "animateStateChange": true,
          "alpha": 1,
          "backgroundColor": "#20263D",
          "borderColor": "#20263D",
          "borderWidth": 1,
          "cornerRadius": 32,
          "shadowColor": "",
          "shadowOffset": [0, 0],
          "shadowOpacity": 0,
          "shadowRadius": 0,
          "textColor": "#00B2FD",
          "transform": { "a": 1, "b": 0, "c": 0, "d": 1, "tx": 0, "ty": 0 }
        },
        "disabled": {
          "animateStateChange": true,
          "alpha": 1,
          "backgroundColor": "#FFFFFF",
          "borderColor": "#E9E9EB",
          "borderWidth": 1,
          "cornerRadius": 32,
          "shadowColor": "",
          "shadowOffset": [0, 0],
          "shadowOpacity": 0,
          "shadowRadius": 0,
          "textColor": "#E9E9EB",
          "transform": { "a": 1, "b": 0, "c": 0, "d": 1, "tx": 0, "ty": 0 }
        }
      },
      "big": {
        "height": 64,
        "minWidth": 200,
        "contentInsets": { "top": 19, "left": 32, "bottom": 19, "right": 32 },
        "kerning": 0
      },
      "medium": {
        "height": 46,
        "minWidth": 0,
        "contentInsets": { "top": 12, "left": 24, "bottom": 12, "right": 24 },
        "kerning": 0
      }
    },
    "text": {
      "states": {
        "normal": {
          "animateStateChange": true,
          "alpha": 1,
          "backgroundColor": "",
          "borderColor": "",
          "borderWidth": 0,
          "cornerRadius": 0,
          "shadowColor": "",
          "shadowOffset": [0, 0],
          "shadowOpacity": 0,
          "shadowRadius": 0,
          "textColor": "#20263D",
          "transform": { "a": 1, "b": 0, "c": 0, "d": 1, "tx": 0, "ty": 0 }
        }
      },
      "big": {
        "height": 40,
        "minWidth": 200,
        "contentInsets": { "top": 8, "left": 16, "bottom": 8, "right": 16 },
        "kerning": 0
      },
      "medium": {
        "height": 30,
        "minWidth": 0,
        "contentInsets": { "top": 12, "left": 24, "bottom": 12, "right": 24 },
        "kerning": 0
      }
    },
    "help": {
      "states": {
        "normal": {
          "animateStateChange": true,
          "alpha": 1,
          "backgroundColor": "#00B2FD",
          "cornerRadius": 32,
          "textColor": "#FFFFFF"
        }
      },
      "big": {
        "height": 64,
        "minWidth": 200,
        "contentInsets": { "top": 19, "left": 32, "bottom": 19, "right": 32 },
        "kerning": 0
      }
    }
  },
  "labels": {
    "title": { "textColor": "#20263D", "kerning": 0 },
    "secondaryTitle": { "textColor": "#FFFFFF", "kerning": 0 },
    "subtitle": { "textColor": "#20263D", "kerning": 0 },
    "secondarySubtitle": { "textColor": "#FFFFFF", "kerning": 0 },
    "smallSubtitle": { "textColor": "#20263D", "kerning": 0 },
    "info": { "textColor": "#636670", "kerning": 0 },
    "secondaryInfo": { "textColor": "#FFFFFF", "kerning": 0 },
    "body": { "textColor": "#20263D", "kerning": 0 },
    "secondaryBody": { "textColor": "#FFFFFF", "kerning": 0 },
    "code": { "textColor": "#20263D", "kerning": 16 }
  },
  "customComponents": {
    "cameraFeedback": {
      "alpha": 0.8,
      "backgroundColor": "#000000",
      "cornerRadius": 20,
      "textBackgroundColor": "",
      "textColor": "#FFFFFF"
    },
    "idCaptureHelp": {
      "commonIssueLayoutOrientation": "horizontal"
    },
    "idSideLabel": {
      "alpha": 1,
      "backgroundColor": "#FFFFFF",
      "borderColor": "",
      "borderWidth": 0,
      "cornerRadius": 5
    },
    "separator": {
      "alpha": 1.0,
      "color": "#20263D",
      "cornerRadius": 0,
      "padding": 24,
      "thickness": 1
    },
    "signature": {
      "signatureColor": "#04BD19",
      "canvasBorderColor": "#EC03FC"
    },
    "idAutocaptureCountdown": {
      "backgroundColor": "#00B2FD",
      "numberColor": "#FFFFFF"
    }
  }
}
```

V1 theme sections:

| Section            | Description                                                                                         |
|--------------------|-----------------------------------------------------------------------------------------------------|
| `colors`           | Semantic colors: `accent`, `primary`, `background`, `secondaryBackground`, `success`, `error`, `warning`, `cancel`. |
| `fonts`            | Per-role font name + size: buttons, titles, subtitles, body, info, text fields, etc.              |
| `buttons`          | Per-type (`primary`, `secondary`, `text`, `help`) state styling (`normal`, `highlighted`, `disabled`) plus `big`/`medium` sizing. |
| `labels`           | Per-role text color and kerning.                                                                    |
| `customComponents`  | Component-specific styling (`cameraFeedback`, `idCaptureHelp`, `idSideLabel`, `separator`, `signature`, `idAutocaptureCountdown`). |

## setString

Override individual UI strings with custom copy. `setString` accepts an **object** mapping locale keys to custom strings. The keys are **platform-specific** — on iOS they use the `incdOnboarding.*` namespace (e.g. `incdOnboarding.userInformation.email.title`).

JavaScript

```javascript
let strings = {
  "incdOnboarding.userInformation.email.title": "Your email address"
  // ...more keys
};

cordova.exec(
  function () { console.log("Strings overridden"); },
  function (err) { console.log("setString error:", err); },
  "Cplugin",
  "setString",
  [strings]
);
```

> The string keys are overridden for the **current locale**.

## setLocalizationLanguage

Change the UI language at runtime. Accepts a language code string.

| Code | Language |
|------|----------|
| `en` | English  |
| `es` | Spanish  |
| `pt` | Portuguese |
| `he` | Hebrew   |

JavaScript

```javascript
cordova.exec(
  function () { console.log("Language set"); },
  function (err) { console.log("Error:", err); },
  "Cplugin",
  "setLocalizationLanguage",
  ["es"]
);
```

## setUXConfig

Set UX configuration at runtime. Accepts a **JSON string**.

| Option          | Type    | Description                                                  |
|-----------------|---------|--------------------------------------------------------------|
| `showFooter`    | boolean | Show or hide the footer in V2 IdScan and SelfieScan modules. |

JavaScript

```javascript
let uxConfig = JSON.stringify({ showFooter: false });

cordova.exec(
  function () {},
  function (err) { console.log("setUXConfig error:", err); },
  "Cplugin",
  "setUXConfig",
  [uxConfig]
);
```

## setFaceAuthenticationHint

Set a hint text shown to the user during face authentication. Accepts a string.

JavaScript

```javascript
cordova.exec(
  function () {},
  function (err) { console.log("Error:", err); },
  "Cplugin",
  "setFaceAuthenticationHint",
  ["Look straight into the camera"]
);
```

## showCloseButton

Show or hide the close/cancel button during onboarding flows. Accepts a string (`"true"` shows the button).

JavaScript

```javascript
cordova.exec(
  function () {},
  function (err) { console.log("Error:", err); },
  "Cplugin",
  "showCloseButton",
  ["true"]
);
```

## Asset Instructions

### Custom fonts on Android

1. Place your font files (`.ttf` / `.otf`) in `res/font/` of the Android app.
2. Reference them by their resource name in the V2 theme `typography.family` block (e.g. `"regular": "onboard_sdk_dm_sans_regular"`). The resource name must match the file name (without extension).

### Custom fonts on iOS

1. Add the font files to your iOS project (drag them in and ensure they are part of the app target's "Copy Bundle Resources").
2. Register them in `Info.plist` under the `UIAppFonts` (Fonts provided by application) array.
3. Reference them by their PostScript font name in the theme JSON (e.g. `"regular": "DMSans-Regular"`).
