Apariencia
Haz que el cotizador parezca construido por tu propio equipo de producto.
La API de Apariencia
Un solo objeto appearance controla el aspecto del cotizador embebido y de los componentes
nativos. Se compone de cinco piezas: theme, variables, rules, layout y fonts.
El mismo objeto, dos mecanismos. En el iframe (embed.js, <cord-quote>,
<CordCotizador>) el objeto viaja al servidor de Cord, que lo valida y genera el CSS dentro de su
propio origen: tu página nunca escribe estilos dentro del iframe. En los componentes nativos
(<CordBuilder> vía <CordProvider appearance={...}>) el SDK aplica las variables como CSS en
tu página. rules y layout solo aplican al iframe; elements y baseTheme, solo a lo nativo.
<script src="https://cordhq.app/embed.js" async></script>
<div
data-cord-token="a1b2c3d4e5f60718"
data-cord-appearance='{
"theme": "flat",
"variables": {
"colorPrimary": "#0f766e",
"colorText": "#0b1220",
"borderRadius": "10px",
"borderRadiusButton": "999px"
},
"rules": {
"Button": { "text-transform": "uppercase", "letter-spacing": "0.04em" },
"Total": { "font-weight": "700" }
},
"layout": { "compact": true, "hideChat": true },
"fonts": [{ "cssSrc": "https://fonts.googleapis.com/css2?family=Inter:wght@400;600&display=swap" }]
}'>
</div>
Con el Web Component, el mismo JSON va en el atributo appearance o en la propiedad
element.appearance; en React, en la prop appearance de <CordCotizador>.
Editor visual
Elige el tema, los colores, la forma y las reglas, y mira la tarjeta con el mismo CSS que Cord genera dentro del iframe. El objeto de abajo ya pasó por sanitizeAppearance, el validador del servidor: si escribes un valor que Cord descartaría, te dice cuál.
Vista previa
La tarjeta con el mismo CSS que Cord genera dentro del iframe. Las hojas de fonts solo se cargan en el iframe.
Tu appearance
const appearance = {};<cord-quote token="TU_TOKEN" appearance='{}'></cord-quote>Cord acepta todo el objeto.
Temas (theme)
| Tema | Qué hace |
|---|---|
light |
Por defecto. |
dark |
Paleta oscura completa: fondo, superficies, texto, bordes y campos. night es un alias. |
auto |
Sigue prefers-color-scheme del visitante. |
flat |
Sin sombra y con bordes visibles, para sitios que no usan elevación. |
El tema se aplica primero y tus variables siempre ganan sobre él.
Variables (variables)
Se escriben en camelCase. Cada una llega a una superficie real del cotizador; una variable
que no defines conserva el valor de Cord.
| Variable | Tipo | Dónde se ve |
|---|---|---|
colorPrimary |
color | Botón principal, acentos, burbujas propias del chat |
colorOnPrimary |
color | Texto sobre el color primario |
colorBackground |
color | Fondo de la tarjeta |
colorSurface |
color | Paneles internos: notas, total, chat, avisos |
colorText |
color | Texto principal e importes |
colorTextSecondary |
color | Etiquetas, RFC, notas |
colorTextPlaceholder |
color | Encabezados de tabla, ayudas, placeholders |
colorBorder |
color | Divisores y bordes |
colorDanger |
color | Rechazar y errores |
colorSuccess |
color | Confirmaciones |
colorInput |
color | Fondo de los campos |
colorInputText |
color | Texto de los campos |
colorInputBorder |
color | Borde de los campos |
colorFocus |
color | Borde del campo enfocado |
fontFamily |
familia | Toda la tarjeta |
fontSize |
longitud | Partidas |
fontWeightBold |
peso | Botones |
borderRadius |
longitud | Tarjeta |
borderRadiusButton |
longitud | Botones |
borderRadiusInput |
longitud | Campos |
spacingCard |
espaciado | Relleno de la tarjeta (2rem o 1.5rem 2rem) |
shadowCard |
none o default |
Sombra de la tarjeta |
Un color acepta hexadecimal, rgb(), hsl(), oklch(), oklab(), lab(), lch() o un
nombre. Una longitud acepta px, rem, em o %.
Reglas por componente (rules)
Para lo que las variables no alcanzan, rules aplica propiedades a componentes con nombre
público. No son selectores CSS: son nombres estables que Cord traduce a su markup, así que no se
rompen cuando el markup cambia.
"rules": {
"Button": { "text-transform": "uppercase" },
"Button:hover": { "opacity": "0.9" },
"Input:focus": { "border-color": "#0f766e" },
"Bubble--mine": { "background-color": "#0f766e" }
}
Componentes: Card, Header, Total, Table, Row, SummaryRow, Notes, Button,
Button:hover, ButtonSecondary, ButtonSecondary:hover, Input, Input:focus, Chat,
Bubble, Bubble--mine.
Propiedades: color, background-color, border-color, border-width, border-style,
border-radius, font-size, font-weight, letter-spacing, text-transform, padding,
box-shadow (none o default) y opacity.
Layout (layout)
| Opción | Efecto |
|---|---|
compact: true |
Menos aire en la tarjeta, para columnas angostas. |
hideChat: true |
Oculta la conversación y los comentarios por partida. |
hideNotes: true |
Oculta el bloque de notas de la cotización. |
Ocultar es solo presentación: la cotización y sus acciones siguen siendo las mismas en el link público.
Fuentes (fonts)
Hasta cuatro hojas de fonts.googleapis.com o fonts.bunny.net por https. Si no declaras
fontFamily, Cord usa la primera familia de la primera hoja.
Qué valida Cord y por qué
Todo valor que termina en CSS pasa por un validador con listas cerradas de claves, componentes y
propiedades, y una gramática por tipo de valor. Se descartan url(), expression(), @,
!important, ;, llaves y <, y el objeto completo se ignora si pesa más de 8 KB. Lo
descartado no rompe el resto: se ignora, el SDK lo avisa en la consola durante el desarrollo y
aparece en la barra de depuración con una llave
de prueba.
Esto cierra la puerta a usar la apariencia para ocultar botones, tapar el total o cargar recursos de terceros dentro del iframe: el diseño es tuyo, la integridad de la cotización es de Cord.
Componentes nativos
Modo headless (baseTheme: 'none')
Con <CordBuilder> o useQuoteBuilder y tu propia UI, appearance={{ baseTheme: 'none' }} en
<CordProvider> desactiva la hoja de estilos base. Las clases .cord-* siguen en el markup y el
aspecto queda en tus manos (Tailwind, CSS Modules o lo que uses).
Overrides por elemento (elements)
Cada nodo de <CordBuilder> lleva una clase estable .cord-<key> (builderRoot, formField,
itemRow, summaryRoot, submitButton…). appearance.elements le suma tu className y tu
style:
<CordProvider
publishableKey={pk}
appearance={{
variables: { colorPrimary: '#0f766e', borderRadiusInput: '6px' },
elements: {
submitButton: 'mi-boton',
itemRow: { style: { gap: '18px' } },
},
}}
>
<CordBuilder />
</CordProvider>
La clase base .cord-<key> nunca se reemplaza; la tuya se agrega encima.