Version 1.4 · September 2026

One visual language for every Bubblegum surface

The manager, the calendar drawer, the cross-agent library, Bubbles, the visitor cards, inbound and outbound, pending, the widget, the accounts portal — they grew one at a time and each brought a font, a blue and a corner radius of its own. This is the single set of decisions they all follow from here, with the tokens to import and the list of what each app has to change.

Principles

Five rules that settle most arguments before they start.

1
One accent, and it means "act".Bubblegum Violet is the only coloured thing on a quiet surface. It marks the primary action, the selected state, a link, and nothing decorative. If two things on screen are violet, one of them is wrong.
2
A header, then the sentence that says what it is.Every setting, shelf, option and card is a title with one line of plain description under it. A title alone is a label; a paragraph alone is a manual. Neither is ours.
3
Quiet surfaces, one line between.White panels on a near-white canvas, separated by 1px rules, not shadows. Depth is for things that float: menus, toasts, modals. Two panels side by side are a split screen with a line, never a modal over a modal.
4
Motion says where things went.A panel slides in from the edge it lives on and leaves the same way. Bubbles flies out before the library flies in. Nothing pops, nothing fades in place, and reduced-motion turns all of it off.
5
Nothing sleeps that could have said so.A Save button is disabled until something changed. A tooltip waits 300ms and then arrives at once. A hidden row leaves a note behind. An empty list explains what would fill it.

How to use this

Two files, one import, no raw hex.

Every product surface links tokens.css first and components.css second, then writes its own styles only in token names. A colour, radius or font that is not a token is not a Bubblegum colour, radius or font. When something is missing, add the token here and ship it everywhere, rather than inventing one locally.

<link rel="stylesheet" href="https://styleguide.bubblegum.ai/tokens.css"> <link rel="stylesheet" href="https://styleguide.bubblegum.ai/components.css">

Both files are versioned with the guide; a breaking change to a token name is a new major and a note in Files. Marketing (the landing site) shares the type scale and the neutrals and keeps its own hero palette, which is documented below and nowhere else.

Colour

Neutrals do the work; one accent acts; four statuses speak. Every value below is a token name in tokens.css.

Neutrals

