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

# Theming

> Match the Insito modal to your brand with one of four presets or any subset of design tokens.

The SDK ships four themes out of the box — `light`, `dark`, `minimal`,
`rounded` — and a deep token system so you can override anything down to the
corner radius of a button.

<Note>
  You can also style surveys without touching code using the
  [Brand Kit](/dashboard/brand-kit) in the dashboard. The SDK applies the
  Brand Kit on top of the base preset, then applies any `init()` overrides on
  top of that — so **code always wins over the dashboard**:

  `base preset` → `Brand Kit (dashboard)` → `init() overrides`
</Note>

<Note>
  Theming controls colours, type, and shape. To change the modal's **text**
  (buttons, placeholders, NPS anchors, progress counter), see
  [Labels](/sdk/flutter/labels).
</Note>

## Pick a preset

```dart theme={null}
await MicroSurvey.init(
  const InsitoConfig(
    apiKey: 'proj_xxx',
    themePreset: ThemePreset.rounded,
  ),
);
```

| `ThemePreset`     | When to use                                                                                             |
| ----------------- | ------------------------------------------------------------------------------------------------------- |
| `light` (default) | Clean white surfaces, blue primary. Works against most app palettes.                                    |
| `dark`            | Dark surfaces, off-white text. Pair with your app's dark mode.                                          |
| `minimal`         | Hairline borders, sharp corners, neutral primary, no "Powered by" footer. Great for content-first apps. |
| `rounded`         | Large radii, violet primary, friendly feel. Consumer / lifestyle apps.                                  |

## Override tokens

Pass `themeOverrides` to deep-merge on top of a preset. Only the tokens you set
are changed; everything else inherits the preset.

```dart theme={null}
await MicroSurvey.init(
  const InsitoConfig(
    apiKey: 'proj_xxx',
    themePreset: ThemePreset.light,
    themeOverrides: InsitoThemeOverrides(
      colors: InsitoColorsOverride(
        primary: Color(0xFFFF6B35),
        primaryText: Color(0xFFFFFFFF),
      ),
      typography: InsitoTypographyOverride(fontFamily: 'Inter'),
      radii: InsitoRadiiOverride(md: 12, pill: 999),
    ),
  ),
);
```

## Full token map

Each override object mirrors a resolved token group; every field is optional
(`null` = inherit).

```dart theme={null}
class InsitoTheme {
  final InsitoColors colors;
  final InsitoTypography typography;
  final InsitoSpacing spacing;
  final InsitoRadii radii;
  final InsitoComponents components;
}

class InsitoColors {
  final Color background;    // Modal canvas
  final Color surface;       // Card / button surfaces
  final Color overlay;       // Backdrop behind the modal (incl. alpha)
  final Color text;
  final Color textMuted;
  final Color border;
  final Color primary;       // "Next" / "Submit" buttons, accents
  final Color primaryText;   // Text on top of primary
  final Color npsDetractor;  // 0–6 bucket colour
  final Color npsPassive;    // 7–8 bucket colour
  final Color npsPromoter;   // 9–10 bucket colour
}

class InsitoTypography {
  final String? fontFamily;         // System default if unset (see note below)
  final double questionSize;        // Question text
  final double bodySize;            // Body / option text
  final double labelSize;           // Helper text
  final FontWeight fontWeightRegular;
  final FontWeight fontWeightBold;
}

class InsitoSpacing { final double xs, sm, md, lg, xl; }
class InsitoRadii   { final double sm, md, lg, pill; }

class InsitoComponents {
  final bool showPoweredBy;             // "Powered by Insito" badge at bottom
  final double modalMaxHeightFraction;  // 0..1, default 0.85
}
```

## Custom fonts

<Warning>
  `typography.fontFamily` (set in code or via the dashboard Brand Kit) only
  applies if the font is **declared in your app's `pubspec.yaml`** (or loaded
  with a package like `google_fonts`). The SDK does not bundle or load fonts.
  If the named family isn't registered, Flutter falls back to the platform
  default.
</Warning>

```yaml pubspec.yaml theme={null}
flutter:
  fonts:
    - family: Inter
      fonts:
        - asset: assets/fonts/Inter-Regular.ttf
        - asset: assets/fonts/Inter-SemiBold.ttf
          weight: 600
```

```dart theme={null}
themeOverrides: InsitoThemeOverrides(
  typography: InsitoTypographyOverride(fontFamily: 'Inter'),
),
```

## Dark mode & auto appearance

The dashboard [Brand Kit](/dashboard/brand-kit) has an **Appearance** setting —
`light`, `dark`, or `auto` — delivered to the SDK as `brandConfig.themeMode`.
No code is required: the SDK resolves the right scheme per survey.

* **`auto`** follows the device appearance. `InsitoProvider` observes
  `didChangePlatformBrightness`, so if the user flips system dark mode **while a
  survey is open**, the modal re-themes live without closing.
* **`dark`** forces the SDK `dark` preset as the base; **`light`** keeps your
  configured `init()` preset.
* The Brand Kit ships **two colour palettes** (light and dark). The matching one
  is mapped on top of the resolved base preset; any dark colour left unset in the
  dashboard inherits the built-in `dark` preset token.

Precedence is unchanged — `init()` overrides still win over the Brand Kit:

`resolved scheme preset` → `Brand Kit palette` → `init() overrides`

## Follow your app's theme

When your app manages light/dark itself (a theme controller, a user preference)
rather than only the OS toggle, `auto`'s device detection can disagree with what
the user sees. Pass your app's current appearance to `InsitoProvider.appearance`
and `themeMode: "auto"` surveys follow it instead of the device.

```dart theme={null}
InsitoProvider(
  appearance: isDark ? InsitoAppearance.dark : InsitoAppearance.light,
  child: MaterialApp(/* ... */),
);
```

| `InsitoAppearance` | Behaviour                                                 |
| ------------------ | --------------------------------------------------------- |
| `system` (default) | Follow the device via platform brightness, updating live. |
| `light` / `dark`   | Force that scheme — use it to mirror your in-app theme.   |

Updating the prop re-themes an open survey live, and switching back to `system`
resumes device following.

## Previewing a theme

Use the standalone `resolveTheme` helper (or the raw `themePresets` map) to build
a fully-populated `InsitoTheme` outside the SDK — handy for widgetbook/preview
scenarios:

```dart theme={null}
import 'package:insito_flutter/insito_flutter.dart';

final preview = resolveTheme(
  ThemePreset.rounded,
  const InsitoThemeOverrides(
    colors: InsitoColorsOverride(primary: Color(0xFFFF6B35)),
  ),
);
print(preview.colors.primary); // Color(0xFFFF6B35)
```

## Branding rules

* `components.showPoweredBy` toggles the "Powered by Insito" badge. A per-survey
  `showBranding` value from the server (when present) wins; otherwise the theme
  token applies (the `minimal` preset defaults it to `false`). Plan-based
  branding enforcement happens server-side / in the dashboard.
* Keep colours WCAG AA-compliant — primary on background should hit 3:1 contrast
  minimum for usability. The default presets already pass.
* `modalMaxHeightFraction` defaults to `0.85`; keep it within a sensible
  `0.5`–`0.95` range (the value is applied as-is, not clamped by the SDK).
