Skip to content
Theming

Guides

Theming

Every colour, both fonts, the corner radius and the shadow are CSS variables. Point them at your design tokens and the call looks like it was built with the rest of your product.

Playground

Pick a preset or your own colours. The call below re-skins live, and the CSS underneath is ready to paste. Every other token is worked out from these four colours, much as you’d map your own palette.

Theme playgroundInteractive
Background
Tiles and panels
Text
Accent
Name tags
A small pill in the corner, as wide as the name
Control bar
A raised bar with a shadow, in the middle
Bar size
Buttons easy to hit on any screen
Buttons
--im-control-radius
Theme preview

4 people here · your colours

your-app.css
.inlinemeet-call.my-app-call {
  --im-canvas: #eef2f6;
  --im-bg: #f7f9fb;
  --im-surface: #ffffff;
  --im-raised: #f3f3f4;
  --im-hover: #e9eaec;
  --im-bar: rgba(238, 242, 246, 0.8);
  --im-controls-bg: rgba(255, 255, 255, 0.9);
  --im-float: rgba(255, 255, 255, 0.96);
  --im-stage-bg: #0f172a;
  --im-overlay: rgba(15, 23, 42, 0.62);
  --im-overlay-ink: #f8fafc;
  --im-border: rgba(15, 23, 42, 0.1);
  --im-border-strong: rgba(15, 23, 42, 0.18);
  --im-ink: #0f172a;
  --im-soft: #636875;
  --im-faint: #93979f;
  --im-accent: #0d9488;
  --im-accent-ink: #ffffff;
  --im-accent-text: #0c857a;
  --im-avatar-s: 55%;
  --im-avatar-l: 88%;
  --im-avatar-ink-s: 45%;
  --im-avatar-ink-l: 30%;
  --im-radius: 12px;
  --im-shadow: 0 10px 30px rgba(15, 23, 42, 0.12);
  --im-warn: #b45309;
  --im-danger: #dc2626;
}
your-call.tsx
<CallRoom
  backend={backend}
  title="Weekly sync"
  className="my-app-call"
/>
A template with these colours, for your recordings and streams
POST /v1/templates

{
  "name": "Our call colours",
  "kind": "meeting",
  "setup": {
    "look": {
      "theme": {
        "bg": "#f7f9fb",
        "surface": "#ffffff",
        "raised": "#f3f3f4",
        "hover": "#e9eaec",
        "bar": "rgba(238, 242, 246, 0.8)",
        "controls-bg": "rgba(255, 255, 255, 0.9)",
        "float": "rgba(255, 255, 255, 0.96)",
        "stage-bg": "#0f172a",
        "overlay": "rgba(15, 23, 42, 0.62)",
        "overlay-ink": "#f8fafc",
        "border": "rgba(15, 23, 42, 0.1)",
        "border-strong": "rgba(15, 23, 42, 0.18)",
        "ink": "#0f172a",
        "soft": "#636875",
        "faint": "#93979f",
        "accent": "#0d9488",
        "accent-ink": "#ffffff",
        "accent-text": "#0c857a",
        "danger": "#dc2626",
        "warn": "#b45309",
        "avatar-s": "55%",
        "avatar-l": "88%",
        "avatar-ink-s": "45%",
        "avatar-ink-l": "30%"
      }
    }
  }
}

How it works

The call’s root element is .inlinemeet-call, and its whole palette lives in custom properties on it. Give the component a class of your own, and override the properties under both classes in your stylesheet:

<CallRoom backend={backend} title="Weekly sync" className="my-app-call" />
app.css
.inlinemeet-call.my-app-call {
  --im-accent: #0d9488;
  --im-accent-text: #0f766e;
  --im-radius: 12px;
}

Two classes outrank the stylesheet the component ships with, so load order never matters. And because every rule the call ships is scoped under .inlinemeet-call, nothing leaks the other way into your pages.

Follow your own tokens

