Graine AI

Your design

Choose how the agent looks in the dashboard — the SDK draws it on your website and in every app, typeface included, with nothing in your code.

The brand decides how the agent looks, once, in the dashboard. Every surface draws that design: the website widget, and the React Native, Android, iOS and Flutter SDKs. That covers the launcher, the voice bar, the caption, the chat window and every component the agent shows. The app passes nothing about how the agent looks. There is no colour to set in code and no font to bundle, so a redesign reaches every phone the next time your app starts, with no app release.

In one line: pick a design under Agent → Embed & Widgets → Appearance and save. Websites change on their next page load, and apps on React Native 0.38.0 or Android, iOS and Flutter 0.3.0 the next time they start — within about 30 seconds of saving. Every design and knob is on The Garage.

Choosing a design

Appearance opens on the Garage: design philosophies you flip through like cars in a showroom, with the website and in-app previews redrawing as you go. Each design has a light and a dark version, and every text colour is checked for legibility.

Graine Classic · Signature · Chat Neutral · Material You · iOS Native · Minimal Mono · Fluent · Enterprise Grid · Fintech Clear · Liquid Glass · Soft & Playful · Desktop Buddy · Swiss Grid · Precision · Japandi Calm · Neo-Brutalist · Editorial · Black & Gold · Retro Terminal · Warm & Earthy · Bauhaus · Gamified · High Contrast

Each one comes from a real design tradition: the International Typographic Style for Swiss Grid, the Bauhaus primaries, Linear's dense dark interface for Precision, wabi-sabi and calm technology for Japandi Calm, Duolingo's chunky play for Gamified, and the navy-and-teal restraint of payment products for Fintech Clear, and Graine's own look — quiet greys, an indigo voice, the grain of the G mark — for Signature.

Then tune it — Paint, Body, Typeface, Rims, Lights and Interior: the accent, roundness, the launcher's shape and glyph, the fonts, motion and glass, the chat's bubbles and frame. Every knob and its values are on The Garage.

Save, and the design is live. The phone preview is drawn from the same tokens the SDKs draw, element by element, so what the brand approves there is what customers see.

Upload it under Setup → Logo and pick it as the launcher glyph under Rims. Wherever it stands in for the glyph — the launcher, the voice bar's avatar, the chat header — it is drawn whole: fitted into the largest square the shape holds, proportions kept, never cropped. A wide wordmark shows end to end; a square logo keeps its corners.

It sits on one of two backgrounds, shown side by side under the upload so you can see both:

BackgroundFor
Brand colourA white or light logo made for a coloured background
WhiteAnything else — a coloured or dark logo, or an image with its own background. A logo drawn in your brand colour would vanish on a button of the same colour

The dashboard reads the logo when you upload it and picks one for you; change it any time. Empty transparent space around the logo is trimmed on upload, so it fills its button instead of floating small in the middle.

What the SDK draws

SurfaceDrawn from the design
LauncherThe accent, the launcher shape, the glyph or logo, the shadow or hard offset
Voice barThe surface, outline, corners and shadow. Then the accent avatar, and the name and status in the design's typeface, with a meter that moves at the design's pace. Then the microphone and the hang-up
CaptionThe line being said, on the design's card
Chat windowThe page, a header with the heading in the heading font, bubbles in the chosen style, and the composer — and the window size, title, avatar, header, background, starters, placeholder and timestamps from the Garage's Chat window tab
Call screenThe ring and the call, from the Garage's Call screen tab: background, avatar, controls, captions, timer, end button, ringtone and the words for each state. A locked iPhone shows the system's call screen — The Garage → Every state of a call
ComponentsCards, lists and choices in the design's corners, type and depth — a component's own look still wins where you set one
LoaderYour choice in Appearance → Loading, while connecting, reconnecting, thinking and while a component loads

Typefaces

The system font, or one of 24 families — eleven with Devanagari:

Inter · Roboto · Geist · IBM Plex Sans · IBM Plex Sans Devanagari · DM Sans · Noto Sans · Noto Sans Devanagari · Noto Sans Tamil · Mukta · Hind · Anek Devanagari · Poppins · Baloo 2 · Nunito · Atkinson Hyperlegible Next · Source Serif 4 · Newsreader · Fraunces · Playfair Display · Tiro Devanagari Hindi · Noto Serif Devanagari · Martel · JetBrains Mono

The SDK loads the typeface itself. It fetches only the faces the design draws with: the body font at its regular and strong weights, and the heading font at its title weight. They come from Graine, never a third party, and are kept on the device so each is fetched once. Until a face arrives, and if it never does, the SDK draws the system font. A missing font never costs a call.

A family your app already ships wins over the download: name it in fonts on the React Native provider, or in GraineConfig.fonts natively.

What your app does

React Native — mount the SDK's bar, and hand the provider the two platform abilities it cannot import itself: registering a font, and drawing a vector.

import * as Font from "expo-font";
import Svg, { Path } from "react-native-svg";
 
<GraineProvider client={client} autoConnect={false} loadFont={Font.loadAsync} svg={{ Svg, Path }}>
  <GraineVoiceLauncher webView={WebView} active={open} autoStart>
    {(api) => (open ? <GraineVoiceBar api={api} onClose={() => setOpen(false)} /> : null)}
  </GraineVoiceLauncher>
</GraineProvider>

For a launcher of your own placement, GraineLauncherButton draws the design's launcher and calls onPress. See React Native.

Android, iOS, Flutter — nothing beyond the bar you already mount (GraineAgentBarView, GraineAgentBar). From 0.3.0 it is drawn in the design, and the SDK downloads and registers the typeface natively — no module to add, nothing to hand over. Pass onClose if your app shows the bar on demand.

Light, dark and motion

Auto follows each customer's device, and switches the moment they do. Light or dark pins it for everyone. Motion runs at the design's pace: the meter, the caption and chat arriving, the launcher appearing. It stops entirely when the design says none, or when the customer's phone asks for reduced motion.

Drawing your own UI

You rarely need to, and replacing the SDK's bar means the design chosen in the dashboard stops reaching that part of your app. For anything you draw beside the agent, the design is available as tokens: useGraineTheme() in React Native, and the resolved tokens on GraineInApp natively. They cover colours, type, corners, spacing, shadows and motion for the device's light or dark.

When the phone does not match

SymptomCheck
The website changed, the app did notThe app draws its own bar instead of the SDK's — mount GraineVoiceBar (React Native) or the SDK's bar (native) — or the SDK is older than 0.38.0 / 0.3.0
The app changed later than the websiteThe SDK reads the design once each time the app starts. Quit the app fully and open it again — coming back from the background is not a new start
The typeface did not changeReact Native without loadFont; a family the app named in fonts wins; the phone was offline the first time — it draws the system font and tries again next session
Icons are plain glyphsReact Native without svg
No switch to the chat in a native appThe Android, iOS and Flutter SDKs carry the call, not the text chat. In Flutter, hand the bar your chat (chat:) and it offers the switch

On this page