Brand Concierge Style Guide (iOS)
This document provides a reference for styling properties supported by the AEPBrandConcierge framework. Themes are configured using JSON files that follow a web-compatible CSS variable format.
Overview
The theme configuration is loaded from a JSON file using ConciergeThemeLoader.load(from:in:). The framework supports CSS-like variable names (prefixed with --) that are mapped to native Swift properties.
Loading a Theme
// Load from app bundle
let theme = ConciergeThemeLoader.load(from: "theme-default", in: .main)
// Use default theme
let defaultTheme = ConciergeThemeLoader.default()
Applying a Theme
Apply the theme using the .conciergeTheme() view modifier on your wrapped content:
import SwiftUI
import AEPBrandConcierge
struct ContentView: View {
@State private var theme: ConciergeTheme = ConciergeThemeLoader.default()
var body: some View {
Concierge.wrap(
// Your app content here
Text("Hello, World!"),
surfaces: ["my-surface"]
)
.conciergeTheme(theme) // Apply theme to the wrapper
.onAppear {
// Load custom theme from JSON file
if let loadedTheme = ConciergeThemeLoader.load(from: "my-theme", in: .main) {
theme = loadedTheme
}
}
}
}
Important: The .conciergeTheme() modifier must be applied to the result of Concierge.wrap() so the theme is available to both the wrapper and the chat overlay.
JSON Structure
The theme JSON file contains these top-level keys:
metadatabehaviordisclaimertextarraysassetsthemeValue Formats
Understanding the value formats used throughout this document.
Colors
Colors are specified as hex strings:
"--color-primary": "#EB1000"
"--message-user-background": "#EBEEFF"
"--input-box-shadow": "0 2px 8px 0 #00000014"
Supported formats:
#RRGGBB- 6 digit hex#RRGGBBAA- 8 digit hex with alpha
Dimensions
Dimensions use CSS pixel units:
{
"--input-height-mobile": "52px",
"--input-border-radius-mobile": "12px",
"--message-max-width": "100%"
}
On iOS, prefer the *-mobile token names; --input-height and --input-border-radius without the suffix are not supported (see Unsupported CSS Variables).
Padding
Padding follows CSS shorthand syntax:
"--message-padding": "8px 16px"
Formats:
8px- All sides8px 16px- Vertical, horizontal8px 16px 4px- Top, horizontal, bottom8px 16px 4px 2px- Top, right, bottom, left
Shadows
Shadows use CSS box-shadow syntax:
"--input-box-shadow": "0 2px 8px 0 #00000014"
"--multimodal-card-box-shadow": "none"
Format: offsetX offsetY blurRadius spreadRadius color
Font Weights
Font weights use CSS numeric or named values:
100ultraLight200thin300light400 / normalregular500medium600semibold700 / boldbold800heavy900blackText Alignment
left.leadingcenter.centerright.trailingMetadata
Theme identification information.
metadata.brandName""metadata.version"0.0.0"metadata.language"en-US"metadata.namespace"brand-concierge"Example
{
"metadata": {
"brandName": "Concierge Demo",
"version": "1.0.0",
"language": "en-US",
"namespace": "brand-concierge"
}
}
Behavior
Feature toggles and interaction configuration.
Multimodal Carousel
behavior.multimodalCarousel.cardClickAction"openLink"behavior.multimodalCarousel.carouselStyle"paged""paged" snaps to one item at a time with prev/next buttons and page indicator dots. "scroll" provides continuous horizontal scrolling.Input
behavior.input.enableVoiceInputfalsebehavior.input.disableMultilinetruebehavior.input.showAiChatIconnullicon property (SVG string or URL).behavior.input.sendButtonStyle"default""default" shows a paper airplane icon. "arrow" shows a filled circle with an upward arrow.behavior.input.silenceThreshold0.02behavior.input.silenceDuration2Chat
behavior.chat.messageAlignment"left""left" / "leading" / "start", "center" / "justify", "right" / "trailing" / "end" (case-insensitive). Unknown values fall back to "left".behavior.chat.messageWidth"100%""100%", "768px")behavior.chat.userMessageBubbleStyle"default""balloon" for speech-bubble style (squared-off bottom-right corner); any other value uses fully rounded cornersProduct Card
behavior.productCard.cardStyle"actionButton""actionButton" shows an image, description text, and primary/secondary action buttons. "productDetail" shows an image, optional badge, title, subtitle, and price — the entire card is tappable.behavior.productCard.cardsAlignment"center""start", "center", "end".Welcome Card
behavior.welcomeCard.closeButtonAlignment"end""start" places it before the title, "end" places it after (trailing).behavior.welcomeCard.promptFullWidthtruetrue, prompt suggestions render as full-width cards with image thumbnails. When false, they render as compact chips.behavior.welcomeCard.promptMaxLines3behavior.welcomeCard.contentAlignment"top""center" centers content vertically, "top" aligns to top.Prompt Suggestions
behavior.promptSuggestions.itemMaxLines1behavior.promptSuggestions.showHeaderfalsetext["suggestions.header"].behavior.promptSuggestions.alignToMessagefalsefalse, uses the default chat padding offset.Feedback
behavior.feedback.displayMode"modal""modal" renders inline as a Modal overlay; "action" renders as an action sheet-style layout.behavior.feedback.thumbsPlacement"inline""inline" places them beside the sources accordion header. "below" places them below the header with a "Was this helpful?" label.behavior.feedback.showCloseButtonnullnull = shown for "action", hidden for "modal".behavior.feedback.showCancelButtonnullnull = shown for "modal", hidden for "action". Both set to false is honored — Submit and (in action mode) drag-down still dismiss.Note: The notes field is only available in
"modal"display mode, gated bycomponents.feedback.positiveNotesEnabled/negativeNotesEnabled.
Citations
behavior.citations.showLinkIconfalsetrue, shows an external link icon next to citation URLs in the sources list.Privacy Notice
behavior.privacyNotice.title"Privacy Notice"behavior.privacyNotice.text"Privacy notice text."Example
{
"behavior": {
"multimodalCarousel": {
"cardClickAction": "openLink",
"carouselStyle": "paged"
},
"input": {
"enableVoiceInput": true,
"disableMultiline": false,
"showAiChatIcon": null,
"sendButtonStyle": "default",
"silenceThreshold": 0.02,
"silenceDuration": 2
},
"chat": {
"messageAlignment": "left",
"messageWidth": "100%",
"userMessageBubbleStyle": "default"
},
"productCard": {
"cardStyle": "productDetail",
"cardsAlignment": "center"
},
"welcomeCard": {
"closeButtonAlignment": "end",
"promptFullWidth": true,
"promptMaxLines": 3,
"contentAlignment": "top"
},
"promptSuggestions": {
"itemMaxLines": 1,
"showHeader": false,
"alignToMessage": false
},
"feedback": {
"displayMode": "modal",
"thumbsPlacement": "inline",
"showCloseButton": null,
"showCancelButton": null
},
"citations": {
"showLinkIcon": false
},
"privacyNotice": {
"title": "Privacy Notice",
"text": "Privacy notice text."
}
}
}
Disclaimer
Legal disclaimer text with embedded links.
disclaimer.text"AI responses may be inaccurate..."{placeholders} for linksdisclaimer.links[]text and url.disclaimer.links[].text""disclaimer.links[].url""Example
{
"disclaimer": {
"text": "AI responses may be inaccurate. Check answers and sources. {Terms}",
"links": [
{
"text": "Terms",
"url": "https://www.adobe.com/legal/licenses-terms/adobe-gen-ai-user-guidelines.html"
}
]
}
}
Text (Copy)
Localized UI strings using dot-notation keys.
✅ Content Recommendations
While there are no strict requirements for character limits in many of these text fields, it is strongly recommended that the values be tested on target device(s) prior to deployment, ensuring the UI renders as desired.
Header
text["header.title"]""title parameter passed to ChatView.text["header.subtitle"]""subtitle parameter passed to ChatView.Tip: To hide the header subtitle, set
text["header.subtitle"]to"". The subtitle is automatically hidden when its text is blank.
Welcome Screen
text["welcome.heading"]"Explore what you can do with Adobe apps."text["welcome.subheading"]"Choose an option or tell us..."Input
text["input.placeholder"]"Tell us what you'd like to do or create"text["input.messageInput.aria"]"Message input"text["input.send.aria"]"Send message"text["input.aiChatIcon.tooltip"]"Ask AI"text["input.mic.aria"]"Voice input"Cards & Carousel
text["card.aria.select"]"Select example message"text["carousel.prev.aria"]"Previous cards"text["carousel.next.aria"]"Next cards"System Messages
text["scroll.bottom.aria"]"Scroll to bottom"text["error.network"]"I'm sorry, I'm having trouble..."text["loading.message"]"Generating response from our knowledge base"Feedback Dialog
text["feedback.dialog.title.positive"]"Your feedback is appreciated"text["feedback.dialog.title.negative"]"Your feedback is appreciated"text["feedback.dialog.question.positive"]"What went well? Select all that apply."text["feedback.dialog.question.negative"]"What went wrong? Select all that apply."text["feedback.dialog.notes"]"Notes"text["feedback.dialog.submit"]"Submit"text["feedback.dialog.cancel"]"Cancel"text["feedback.dialog.notes.placeholder"]"Additional notes (optional)"text["feedback.toast.success"]"Thank you for the feedback."text["feedback.thumbsUp.aria"]"Thumbs up"text["feedback.thumbsDown.aria"]"Thumbs down"Sources & Feedback
text["sourcesLabel"]"Sources"text["feedbackHelpfulLabel"]"Was this helpful?"behavior.feedback.thumbsPlacement is "below"Prompt Suggestions
text["suggestions.header"]"Suggestions"behavior.promptSuggestions.showHeader is true.Example
{
"text": {
"welcome.heading": "Welcome to Brand Concierge!",
"welcome.subheading": "I'm your personal guide to help you explore.",
"input.placeholder": "How can I help?",
"error.network": "I'm sorry, I'm having trouble connecting."
}
}
Arrays
List-based configuration for examples and feedback options.
Welcome Examples
You shouldn't have more than four items in your welcome examples.
Always test your values on device to ensure the UI looks as desired.
arrays["welcome.examples"]text, optional image, and optional backgroundColor (hex string).arrays["welcome.examples"][].textarrays["welcome.examples"][].imagenull or omitted).arrays["welcome.examples"][].backgroundColornull or omitted).Feedback Options
You shouldn't have more than five options available for feedback.
Always test your values on device to ensure the UI looks as desired.
arrays["feedback.positive.options"]arrays["feedback.negative.options"]Example
{
"arrays": {
"welcome.examples": [
{
"text": "I'd like to explore templates to see what I can create.",
"image": "https://example.com/template.png",
"backgroundColor": "#F5F5F5"
}
],
"feedback.positive.options": [
"Helpful and relevant recommendations",
"Clear and easy to understand",
"Other"
],
"feedback.negative.options": [
"Didn't understand my request",
"Unhelpful or irrelevant information",
"Other"
]
}
}
Assets
Icon and image asset configuration.
assets.icons.company""http:// or https://) or a local asset name from the app bundle (checked via UIImage(named:) and supported file extensions: .png, .jpg, .jpeg, .webp, .heic, .heif, .gif, .tiff, .tif, .bmp). Leave empty to display no icon.Bundling local icons
Asset catalog (recommended): Add the image to an .xcassets file in the host app and use the image set name as the value. This supports @1x/@2x/@3x scale variants and dark mode variants automatically.
Loose bundle file: Add the image file directly to the app target so it is copied to the bundle root, then use the filename without its extension as the value.
Remote URLs must resolve to a supported raster format (PNG, JPEG, WebP, HEIC/HEIF, GIF, TIFF, BMP). SVG is not supported for remote or local icons.
Example
{
"assets": {
"icons": {
"company": "company-logo"
}
}
}
Theme Tokens
Visual styling using CSS-like variable names. All properties in the theme object use the --property-name format.
Typography
--font-familytypography.fontFamilyString"" (system font)--line-height-bodytypography.lineHeightCGFloat1.0Colors - Primary
--color-primarycolors.primary.primaryColoraccentColor--color-textcolors.primary.textColorprimary--color-containercolors.primary.containerColor?nil (falls back to secondarySystemBackground)Colors - Surface
--main-container-backgroundcolors.surface.mainContainerBackgroundColorsystemBackground--main-container-bottom-backgroundcolors.surface.mainContainerBottomBackgroundColorsystemBackground--message-blocker-backgroundcolors.surface.messageBlockerBackgroundColorsystemBackgroundColors - Messages
--message-user-backgroundcolors.message.userBackgroundColorsecondarySystemBackground--message-user-textcolors.message.userTextColorprimary--message-concierge-backgroundcolors.message.conciergeBackgroundColorsystemBackground--message-concierge-textcolors.message.conciergeTextColorprimary--message-concierge-link-colorcolors.message.conciergeLinkColoraccentColorColors - Buttons
--button-primary-backgroundcolors.button.primaryBackgroundColoraccentColor--button-primary-textcolors.button.primaryTextColorwhite--button-secondary-bordercolors.button.secondaryBorderColorprimary--button-secondary-textcolors.button.secondaryTextColorprimary--submit-button-fill-colorcolors.button.submitFillColorclear--submit-button-fill-color-disabledcolors.button.submitFillDisabledColorclear--color-button-submitcolors.button.submitTextColoraccentColor--button-disabled-backgroundcolors.button.disabledBackgroundColorclearColors - Input
--input-backgroundcolors.input.backgroundColorwhite--input-text-colorcolors.input.textColorprimary--input-outline-colorcolors.input.outlineColor?nil--input-focus-outline-colorcolors.input.outlineFocusColoraccentColorColors - Input Icons
--input-send-icon-colorcolors.input.sendIconColorColor?nil--input-send-arrow-icon-colorcolors.input.sendArrowIconColorColor?nil--input-send-arrow-background-colorcolors.input.sendArrowBackgroundColorColor?nil--input-mic-icon-colorcolors.input.micIconColorColor?nil--color-primary.--input-mic-recording-icon-colorcolors.input.micRecordingIconColorColor?nilColors - Welcome Prompts
--welcome-prompt-background-colorcolors.welcomePrompt.backgroundColorColor?nilbackgroundColor from arrays["welcome.examples"].--welcome-prompt-text-colorcolors.welcomePrompt.textColorColor?nil--color-text.Colors - Prompt Suggestions
--suggestion-background-colorcolors.promptSuggestion.backgroundColorColor?nil (falls back to --color-container then secondarySystemBackground)--suggestion-text-colorcolors.promptSuggestion.textColorColor?nil (falls back to --message-concierge-text)Colors - Citations
--citations-background-colorcolors.citation.backgroundColorsystemGray3--citations-text-colorcolors.citation.textColorprimaryColors - Feedback
--feedback-icon-btn-backgroundcolors.feedback.iconButtonBackgroundColorclear--feedback-sheet-background-colorcolors.feedback.sheetBackgroundColor?nil (falls back to colors.surface.light)--feedback-title-text-colorcolors.feedback.titleTextColor?nil (falls back to system .primary)--feedback-sheet-background-color is pinned — system .primary tracks device interface style, not the themed fill.--feedback-question-text-colorcolors.feedback.questionTextColor?nil (falls back to system .secondary)--feedback-options-text-colorcolors.feedback.optionsTextColor?nil (falls back to system .primary)--feedback-title-text-color when --feedback-sheet-background-color is pinned.--feedback-checkbox-border-colorcolors.feedback.checkboxBorderColor?nil (#FFFFFF47 dark / #00000059 light)--feedback-sheet-background-color is pinned, as the adaptive fallback tracks device interface style.--feedback-drag-handle-colorcolors.feedback.dragHandleColor?nil (falls back to Color.secondary.opacity(0.4))action display mode. Set alongside --feedback-sheet-background-color when using a fixed fill.--feedback-submit-button-fill-colorcolors.feedback.submitButtonFillColor?nil (falls back to colors.button.primaryBackground)--feedback-submit-button-text-colorcolors.feedback.submitButtonTextColor?nil (falls back to colors.button.primaryText)--feedback-cancel-button-fill-colorcolors.feedback.cancelButtonFillColor?nil (transparent; outline style)nil = transparent (outline style); set to a color for a solid fill. Border is always applied — set feedbackCancelButtonBorderWidth to 0 to suppress it. Also tints the X close icon.--feedback-cancel-button-text-colorcolors.feedback.cancelButtonTextColor?nil (falls back to colors.button.secondaryText)--feedback-cancel-button-border-colorcolors.feedback.cancelButtonBorderColor?nil (falls back to colors.button.secondaryBorder)feedbackCancelButtonBorderWidth > 0, regardless of whether cancelButtonFill is set.Colors - Product Card
--product-card-background-colorcolors.productCard.backgroundColorColorwhite--product-card-title-colorcolors.productCard.titleColorColorprimary--product-card-subtitle-colorcolors.productCard.subtitleColorColorprimary--product-card-price-colorcolors.productCard.priceColorColorprimary--product-card-was-price-colorcolors.productCard.wasPriceColorColorsecondary--product-card-badge-text-colorcolors.productCard.badgeTextColorColorwhite--product-card-badge-background-colorcolors.productCard.badgeBackgroundColorColorprimary--product-card-outline-colorcolors.productCard.outlineColorColorclearColors - CTA Button
--cta-button-background-colorcolors.ctaButton.backgroundColor#EDEDED--cta-button-text-colorcolors.ctaButton.textColor#191F1C--cta-button-icon-colorcolors.ctaButton.iconColorColor#161313Colors - Disclaimer
--disclaimer-colorcolors.disclaimerColorsystemGrayColors - Thinking Animation
--thinking-dot-colorcolors.thinking.dotColorColor?nil (falls back to primaryDotColor from ConciergeResponsePlaceholderConfig)Layout - Input
--input-height-mobilelayout.inputHeightCGFloat52--input-border-radius-mobilelayout.inputBorderRadiusCGFloat12--input-outline-widthlayout.inputOutlineWidthCGFloat2--input-focus-outline-widthlayout.inputFocusOutlineWidthCGFloat2--input-font-sizelayout.inputFontSizeCGFloat16--input-button-heightlayout.inputButtonHeightCGFloat30--input-button-widthlayout.inputButtonWidthCGFloat30--input-button-border-radiuslayout.inputButtonBorderRadiusCGFloat8--input-box-shadowlayout.inputBoxShadowShadownoneLayout - Messages
--message-border-radiuslayout.messageBorderRadiusCGFloat10--message-paddinglayout.messagePaddingPadding8px 16px--message-max-widthlayout.messageMaxWidthCGFloat?nil--agent-icon-sizelayout.agentIconSizeCGFloat39--agent-icon-spacinglayout.agentIconSpacingCGFloat12Layout - Chat
--chat-interface-max-widthlayout.chatInterfaceMaxWidthCGFloat768--chat-history-paddinglayout.chatHistoryPaddingCGFloat16--product-card-carousel-horizontal-padding when that property is not set.--chat-history-padding-top-expandedlayout.chatHistoryPaddingTopExpandedCGFloat8--chat-history-bottom-paddinglayout.chatHistoryBottomPaddingCGFloat12--message-blocker-heightlayout.messageBlockerHeightCGFloat105Layout - Cards & Carousel
--border-radius-cardlayout.borderRadiusCardCGFloat16--multimodal-card-box-shadowlayout.multimodalCardBoxShadowShadow0 1px 3px 0 #00000033Layout - Buttons
--button-height-slayout.buttonHeightSmallCGFloat30Layout - Feedback
--feedback-container-gaplayout.feedbackContainerGapCGFloat4--feedback-icon-btn-size-desktoplayout.feedbackIconButtonSizeCGFloat44--feedback-submit-button-border-radiuslayout.feedbackSubmitButtonBorderRadiusCGFloat10--feedback-submit-button-font-weightlayout.feedbackSubmitButtonFontWeightFontWeightsemibold--feedback-cancel-button-border-radiuslayout.feedbackCancelButtonBorderRadiusCGFloat10--feedback-cancel-button-border-widthlayout.feedbackCancelButtonBorderWidthCGFloat1cancelButtonFill is set; set to 0 to suppress the stroke.--feedback-cancel-button-font-weightlayout.feedbackCancelButtonFontWeightFontWeightsemibold--feedback-checkbox-border-radiuslayout.feedbackCheckboxBorderRadiusCGFloat6--feedback-title-text-alignlayout.feedbackTitleTextAlignConciergeTextAlignment?nil (.leading)"left" / "leading" / "start", "center" / "justify", "right" / "trailing" / "end" (case-insensitive). Unknown values fall back to .leading.--feedback-title-font-sizelayout.feedbackTitleFontSizeCGFloat?nil (falls back to system .title2, ~22pt at default Dynamic Type)Layout - Citations
--citations-text-font-weightlayout.citationsTextFontWeightFontWeightbold--citations-desktop-button-font-sizelayout.citationsDesktopButtonFontSizeCGFloat14Layout - Disclaimer
--disclaimer-font-sizelayout.disclaimerFontSizeCGFloat12--disclaimer-font-weightlayout.disclaimerFontWeightFontWeightregularLayout - Product Card
--product-card-widthlayout.productCardWidthCGFloat250--product-card-heightlayout.productCardHeightCGFloat300--product-card-title-font-sizelayout.productCardTitleFontSizeCGFloat14--product-card-title-font-weightlayout.productCardTitleFontWeightFontWeightbold--product-card-subtitle-font-sizelayout.productCardSubtitleFontSizeCGFloat12--product-card-subtitle-font-weightlayout.productCardSubtitleFontWeightFontWeightregular--product-card-price-font-sizelayout.productCardPriceFontSizeCGFloat14--product-card-price-font-weightlayout.productCardPriceFontWeightFontWeightlight--product-card-badge-font-sizelayout.productCardBadgeFontSizeCGFloat12--product-card-badge-font-weightlayout.productCardBadgeFontWeightFontWeightsemibold--product-card-was-price-text-prefixlayout.productCardWasPriceTextPrefixString"was "--product-card-was-price-font-sizelayout.productCardWasPriceFontSizeCGFloat12--product-card-was-price-font-weightlayout.productCardWasPriceFontWeightFontWeightregular--product-card-text-spacinglayout.productCardTextSpacingCGFloat8--product-card-text-top-paddinglayout.productCardTextTopPaddingCGFloat20--product-card-text-bottom-paddinglayout.productCardTextBottomPaddingCGFloat12--product-card-text-horizontal-paddinglayout.productCardTextHorizontalPaddingCGFloat12--product-card-carousel-spacinglayout.productCardCarouselSpacingCGFloat12--product-card-carousel-horizontal-paddinglayout.productCardCarouselHorizontalPaddingCGFloat?nilnil, both fall back to chatHistoryPadding. Leading cannot go below the column-aligned base.Layout - CTA Button
--cta-button-border-radiuslayout.ctaButtonBorderRadiusCGFloat99--cta-button-horizontal-paddinglayout.ctaButtonHorizontalPaddingCGFloat16--cta-button-vertical-paddinglayout.ctaButtonVerticalPaddingCGFloat12--cta-button-font-sizelayout.ctaButtonFontSizeCGFloat14--cta-button-font-weightlayout.ctaButtonFontWeightFontWeightregular--cta-button-icon-sizelayout.ctaButtonIconSizeCGFloat16Layout - Welcome Screen Order
Layout - Header
--header-title-font-sizelayout.headerTitleFontSizeCGFloat?nilnil, uses the default system .title3 size.Layout - Welcome Screen
--welcome-input-orderlayout.welcomeInputOrderInt3--welcome-cards-orderlayout.welcomeCardsOrderInt2--welcome-title-font-sizelayout.welcomeTitleFontSizeCGFloat?nilnil, defaults to 22.--welcome-text-alignlayout.welcomeTextAlignString?nil"left", "center"). When nil, defaults to left.--welcome-content-paddinglayout.welcomeContentPaddingCGFloat?nil--welcome-prompt-image-sizelayout.welcomePromptImageSizeCGFloat?nil90.--welcome-prompt-spacinglayout.welcomePromptSpacingCGFloat?nil--welcome-title-bottom-spacinglayout.welcomeTitleBottomSpacingCGFloat?nil10.--welcome-prompts-top-spacinglayout.welcomePromptsTopSpacingCGFloat?nil--welcome-prompt-paddinglayout.welcomePromptPaddingCGFloat?nil--welcome-prompt-corner-radiuslayout.welcomePromptCornerRadiusCGFloat?nil--border-radius-card.--suggestion-item-border-radiuslayout.suggestionItemBorderRadiusCGFloat?nil (defaults to 10)Layout - Thinking Animation
--thinking-dot-sizelayout.thinkingDotSizeCGFloat?8--thinking-dot-spacinglayout.thinkingDotSpacingCGFloat?8--thinking-bubble-border-radiuslayout.thinkingBubbleBorderRadiusCGFloat?8--thinking-bubble-padding-horizontallayout.thinkingBubblePaddingHorizontalCGFloat?16--thinking-bubble-padding-verticallayout.thinkingBubblePaddingVerticalCGFloat?8--thinking-dot-vertical-alignmentlayout.thinkingDotVerticalAlignmentString?"center""top", "center", or "bottom"Complete Example
{
"metadata": {
"brandName": "Concierge Demo",
"version": "1.0.0",
"language": "en-US",
"namespace": "brand-concierge"
},
"behavior": {
"multimodalCarousel": {
"cardClickAction": "openLink",
"carouselStyle": "paged"
},
"input": {
"enableVoiceInput": true,
"disableMultiline": false,
"showAiChatIcon": null,
"sendButtonStyle": "default",
"silenceThreshold": 0.02,
"silenceDuration": 2
},
"chat": {
"messageAlignment": "left",
"messageWidth": "100%",
"userMessageBubbleStyle": "default"
},
"productCard": {
"cardStyle": "productDetail",
"cardsAlignment": "center"
},
"welcomeCard": {
"closeButtonAlignment": "end",
"promptFullWidth": true,
"promptMaxLines": 3,
"contentAlignment": "top"
},
"promptSuggestions": {
"itemMaxLines": 1,
"showHeader": false,
"alignToMessage": false
},
"feedback": {
"displayMode": "modal",
"thumbsPlacement": "inline",
"showCloseButton": null,
"showCancelButton": null
},
"citations": {
"showLinkIcon": false
},
"privacyNotice": {
"title": "Privacy Notice",
"text": "Privacy notice text."
}
},
"disclaimer": {
"text": "AI responses may be inaccurate. Check answers and sources. {Terms}",
"links": [
{
"text": "Terms",
"url": "https://www.adobe.com/legal/licenses-terms/adobe-gen-ai-user-guidelines.html"
}
]
},
"text": {
"welcome.heading": "Welcome to Brand Concierge!",
"welcome.subheading": "I'm your personal guide to help you explore.",
"input.placeholder": "How can I help?",
"input.messageInput.aria": "Message input",
"input.send.aria": "Send message",
"feedback.dialog.title.positive": "Your feedback is appreciated",
"feedback.dialog.submit": "Submit",
"feedback.dialog.cancel": "Cancel",
"header.title": "",
"header.subtitle": "",
"sourcesLabel": "Sources",
"feedbackHelpfulLabel": "Was this helpful?",
"suggestions.header": "Suggestions"
},
"arrays": {
"welcome.examples": [
{
"text": "I'd like to explore templates to see what I can create.",
"image": "https://example.com/template.png",
"backgroundColor": "#F5F5F5"
}
],
"feedback.positive.options": [
"Helpful and relevant recommendations",
"Clear and easy to understand",
"Other"
],
"feedback.negative.options": [
"Didn't understand my request",
"Unhelpful or irrelevant information",
"Other"
]
},
"assets": {
"icons": {
"company": ""
}
},
"theme": {
"--welcome-input-order": "3",
"--welcome-cards-order": "2",
"--font-family": "",
"--color-primary": "#EB1000",
"--color-text": "#131313",
"--line-height-body": "1.75",
"--main-container-background": "#FFFFFF",
"--main-container-bottom-background": "#FFFFFF",
"--message-blocker-background": "#FFFFFF",
"--input-height-mobile": "52px",
"--input-border-radius-mobile": "12px",
"--input-background": "#FFFFFF",
"--input-outline-color": null,
"--input-outline-width": "2px",
"--input-focus-outline-width": "2px",
"--input-focus-outline-color": "#4B75FF",
"--input-font-size": "16px",
"--input-text-color": "#292929",
"--input-button-height": "32px",
"--input-button-width": "32px",
"--input-button-border-radius": "8px",
"--input-box-shadow": "0 2px 8px 0 #00000014",
"--submit-button-fill-color": "#FFFFFF",
"--submit-button-fill-color-disabled": "#C6C6C6",
"--color-button-submit": "#292929",
"--button-disabled-background": "#FFFFFF",
"--button-primary-background": "#3B63FB",
"--button-primary-text": "#FFFFFF",
"--button-secondary-border": "#2C2C2C",
"--button-secondary-text": "#2C2C2C",
"--button-height-s": "30px",
"--disclaimer-color": "#4B4B4B",
"--disclaimer-font-size": "12px",
"--disclaimer-font-weight": "400",
"--message-user-background": "#EBEEFF",
"--message-user-text": "#292929",
"--message-concierge-background": "#F5F5F5",
"--message-concierge-text": "#292929",
"--message-concierge-link-color": "#274DEA",
"--message-border-radius": "10px",
"--message-padding": "8px 16px",
"--message-max-width": "100%",
"--chat-interface-max-width": "768px",
"--chat-history-padding": "16px",
"--chat-history-padding-top-expanded": "0",
"--chat-history-bottom-padding": "0",
"--message-blocker-height": "105px",
"--border-radius-card": "16px",
"--multimodal-card-box-shadow": "none",
"--feedback-container-gap": "4px",
"--feedback-icon-btn-background": "#FFFFFF",
"--feedback-icon-btn-size-desktop": "32px",
"--feedback-sheet-background-color": "#FFFFFF",
"--feedback-title-text-color": "#131313",
"--feedback-question-text-color": "#424242",
"--feedback-options-text-color": "#131313",
"--feedback-checkbox-border-color": "#131313",
"--feedback-drag-handle-color": "#CCCCCC",
"--feedback-submit-button-fill-color": "#006554",
"--feedback-submit-button-text-color": "#FFFFFF",
"--feedback-submit-button-border-radius": "10px",
"--feedback-submit-button-font-weight": "600",
"--feedback-cancel-button-fill-color": "#006554",
"--feedback-cancel-button-text-color": "#006554",
"--feedback-cancel-button-border-color": "#006554",
"--feedback-cancel-button-border-width": "1px",
"--feedback-cancel-button-border-radius": "10px",
"--feedback-cancel-button-font-weight": "600",
"--feedback-checkbox-border-radius": "6px",
"--feedback-title-font-size": "22px",
"--citations-text-font-weight": "700",
"--citations-desktop-button-font-size": "12px",
"--product-card-background-color": "#FFFFFF",
"--product-card-title-color": "#292929",
"--product-card-title-font-size": "14px",
"--product-card-title-font-weight": "700",
"--product-card-subtitle-color": "#292929",
"--product-card-subtitle-font-size": "12px",
"--product-card-subtitle-font-weight": "400",
"--product-card-price-color": "#292929",
"--product-card-price-font-size": "16px",
"--product-card-price-font-weight": "300",
"--product-card-was-price-color": "#6E6E6E",
"--product-card-was-price-text-prefix": "was ",
"--product-card-was-price-font-size": "12px",
"--product-card-was-price-font-weight": "400",
"--product-card-badge-text-color": "#FFFFFF",
"--product-card-badge-background-color": "#000000",
"--product-card-badge-font-size": "12px",
"--product-card-badge-font-weight": "600",
"--product-card-outline-color": "#00000000",
"--product-card-width": "200px",
"--product-card-height": "300px",
"--product-card-text-spacing": "8px",
"--product-card-text-top-padding": "20px",
"--product-card-text-bottom-padding": "12px",
"--product-card-text-horizontal-padding": "12px",
"--product-card-carousel-spacing": "12px",
"--product-card-carousel-horizontal-padding": "4px",
"--cta-button-background-color": "#EDEDED",
"--cta-button-text-color": "#191F1C",
"--cta-button-icon-color": "#161313",
"--cta-button-border-radius": "99px",
"--cta-button-horizontal-padding": "16px",
"--cta-button-vertical-padding": "12px",
"--cta-button-font-size": "14px",
"--cta-button-font-weight": "400",
"--cta-button-icon-size": "16px",
"--header-title-font-size": "18px",
"--input-send-icon-color": "",
"--input-send-arrow-icon-color": "",
"--input-send-arrow-background-color": "",
"--input-mic-icon-color": "",
"--input-mic-recording-icon-color": "",
"--color-container": "#F0F0F0",
"--suggestion-background-color": "#F0F0F0",
"--suggestion-text-color": "#131313",
"--suggestion-item-border-radius": "10px",
"--welcome-prompt-background-color": "",
"--welcome-prompt-text-color": "",
"--welcome-title-font-size": "22px",
"--welcome-text-align": "left",
"--welcome-content-padding": "0px",
"--welcome-prompt-image-size": "90px",
"--welcome-prompt-spacing": "8px",
"--welcome-title-bottom-spacing": "10px",
"--welcome-prompts-top-spacing": "8px",
"--welcome-prompt-padding": "0px",
"--welcome-prompt-corner-radius": "16px"
}
}
Implementation Status
This section documents which properties are fully implemented, partially implemented, or not yet implemented in the iOS framework.
Legend
Metadata
metadata.brandNamemetadata.versionmetadata.languagemetadata.namespaceBehavior
behavior.multimodalCarousel.cardClickActionbehavior.multimodalCarousel.carouselStylebehavior.productCard.cardStylebehavior.productCard.cardsAlignmentbehavior.input.enableVoiceInputbehavior.input.disableMultilinebehavior.input.showAiChatIconbehavior.input.sendButtonStylebehavior.input.silenceThresholdbehavior.input.silenceDurationbehavior.welcomeCard.closeButtonAlignmentbehavior.welcomeCard.promptFullWidthbehavior.welcomeCard.promptMaxLinesbehavior.welcomeCard.contentAlignmentbehavior.promptSuggestions.itemMaxLinesbehavior.promptSuggestions.showHeaderbehavior.promptSuggestions.alignToMessagebehavior.feedback.displayMode"modal" (centered) vs "action" (action sheet) in FeedbackOverlayViewbehavior.feedback.thumbsPlacementbehavior.feedback.showCloseButtondisplayMode when nullbehavior.feedback.showCancelButtondisplayMode when nullbehavior.citations.showLinkIconbehavior.chat.messageAlignmentbehavior.chat.messageWidthbehavior.chat.userMessageBubbleStyle"balloon" = speech bubble with squared-off bottom-right; default = fully rounded)behavior.privacyNotice.titlebehavior.privacyNotice.textDisclaimer
disclaimer.textdisclaimer.linksText (Copy)
text["welcome.heading"]text["welcome.subheading"]text["input.placeholder"]text["input.messageInput.aria"]text["input.send.aria"]text["input.aiChatIcon.tooltip"]text["input.mic.aria"]text["card.aria.select"]text["carousel.prev.aria"]text["carousel.next.aria"]text["scroll.bottom.aria"]text["error.network"]text["loading.message"]text["feedback.dialog.title.positive"]text["feedback.dialog.title.negative"]text["feedback.dialog.question.positive"]text["feedback.dialog.question.negative"]text["feedback.dialog.notes"]text["feedback.dialog.submit"]text["feedback.dialog.cancel"]text["feedback.dialog.notes.placeholder"]text["feedback.toast.success"]text["feedback.thumbsUp.aria"]text["feedback.thumbsDown.aria"]text["header.title"]text["header.subtitle"]text["sourcesLabel"]text["feedbackHelpfulLabel"]text["suggestions.header"]behavior.promptSuggestions.showHeader is trueArrays
arrays["welcome.examples"]arrays["feedback.positive.options"]arrays["feedback.negative.options"]Assets
assets.icons.companyTheme Tokens - Typography
--font-family--line-height-bodyTheme Tokens - Colors
--color-primary--color-text--color-container--suggestion-background-color--suggestion-text-color--main-container-background--main-container-bottom-background--message-blocker-background--message-user-background--message-user-text--message-concierge-background--message-concierge-text--message-concierge-link-color--button-primary-background--button-primary-text--button-secondary-border--button-secondary-text--submit-button-fill-color--submit-button-fill-color-disabled--color-button-submit--button-disabled-background--input-background--input-text-color--input-outline-color--input-focus-outline-color--citations-background-color--citations-text-color--feedback-icon-btn-background--feedback-sheet-background-color--feedback-title-text-color--feedback-question-text-color--feedback-options-text-color--feedback-checkbox-border-color--feedback-drag-handle-color--feedback-submit-button-fill-color--feedback-submit-button-text-color--feedback-cancel-button-fill-color--feedback-cancel-button-text-color--feedback-cancel-button-border-color--disclaimer-color--input-send-icon-color--input-send-arrow-icon-color--input-send-arrow-background-color--input-mic-icon-color--input-mic-recording-icon-color--welcome-prompt-background-color--welcome-prompt-text-colorTheme Tokens - Colors (CTA Button)
--cta-button-background-color--cta-button-text-color--cta-button-icon-colorTheme Tokens - Colors (Product Card)
--product-card-background-color--product-card-title-color--product-card-subtitle-color--product-card-price-color--product-card-was-price-color--product-card-badge-text-color--product-card-badge-background-color--product-card-outline-colorTheme Tokens - Layout
--input-height-mobile--input-border-radius-mobile--input-outline-width--input-focus-outline-width--input-font-size--input-button-height--input-button-width--input-button-border-radius--input-box-shadow--message-border-radius--message-padding--message-max-width--chat-interface-max-width--chat-history-padding--chat-history-padding-top-expanded--chat-history-bottom-padding--message-blocker-height--border-radius-card--multimodal-card-box-shadow--button-height-s--feedback-container-gap--feedback-icon-btn-size-desktop--feedback-submit-button-border-radius--feedback-submit-button-font-weight--feedback-cancel-button-border-radius--feedback-cancel-button-border-width--feedback-cancel-button-font-weight--feedback-checkbox-border-radius--feedback-title-text-align--feedback-title-font-size--citations-text-font-weight--citations-desktop-button-font-size--disclaimer-font-size--disclaimer-font-weight--welcome-input-order--welcome-cards-order--header-title-font-size--welcome-title-font-size--welcome-text-align--welcome-content-padding--welcome-prompt-image-size--welcome-prompt-spacing--welcome-title-bottom-spacing--welcome-prompts-top-spacing--welcome-prompt-padding--welcome-prompt-corner-radius--suggestion-item-border-radius--product-card-width--product-card-height--product-card-title-font-size--product-card-title-font-weight--product-card-subtitle-font-size--product-card-subtitle-font-weight--product-card-price-font-size--product-card-price-font-weight--product-card-badge-font-size--product-card-badge-font-weight--product-card-was-price-text-prefix--product-card-was-price-font-size--product-card-was-price-font-weight--product-card-text-spacing--product-card-text-top-padding--product-card-text-bottom-padding--product-card-text-horizontal-padding--product-card-carousel-spacing--product-card-carousel-horizontal-paddingchatHistoryPadding when not set--cta-button-border-radius--cta-button-horizontal-padding--cta-button-vertical-padding--cta-button-font-size--cta-button-font-weight--cta-button-icon-size--agent-icon-size--agent-icon-spacingUnsupported CSS Variables
The following CSS variables appear in web theme configurations but are not supported on iOS:
--input-height--input-height-mobile instead--input-border-radius--input-border-radius-mobile instead--color-button-submit-hover--button-primary-hover--button-secondary-hover--color-button-secondary-hover-text--feedback-icon-btn-hover-background--message-alignmentbehavior.chat.messageAlignment instead--message-widthbehavior.chat.messageWidth instead