Saltar al contenido

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.

Tema
Colores
Forma y texto
Reglas y layout

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.