Better than copying colours: point the call at the variables your app already has. Then when your theme changes — light to dark, or mid-call — the call changes with it, with no JavaScript.

app.css — e.g. with shadcn/ui-style variables
.inlinemeet-call.my-app-call {
  --im-font: var(--font-sans);
  --im-canvas: var(--background);
  --im-bg: var(--muted);
  --im-surface: var(--card);
  --im-raised: var(--secondary);
  --im-ink: var(--foreground);
  --im-soft: var(--muted-foreground);
  --im-border: var(--border);
  --im-accent: var(--primary);
  --im-accent-ink: var(--primary-foreground);
  --im-radius: var(--radius);
}

/* Only what dark mode changes that the variables above don't already. */
.dark .inlinemeet-call.my-app-call {
  --im-accent-text: #a5b4fc;
}

The defaults are a dark call, the way most video tools do it — faces and shared screens read better against dark. A light call works just as well; try Daylight or Paper in the playground.

Accent vs accent text

Two tokens are easy to mix up. --im-accent is a fill — a control that’s on, a primary button, your own chat messages — with --im-accent-ink for anything on top of it. --im-accent-text is the accent drawn: text, icons and focus rings on a surface. A deep brand colour usually wants a lighter --im-accent-text in dark mode, so it stays readable. Tints — the recording pill, a raised hand — are mixed from these with color-mix(), so they follow on their own.

Name tags and the control bar

Two props on CallRoom set the call’s shapes. nameTags decides how each person’s name sits on their picture: pill (the default, a small pill in the corner as wide as the name), tab (flush in the bottom corner), shadow (white words, no box) or below (under the picture, covering nothing). controlBar decides how the bar sits: floating (the default), docked (a band across the bottom), bare (just the buttons) or overlay.

Two ways give the video more room. controlBarSize="compact" makes the buttons smaller and closer together. controlBar="overlay" lays the bar over the bottom of the video instead of giving it a row. With a mouse it hides three seconds after the mouse last moved and comes back when it moves. On a phone or tablet, where there is no pointer to move, a tap on the video shows it and another tap hides it, the way a phone’s video player does; it hides five seconds after the last touch, and a double-tap to pin someone leaves it alone. It stays while the mouse rests on it, keyboard focus is in it or a menu is open. While the whiteboard is open it keeps a row of its own, so it never covers the drawing. The buttons’ shape is a token.

<CallRoom backend={backend} title="Weekly sync" className="my-app-call" nameTags="below" controlBar="docked" />
app.css
.inlinemeet-call.my-app-call {
  --im-control-radius: 12px; /* rounded-square buttons */
}

The colours stay the tokens you already set: --im-overlay and --im-overlay-ink for a pill or tab, --im-surface and --im-ink for a name under the picture, and --im-controls-bg for a floating or docked bar. Your own CSS can follow the choice too: the call’s root carries it as data-name-tags and data-control-bar.

Recordings and streams

Your stylesheet themes the call inside your app. Recordings and live streams are drawn by InlineMeet’s recorder, which never loads your stylesheet, so by default they show InlineMeet’s colours. To match them to your call, put the same colours in a template and create your rooms from it. The chat, questions, polls, raised hands, speakers’ titles and scenes in those rooms’ recordings and streams then use your colours. The template carries the rest of your branding too: your logo, speakers’ names and titles, and what each scene says.

1. Make a template with your colours

On the dashboard, open Templates, then a template, and choose Your own colours under Recording colours. Pick them there, or paste the CSS your app already themes its call with. From your server, put the colours in the template’s setup.look.theme. The playground above writes this request for the colours you pick.

Once, from your server
curl -X POST https://api.inlinemeet.com/v1/templates \
  -H "Authorization: Bearer $INLINEMEET_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "name": "Our lessons",
    "kind": "meeting",
    "setup": {
      "look": {
        "logo": true,
        "titles": true,
        "theme": {
          "surface": "#ffffff",
          "ink": "#111827",
          "soft": "#6b7280",
          "border": "rgb(15 55 20 / 0.1)",
          "accent": "#1e5b22",
          "accent-ink": "#ffffff",
          "accent-text": "#1e5b22",
          "warn-fill": "#fcc223",
          "stage-bg": "#0c1f10"
        }
      }
    }
  }'