Warm-grey ink on cool-white surfaces. There is one line colour and one muted text colour — the manager used to carry two families of grey (Google's #5f6368 and Tailwind's #6b7280) side by side; the survivor is the one below.

canvas#fbfbfc
panel#ffffff
soft#f6f7f9
soft-2#f1f2f6
line#e3e3e6
line-strong#c8c9cf
ink#1f2330
ink-muted#6b7280
ink-subtle#9aa0a6

Accent — Bubblegum Violet

The product's one colour. It was already the majority vote (94 uses in the manager, Bubbles, outbound, pending, chatthrough); Google blue #1a73e8 on .btn.primary is retired, and links go violet too.

accent#5b5bd6
accent-hover#4f4fc4
accent-weak#eeeefb
accent-line#dedef7
accent-ink#3f3fa8

Status

Each status is a trio: the strong colour for a dot or a border, a weak fill for the box, and an ink for text on that fill. Never the strong colour as text on white.

success#1f9d57
success-weak#eafbf0
warning#b45309
warning-weak#fff8e8
danger#d93025
danger-weak#fce8e6
side-mine#0f766e
side-theirs#be185d

Sides of a conversation. Outbound and transcripts colour the two parties — ours teal, theirs pink — and only there. Inbound's own pink accent #e0447e folds into side-theirs.

Dark surface

The visitor-facing business card is dark, and the same token names carry it: [data-theme="dark"] swaps the values, nothing else changes.

Business card
goo

Books coffee chats and study-abroad consultations.

Live

Marketing palette (landing only)

The landing site keeps its navy CTA #113a7c, the mint hero gradient, and Lato — it is a brochure, not the product. It adopts the type scale, the neutrals and the radius scale from here; nothing from its palette crosses into an app.

Do
  • Violet for the one primary action on a panel, selected chips, links, the eyebrow of the section you are in.
  • Status fills with their own ink colour.
  • Rules and borders in line; hover borders in line-strong.
Don't
  • Blue buttons. Blue was Google; it is gone.
  • Two greys for muted text on one screen.
  • Strong status colour as body text on white.
  • Tints for decoration — a tinted box means "this is different", so it must be.

Typography

Inter for the interface, JetBrains Mono for anything a machine reads back. Nothing else.

The manager's body says "Google Sans", which users do not have, so it silently renders in whatever the system falls back to — while Inter is loaded and used in eleven places. Bubbles says Google Sans too; cards, inbound, outbound, pending and chatthrough use a system stack; booking uses Lato. From here every product surface is Inter at 13px, weights 400/500/600/700, and the mono face is JetBrains Mono for ids, keys, URLs and code.

3xl · 26 / 700Booking prerequisite formsshelf and screen titles
2xl · 20 / 700Calendar bookingpage titles
xl · 16 / 600Cross-agent librarypanel and modal heads
lg · 14 / 600intake formcard and row names
md · 13 / 400All the event types that can be booked in this specific calendar.body — the default
sm · 12.5 / 400Shared privately with the agentdescriptions, notes
xs · 12 / 600Test with agentmini buttons, chips
2xs · 11 / 700Event typeseyebrows, uppercase, .07em
mono · 12pk_2ampdq · https://maps.google.com/?cid=…ids, links, keys
Do
  • Sentence case everywhere, including buttons and titles.
  • Eyebrows in uppercase with tracking — and only eyebrows.
  • Line height 1.45 for body, 1.62 in chat bubbles, 1.25 for titles.
Don't
  • Title Case, ALL CAPS body text, or bold for emphasis mid-sentence.
  • Weights 450 and 650 — they round to 500 and 600.
  • Sizes off the scale (13.5, 12.8). Pick the neighbour.

Space & layout

A 4px grid, a 20px gutter inside panels, 24px at the page edge.

4
8
12
16
20
24
32
ConstantValueWhere
--bg-bar-h57pxEvery top bar — app head, drawer head, Bubbles head — so the seams meet across a split screen.
--bg-dock-w344pxBubbles, docked left. The library opens in exactly this slot.
--bg-drawer-w540pxA side drawer. The calendar drawer is the wide one at 900px.
--bg-modal-w460pxA centred modal.
--bg-page-w1080pxContent column on a page.
--bg-floor-w1204pxBelow this the app asks for a wider window, drawers included.

Between cards in a drawer: a clear band of white above the next header (24px bottom padding). Inside a card: 12px between a label and its control, 8px between siblings, 16px around a card's content.

Radius

Five stops and a pill. The manager was using eleven different values; these are the ones that stay.

xs · 6
sm · 8
md · 10
lg · 12
xl · 16
pill
StopUsed for
xs · 6Checkboxes, tiny tags, the corner of a "me" chat bubble that points at the sender.
sm · 8Icon buttons, segmented tabs, tiles.
md · 10Inputs, dropdown menus, menu rows, tooltips.
lg · 12Cards, option cards, notes, toasts, dropdown buttons.
xl · 16Modals, the chat input, hero tiles.
pillEverything you press: every button at both sizes, chips, tabs, switches, tags. The pill is the shape of an action; the rectangle is the shape of content.
Do
  • Press = pill. Type or read = rectangle. That is the whole rule.
  • The outer radius is one stop larger than what it contains (a 12 card holds 10 inputs).
Don't
  • 7, 9, 11, 14, 15 — they are gone.
  • A pill button at full width. Pills are inline.

Elevation

Surfaces rest; only floating things cast a shadow.

rest — cards
lift — hover
float — menus
modal

A side drawer has no shadow: it is a column of the page with a 1px seam. Two drawers side by side (the library beside the calendar drawer) are a split screen — a line between, no tint on either. The scrim (--bg-scrim) appears only behind a modal, and behind a drawer only where clicking it closes that drawer.

Motion

Short, directional, and off for anyone who asked.

TokenValueRule
--bg-dur-hover150msBackground, border and colour changes on hover. Never transform on hover except a 1px lift on a linked card.
--bg-dur-enter200ms, ease-outA panel arrives with a 24px slide from the edge it lives on, and a fade from 0.6.
--bg-dur-exit180ms, ease-inIt leaves the way it came. When one panel replaces another in the same slot, the first leaves fully before the second arrives.
--bg-tip-delay300msTooltips wait, then appear at once; they leave instantly. A click on the thing quiets its tip until the pointer leaves.
reduced motion0msprefers-reduced-motion zeroes every duration and animation. Nothing depends on an animation finishing.

Scroll containers set overscroll-behavior: none; anything that must stay put while content scrolls lives outside the scroller (a pinned card head is moved out of the body, not made sticky).

Icons & imagery

Line icons on a 24 grid; one pixel-art character; brand marks as they are.

ThingRule
Glyphs24×24 viewBox, 2.2 stroke, round caps and joins, currentColor. Drawn at 15–18px inside buttons. Never a font glyph (‹ ›) where an SVG is meant — fonts put them wherever they like.
Icon buttonsA 32px circle. The close ✕ in every head, the send in every chat, the chevrons and arrows — one shape, like every other button.
The eyeThe closed-eye mark on a config card means "skip this in the guided chat". Hidden since 21 September 2026 (Joe: back later if needed) — the wiring stays, so every new card still registers its key; see marks.
Avatars40px circle. A file or place gets a tinted circle (accent-weak) holding a 20px glyph; a person gets their photo or an initial.
Tiles32px, radius sm, tinted. Used in dropdown options and settings index rows so a thing keeps the same face everywhere.
BubblesThe pixel sprite (helper-sprite.svg) at 26px, image-rendering: pixelated, always. It is the only illustration in the product.
Brand marksGoogle, Zoom, Telegram, Discord, OpenAI, Cloudflare and model logos are used as supplied, 16px, on a tile. Never recoloured.

Buttons

One shape. Every button is a pill — regular or small — in one of four colours. A panel has one primary.

The rule that settles itAnything you press is a pill: buttons, chips, tabs, toggles. Anything you type in or read is a rounded rectangle: inputs, cards, menus, notes. The same function never has two shapes, and only the primary carries a shadow. If two buttons on one screen differ in anything but colour and size, one of them is wrong.
Open in new tab
KindLooksWhen
PrimaryViolet fill, white text, the accent shadow — the only button with a shadow.The one action a panel exists for: Save changes, Create form, Send to config chat, Create agent. One per panel or modal foot.
SecondaryWhite, 1px line, ink text. No shadow.Cancel, Back, Manage, FAQ, the alternative next to a primary.
DangerDanger-weak fill, danger ink. Never a red fill with white text.Remove, delete, trash — always behind a typed confirmation.
TextViolet text, no box.A link that acts in place: Show me where, Start here, Show cross-agent library.
Regular · 36px13px/600, 16px side padding.Panel and modal foots, page headers, the create section of a shelf, the config card's Send.
Small · 30px12px/600, 12px side padding. Same colours, same pill.Inside a row, under a field, in a toolbar: Test with agent, Save changes per question, Open in new tab, Open / Exit form settings, Activate, Manage, the fold bar.
Icon32px circle, no border, hover soft-2; with a line border when it stands alone (prev/next).Close ✕, chevrons, overflow ⋯, arrows, send.
Do
  • Verb labels: "Save changes", "Create form", "Remove and trash the Google file".
  • Disabled at 45% until there is something to do.
  • "Saving…" in the button while it saves; the label comes back after.
Don't
  • Two primaries on one surface, or a primary in a card head.
  • A rounded-rectangle button anywhere — a pill Create form beside a rectangular Save changes is the thing this guide exists to stop.
  • A shadow on anything but the primary.
  • A pill at full width: a full-width pressable thing is a menu row, and rows are rectangles.

Chips & tags

A chip is something you press — so it is the small button's exact pill. A tag is something you read.

Google form Library Live Reworded Closed

Settled pills

What a setting is right now — the row under "What's configured now". One size for every one of them: 30px, 12px/600, the pill. Colour is the only thing that varies, and it says the category: saved kinds are green, defaults and derived values grey, a proposal not yet saved is dashed violet, an exception amber, places pink, leads blue. A pill's own controls (≡ menu, × remove) are 22px circles inside it and never change its height. Two linked values are joined by a short rule in the first pill's colour.

Coffee chats Online consultations Pizza party
All event types30 minutes Public holidays off Downtown office Lead: 2 days
Do
  • Same height and type as every small pill on the screen.
  • Colour by category, and only the categories above.
Don't
  • A pill that grows because it holds buttons (this is the one that shipped).
  • Two pill sizes in one row, or a 16px radius pretending to be a pill.

A dashed chip is a value that has not been saved yet (a pill the config chat proposed). A selected chip takes the accent border and weak fill. Tags are 11px uppercase and never carry a click; if you want to click it, it is a chip. The quick-paste rows ("Event types quick paste", "Location labels quick paste") use a small lowercase label, not an eyebrow, so they do not compete with the section heads.

Inputs & choices

On a white panel: a soft fill at rest, white with a violet ring on focus. On a tinted surface: white with a line. Labelled, with an example in the placeholder.

Shared privately with the agent
Enable booking

On a tinted surface

A soft-filled field is only a field when it sits on white. Inside a quiet card, a note, or anything else painted soft, it inverts: white with a line border, the same ring on focus. Never a grey field on a grey block.

1. What do you want to work as?short_text
Don't
  • A soft field on a soft card — it disappears (this is the one that shipped).
  • A darker grey to "fix" it. Invert to white instead.

Option cards

A few choices that each need a sentence. The heading format again: a word, then what it feels like.

Segmented tabs and dropdowns

Tabs are pills on a pill track; a stacked list of views is the same pill with the selected one in the accent tint. A dropdown that navigates carries the tile each destination wears elsewhere, never a native <select> — those render in the platform font.

Do
  • Label above, hint below the label, example in the placeholder.
  • Switch for a state that takes effect now; radio or checkbox for a choice that waits for Save.
  • Native checkbox and radio with accent-color — no custom drawings.
Don't
  • 1px hard-bordered white inputs (the 2012 look). Soft fill at rest.
  • Placeholders as labels.
  • A dashed circle with a plus as an upload target — use the tinted circle with a silhouette and a badge.

Cards, rows and bars

The units a screen is made of.

List row

intake form
Open in new tab
S
Sally Ng Teammate
sally@breadslice.com

Avatar, name, one line under it, actions as mini pills. A row that opens something says so in words on a button ("Open form settings" / "Exit form settings"), not with a chevron, and the words carry the state. A kind tag is dropped when the buttons already say what the thing is.

Card and quiet card

Reward payoutsWhat a visitor earns for booking, and when it is paid.
1. What do you want to work as?short_text

A card rests on shadow-rest and lifts on hover only if the whole card is the link. A quiet card (soft fill, no border) groups one item's controls inside a pane — a question and its guidance.

Top bar

Cross-agent library

57px, including its rule. The title is 16/600. The close is an icon button at the far right, on the same row.

Config card head

Event types
Instructions

All the event types that can be booked in this specific calendar. Type them in naturally and then send to the config chat to smooth them out.

The rule under the head stays when the card is expanded; the rule at the bottom of an expanded card is an extra one. The eyebrow of the section you are in is violet; the three sub-heads (Instructions, Natural-text entry, What's configured now) are muted.

Drawers, panels and modals

Three containers, and the rules for stacking them.

ContainerShapeRules
Side drawerRight edge, 540px (900 for the calendar drawer), full height, 1px seam, no shadow. Slides in 24px from the right.Head 57px with the title and ✕. Body scrolls; a sticky toolbar (collapse bar) may sit at its top. A foot holds the one primary (Save changes) when the drawer edits something.
Split panelLeft edge, in Bubbles' slot, capped at the drawer's left column, 1px seam.Both sides stay live — no tint on either. Clicking the gap closes both: the drawer first, with its unsaved-changes question, then the library, each leaving the way it came. The library's ✕ closes it alone. Bubbles leaves before the library arrives, and returns after it leaves.
ModalCentred, 460px, radius xl, modal shadow, scrim behind.One question, one primary in the foot. A modal over a modal dismisses only itself. Never for settings — those are drawers.
BubblesDocked left, 344px, always present above the floor width.Has no close of its own. When summoned over the split panel it sits on top at a higher layer, with an ✕ at the far right of its head that shows only in that state; a tap on the panel behind it sends it away and leaves the panel standing.
Pinned headA bar between a panel's head and its body.When a list item opens its full settings, its head (avatar, name, the two buttons) is moved out of the scrolling body into this bar, and the shelf's own title, blurb and create section hide. It cannot travel because it is not in anything that scrolls.

Split view inside a panel

A test of one thing happens inside the panel that owns it, not in a new window and not in Bubbles' column, which may be mid-conversation: a fixed top half (the thing under test, still editable) and a chat below. The bar reads Back to the list · Question n of m · ‹ ›. When the test ends, the chat half turns accent-weak with a verdict and one button (Test again).

Notes, tooltips and toasts

Three ways to say something small.

Chat history and streamingWhere transcripts go, and whether visitors see replies as they are written.
This question was reworded in GoogleThe expectations written for the old wording were cleared, so the agent is treating it as a question with no guidance. It used to read "Where will you go on vacation?".
This form is not accepting responsesGoogle has it closed, so a visitor cannot submit it and the agent will say so.
Med. i← hover: the tooltip arrives after 300ms, above, spanning its row
SavedCouldn't save that
ThingRule
NoteA tinted box with a bold first line and a sentence. Neutral for guidance, accent for the Ask Bubbles row, warn for something that changed while you were away, danger for something broken. A note is dismissed by fixing the thing, not by an ✕.
TooltipOur own (data-tip), never title — the browser's waits a second. Above the element, spanning the row it sits in so it can never overhang the panel. 300ms in, instant out, quiet after a click until the pointer leaves. Not shown in compact views where the words are already understood.
ToastTop right, dark, one line, radius lg, the toast shadow. Says what happened ("Saved", "Questions synced"), never what to do next. Errors are the same shape in dark red.

Chat

One transcript style for Bubbles, the config chat, tests and the visitor widget.

What would you like to work as?

Just wanna have fun

Ha, wouldn't we all — but I need an actual occupation, such as a teacher, electrician, or nurse. What's yours?

Nurse

The other side's words are bare text at 1.62 line height. Ours sit in an accent-weak pill, indented 28px, with a 4px corner pointing at us. The input is a pill-cornered textarea that grows to a few lines; Enter sends, Shift+Enter is a newline; the send button is a violet circle that greys until there is something to send. A system note in the transcript ("The agent accepted the answer") is a bare line in muted ink. Markdown headings are never rendered inside a bubble.

Pattern: the config card

The calendar drawer's unit, top to bottom.

  1. Head — tile, violet eyebrow (the setting's name), the fold chevron and the closed-eye mark at the right; a rule under it that stays when open.
  2. Instructions (foldable sub-head) — the one-paragraph description, then Examples as a bulleted list of quiet cards, then the Ask Bubbles row.
  3. Graphical entry (sub-head, only on a card that has one — the weekly and day-by-day availability grids: the type pills, Clear all, and the week) under the same dotted rule.
  4. Natural-text entry (sub-head) — the textarea ("Enter here then sent to the config agent for a quick review"), quick-paste chips under it with small lowercase labels, and the Send to config chat primary.
  5. What's configured now (sub-head) — the settled pills, green when saved, dashed when proposed, each with a menu and an ✕.
  6. 24px of white before the next card's head.

The drawer's sticky toolbar holds two small pills — Collapse all · Expand all — and every card's Instructions line carries its own Collapse all · Expand all as muted text buttons at the right, with "Prefer to just chat through all of it? Start here" on a non-sticky line above it. The config chat's head reads "Config chat for ‹box›" with its ✕ on the same row, and Next / Prev rows under its input navigate between boxes without opening a conversation.

Pattern: a library shelf

Every cross-agent shelf is the same page.

  1. Panel head "Cross-agent library" with ✕; under it the Showing dropdown of shelves, each with its tile.
  2. Shelf title (26/700) and its one-paragraph lede; then the Ask Bubbles about this library feature row.
  3. Create — a titled section with the primary (Create form / Create doc + Create sheet), framed by a rule above and below.
  4. In the library — list rows. A form row shows two mini pills (Open in new tab · Open form settings); a doc or sheet shows its link and a chevron.
  5. Open settings take the panel: the row's head moves into the pinned bar, the title, lede, ask row and Create hide, and the layout is one column. Forms show two tabs — Agent guidance (Proactiveness option cards; "Specific expectations for short-answer and paragraph questions" with Sync now under its sentence; a quiet card per question with expectations, effort pills, Save changes + Test with agent) and Other settings (Name, Sharing, Danger zone).

Pattern: saving, danger and marks

RuleHow
Save only when changedEvery Save button starts disabled and wakes on a real difference from what is stored; reverting puts it back to sleep. A single-choice control (a switch, an option card) saves on the click and toasts "Saved".
Per-thing savesA list of editable things (questions) saves per item, with the button beside that item; there is no "save all" at the bottom.
Danger zoneLast in its dropdown, under its own head. The name of the thing, typed exactly, unlocks the buttons. Two ways out where both exist ("Remove and trash the Google file" / "Remove, keep the file in Drive"). The wording says what is lost and what stays.
The closed-eye markEvery config card carries it (hidden for now, wiring intact). It needs the key in OD_FOLD_KEYS (app.js) and the worker's SETTLED_KEYS, or it will not stick. This is the thing that is always forgotten.
Both sides liveA write in the library echoes into the drawer at once (the caches it reads take the returned list; the parts that draw it repaint). Nothing waits for a panel to close.
Fresh before useA mirror of something in Google (a form's questions) is reconciled against the live read at the moment it is used, with a note on anything that moved.

Example layouts

The patterns above, drawn. Each is built from the components on this page and nothing else, so it is also a test of whether the components are enough.

A config card, in full

The calendar drawer's unit. Head with the eyebrow and the eye; three sub-heads — Instructions (with its fold and its own Collapse all · Expand all), Natural-text entry, What's configured now — the second and third each under a dotted rule. Under Instructions: the description, the Examples list, the Ask Bubbles row. Under Natural-text entry: the textarea, quick-paste chips, the card's one primary. 24px of white before the next head.

Durations
InstructionsCollapse all · Expand all

How long each event type can run for.

Examples
  • A fixed durationCoffee chats are 30 minutes
  • Entirely up to the visitorFor coffee chats let the visitor decide how long.
  • A minimum, maximum or bothCoffee chats can be from 30 minutes to 1 hour.Coffee chats must be no longer than 1 hour.
Natural-text entry
Event types quick paste

What's configured now
All event types30 minutesCoffee chatsVisitor decides

The calendar drawer

900px, right edge, two columns: the config cards on the left under a sticky toolbar, the calendar's switches and Google links on the right. The one primary lives in the foot. Shown here at reduced scale.

goocal2

AI assisted configuration
For visitors booking eventsVisitors booking your time with the agent
Event types
Durations
Online locations
Enable bookingIf both booking and schedule checking are off the agent ignores this calendar.
Open in Google

A library shelf, and the same shelf with a file open

Left: the shelf as you arrive — panel head, the Showing dropdown, title and lede, the ask row, Create, the list. Right: a file's settings open — its head pinned in a bar of its own, everything above the list hidden, the tabs, and the guidance.

Cross-agent library

Showing

Booking prerequisite forms

A Google Form a visitor must submit before an event type can be booked.

Create

In the library
intake form
Open in new tab

Cross-agent library

intake form
Open in new tab
Proactiveness
Specific expectations for short-answer and paragraph questions
1. What do you want to work as?short_text

A test, as a split view

Inside the panel that owns it: the bar (Back to the list · Question n of m · ‹ ›), the question under test with its guidance still editable and a Save at the end of the effort row, and the chat below. When the agent accepts, the chat half turns accent-weak with the verdict and Test again.

Question 1 of 3
What do you want to work as?short_text

What would you like to work as?

Just wanna have fun

Ha, wouldn't we all — but I need an actual occupation, such as a teacher, electrician, or nurse. What's yours?

Voice & copy

Written for an owner who is not technical and is reading one line at a time.

Do
  • Sentence case: "Send to config chat", "Booking prerequisite forms".
  • Say who it is for and what it does in one sentence: "Determines the guests (from the hosting side) that are added to the Google Calendar invite for the event."
  • Name the real thing: Google Form, Google Calendar, the config chat, Bubbles.
  • Buttons are verbs; toggles are states; tags are nouns.
  • Errors say what happened and what still works: "Synced — but Google has this form closed to responses."
  • "Made once here, usable by every agent." for anything in the library.
Don't
  • Title Case Headings, exclamation marks, "Oops".
  • "Pre-requisite", "Sync Now", "Config Agent" — one spelling, one case, everywhere.
  • Explain the mechanism when the outcome is enough.
  • Describe a thing twice on one screen (the shelf lede already said what Create makes).
  • Say "successfully". "Saved." is the whole sentence.
Canonical names
Cross-agent library · Calendar booking · Standalone-form filling · Chat history and streaming · Reward payouts · Prerequisite Google Form · Host-side calendar invitees · Pre-event homework · Event-details docs and sheets · Booking prerequisite forms · Config chat · Bubbles · Send to config chat · Collapse all / Expand all · Collapse instructions / Expand instructions · Open form settings / Exit form settings · Test with agent · Save changes · Sync now · Share and send email / Share but don't email · Low / Med. / High · High / Medium / Functional

Compliance, app by app

What each surface does today against this guide, and what has to change. Import the two files first; then work the list.

Manager frontend/public/agents
  • Done (v1.1): a normalisation layer at the end of styles.css gives every pressable class the one pill, two heights and the one shadow rule, over the top of the 160 local radius overrides that had accumulated. The next pass deletes those overrides rather than out-ranking them.
  • Body font is "Google Sans" (unavailable) → --bg-font-ui (Inter). Drop the 11 local Inter declarations; they become the default.
  • .btn radius 7 → md; .btn.primary blue → violet; #settings .btn.primary override and .set-hd-btn collapse into .bg-btn--primary.
  • Two grey families → --bg-ink-muted. Three token vocabularies (--al-*, --d2-*, bare) → the --bg-* names, aliased during migration.
  • Modal radius 15 → xl; drawer shadows off; toast already right.
  • Eleven radii → six. Sweep with the table above.
Calendar drawer & config cards agents/app.js · index.html
  • Already the source of most patterns here. Make every card's head, sub-heads, examples, ask row and quick-paste labels use the component classes rather than per-card CSS.
  • "Fixed online locations" form → the labelled-field style the location and invitee forms have.
  • Homework shelf's internal copy still says "Pre-meeting homework"; the dropdown says "Pre-event homework". One name.
Cross-agent library agents/app.js · settingsLibraryDocsHTML
  • Compliant in shape (this guide was written from it). Replace .od-mini, .ld-*, .lp-* with .bg-btn--sm, .bg-option, .bg-tabs, .bg-note, .bg-tip.
Bubbles apps/helper.js
  • Font "Google Sans" → Inter. Its CSS is inlined in JS; it should import tokens.css and read the names, keeping only the dock mechanics local.
  • Bubble radii, the me-pill fill, the head height and the send circle already match; the error red #b3261e--bg-danger-ink.
Visitor cards frontend/public/cards
  • Dark surface. Its private palette (--bg #0a0f1e, --accent #6366f1) becomes the [data-theme="dark"] values here; the indigo shifts to the dark-mode violet.
  • System font stack → Inter; mono → JetBrains Mono.
Inbound frontend/public/inbound
  • Pink accent #e0447e is a conversation-side colour, not a brand accent → --bg-side-theirs for the visitor, violet for actions. The blue → gone.
  • System font → Inter. Google grey → ink-muted.
Outbound & Pending frontend/public/outbound · pending
  • Closest to compliant: violet accent, teal/pink sides, proper status trios. Rename their local tokens to --bg-* and switch the font.
Chatthrough chatthrough/public
  • Violet already; ink #1f2330 is this guide's ink. Font and radius sweep only.
Widget openchatwidget.css
  • Runs on host pages, so it keeps its --ocw-* namespace, but the defaults behind those variables become these tokens (font, radii, accent, bubble style).
Accounts & Admin portals accounts/pages.mjs · admin
  • Server-rendered HTML with inline styles: link the two files from the guide origin and remove the local button, input and card rules. Admin's Inter stack is already right.
Booking booking/public
  • Visitor-facing pages in Lato → Inter (it is product, not brochure). Navy CTA → violet.
Landing landing/app
  • Keeps Lato and its navy/mint palette. Adopts the neutrals, the radius scale, sentence case and the canonical names above wherever it shows the product.
Docs docs (VitePress)
  • Theme colour → violet; font → Inter; screenshots retaken after the sweep.

Files

FileWhat
tokens.cssEvery value in this guide as a CSS custom property, with the dark set and reduced-motion. Import first.
components.cssThe reference implementation of every component on this page, written only in token names. Import second.
Example layoutsThe config card, the calendar drawer, a library shelf open and closed, and the test split view — each drawn from the components alone.
bubblegum/styleguide/The source of this site, deployed by deploy.sh to Cloudflare Pages at styleguide.bubblegum.ai. Change the guide and the files together; they ship as one.

Version 1.4 · 21 September 2026 — example layouts, drawn from the components. 1.3 — settled pills standardised. 1.2 — inputs invert on tinted surfaces. 1.1 — one shape for everything you press. 1 — first edition.