2. Create rooms from it

Name the template’s id as template when you create a room, or make it your workspace’s default template so every room that names none is set up from it.

POST /v1/rooms
{ "code": "algebra-101", "name": "Algebra 101", "template": "<the template's id>" }
  • Name each colour after its token, without the --im- prefix: --im-accent-text becomes accent-text.
  • Send the colours themselves (hex, rgb() or hsl()). InlineMeet can’t see your app’s CSS variables, so a value like var(--primary) is refused.
  • Only the colours carry over. The canvas, radius, shadow and fonts stay as they are in a recording. A colour you leave out keeps InlineMeet’s own, just as in the call.
  • A template has one set of colours. If your app has a light and a dark mode, use the one your recordings should wear. A light theme works well: white cards over the video, with stage-bg keeping the background behind the video dark.
  • Changing a template’s colours changes the rooms you create from it afterwards. To update a room that already exists, set the template on it again with PATCH /v1/rooms/:code, or send its look.theme directly. null takes a room’s own colours away.
  • If you serve many customers of your own, give each one its own templates with a scope. Their rooms then use their colours, not yours.

A recording uses each token in the same role it has in the call. Cards are surface with ink and soft text. A host’s messages are filled with accent. Tags, the speaker’s title, poll bars and “Answering now” use accent-text. Raised hands use the warn tokens, a quiz’s right answer uses success, and the background behind video and scenes is stage-bg. The accent also edges speakers’ titles, the call to action and the scenes.

For every room in your workspace, including those made without a template, you can also give your brand a theme with PUT /v1/brand. A template’s colours take its place in the rooms made from it.

Every token

TokenColours / sets
--im-canvasThe call’s own background. A colour or a gradient.
--im-surfaceTiles, the side panel, menus and dialogs.
--im-bgInputs, and the track behind the side panel’s tabs.
--im-raisedIdle buttons, and other people’s chat messages.
--im-hoverButtons under the pointer.
--im-barThe top bar (usually translucent).
--im-controls-bgThe control bar, floating or docked.
--im-floatNotices that float over the call.
--im-stage-bgBehind video and shared screens.
--im-overlay
--im-overlay-ink
Name labels laid over video, and their text (a pill or a corner tab).
--im-backdropBehind dialogs, like the recording player.
--im-border
--im-border-strong
Hairlines, and the ones that need to be seen.
--im-ink
--im-soft

--im-faint
Text: primary, secondary, and hints.
--im-accentA fill: controls that are on, primary buttons, your own messages.
--im-accent-inkText and icons on --im-accent.
--im-accent-textThe accent drawn as text, icons and focus rings on a surface.
--im-danger
--im-danger-ink
Muted microphones, leave, recording — and text on it.
--im-warn
--im-warn-fill

--im-warn-ink
Raised hands: as text, as a fill, and text on the fill.
--im-successA quiz’s right answer, and an answer sent.
--im-avatar-s
--im-avatar-l
Saturation and lightness of avatar circles. The hue comes from each name.
--im-avatar-ink-s
--im-avatar-ink-l
The same, for the initials on them.
--im-radiusCorner radius of tiles, panels and the call itself.
--im-control-radiusThe control bar’s buttons: 999px keeps them round, 12px makes rounded squares.
--im-shadowShadow under floating things: the control bar, menus.
--im-font
--im-font-display
Body and heading fonts. Default: the system UI font.

The InlineMeet badge

A small “powered by InlineMeet” mark sits beside the controls. On the Business and Enterprise plans you can remove it:

<CallRoom backend={backend} title="Weekly sync" branding={false} />

On Pro it stays, and stays out of the way — it takes your theme’s faint text colour. Compare plans.